背景
作品集网站是对外展示的第一入口,日常观察下来,访客(不少是招聘方)想确认的问题其实都很具体,比如"有没有 Web 开发经验""做没做过 Agent"。但传统作品集只能被动展示,访客得自己翻遍项目去找答案。
问题
把所有信息摊开让访客自己找,效率不高,访客也未必知道该去哪个项目里找。直接接一个通用的 AI 聊天又会有另一个问题:模型容易凭印象编造经历、编造链接。对一个用来证明自己经验的网站来说,这种编造是不能接受的。
方案
我决定在网站里做一个了解我背景的站内 Agent,让它通过工具调用去查真实的项目、标签、联系方式,而不是靠模型自己的记忆回答。
架构
和客服助手 Agent类似,这里的业务也不复杂,我选了单层 Agent(AI SDK 的 ToolLoopAgent),把工具调用循环上限设为 8 步,避免模型陷入重复调用、浪费 Token。
工具设计
针对访客可能问的问题类型,设计了以下几个工具:
- getContentDetail:按 slug 拉取某个项目案例的完整正文,用于回答具体案例的细节追问。
- searchProjectsByTag:按 role / platform / method / projectType 精确过滤项目,专门用来回答"有没有 XX 经验"这类问题,比模型直接猜测更可靠。
- searchContent:标题、正文加权评分的关键词检索,兜底标签覆盖不到的开放式问题,比如某个爱好或某次获奖。
- getContactInfo:获取真实联系方式,避免模型编链接。
防止编造
系统提示词里做了几条硬约束:回答必须基于背景信息或工具返回结果,不能编造项目、经历或链接;不确定就要明确说不知道;提到具体项目必须原样使用列表或工具结果里给出的 url,不允许自己拼路径。
内容与 Prompt 同源
Prompt 里注入的项目列表、标签、工作经历,和 /llms.txt 输出给外部 AI 爬虫的内容,用的是同一个聚合函数。不管访客是在网站里直接对话,还是通过 ChatGPT、Perplexity 这类外部 AI 搜索引擎间接了解到我,看到的信息都是同一份数据源,不会因为改了项目内容却忘了同步 Prompt 而产生偏差。
GEO:面向 AI 搜索引擎的优化
除了站内 Agent,每个项目也额外输出了 llms.txt 摘要和纯 Markdown 版页面,方便外部大模型抓取引用,用的是和 CometAPI 项目里同一套 GEO 思路,只是这次用在自己的网站上。
并行预测追问
主回复走流式输出,同时用 generateObject 配合 Zod Schema 并行生成 2 个访客可能追问的问题。这个请求只带访客刚发的问题,不等主回复生成完就发出去,让建议 chip 能和回复的渲染节奏对齐,减少等待感。
限流与容错
接口按 IP 限流,60 秒内最多 10 次;上游模型报错时只返回兜底文案,不把原始 error 透出给客户端;模型 Provider 通过环境变量配置接入,换 Provider 不需要改调用方代码。
这部分从 Agent 和工具的搭建,到后续 UI 打磨(抽屉交互、工具调用可视化、消息复制/重新生成),都是在 Claude Code 里持续对话完成的。
效果
功能已上线,访客现在可以直接在网站打开对话,用自然语言确认我的经历和技能匹配度。