幻觉不是模型笨,是上下文过期
过去半年,我把 Claude Code 接进公司 monorepo,最高频的翻车场景不是代码语法,而是「 confidently 调用了一条半年前就被废弃的 API」。根因很简单:模型训练数据截止 2024,而第三方 SDK 每周都在变。当智能体只凭记忆写代码,幻觉是概率问题;当现场文档与训练分布错位,幻觉必然发生。
Nia(trynia.ai,YC S25)把这个问题拆成两层:
- 让智能体「先查后写」,把生成动作变成检索 - 生成两段式;
- 用增量索引保证检索结果与源头版本差在分钟级。
下文给出我落地两周后的参数表与踩坑记录,供想给自己代码 Agent 加「可检索上下文层」的工程师直接抄作业。
架构速览:多路召回 + 增量刷新
Nia 的核心是「索引即服务」。你只需在 MCP 客户端里把 mcp_server_nia 加进去,它就会在后台做四件事:
- 监听来源:Git 仓库、Doc 站点、SDK 页面、PDF 手册;
- 多路索引:
- 语义索引(embedding)—— 回答「如何在 React 19 里用 use ()」;
- 符号索引 —— 回答「函数 foo 在哪被调用」;
- 引用图 —— 回答「改动 foo 会影响哪些文件」;
- BM25 + 正则兜底 —— 回答「grep 式 exact match」。
- 增量刷新:文件级 diff 检测,平均 3~5 min 同步到可查询状态;
- 会话复用:同一 Nia 实例可被多个 Agent 共享,Cursor、Claude Code、浏览器插件同时连进来,session ID 互通,避免重复建索。
落地参数清单
| 参数 | 推荐值 | 说明 |
|---|---|---|
| chunk_size | 600 token | 代码块过大容易截断函数签名,过小会丢失跨行语义 |
| refresh_interval | 15 min | 平衡实时性与 GitHub API 配额;金融场景可降到 5 min |
| top_k | 8 | 召回条数,超过 12 条后模型上下文窗口收益递减 |
| max_age | 7 day | 7 天内未再被引用的 chunk 自动淘汰,减少噪声 |
| session_ttl | 6 h | 开发跨日场景可留到 24 h,防止半夜索引清空 |
| embedding_model | text-embedding-3-small | 维度 1536,在速度与精度间折中 |
| symbol_graph_depth | 2 | 跳两层调用链,足以覆盖 90% 重构影响面分析 |
接入流程(10 分钟版)
- 安装
pipx install nia-mcp
nia login # 生成 API Key
- 在 Cursor
settings.json追加
"mcpServers": {
"nia": {
"command": "nia-mcp",
"env": { "NIA_API_KEY": "nk-xxx" }
}
}
- 索引外部依赖
# 把 Next.js 官方文档+源码一次性拉进来
nia source add --name nextjs-doc --type url https://nextjs.org/docs
nia source add --name nextjs-repo --type github vercel/next.js
nia index --wait
- 验证召回 在 Cursor 里直接问:
@nia在 app router 里怎么读取 cookie?
返回结果会给出「文件路径 + 行号 + 三行上下文」,而非大段复制粘贴,减少 token 占用。
效果:幻觉率降 42%,重复调用降 58%
我用内部 8 万行 TypeScript 项目跑两周对比:
- 对照组:原生 Claude Code,幻觉报错 26 次 / 100 任务;
- 实验组:同模型 + Nia,幻觉报错 15 次 / 100 任务,降幅 42 %;
- 重复文件扫描次数从 312 降到 131,节省 58 % 的 GitHub API 调用。
注意,当本地分支改动超过 30 文件 / 1000 行时,索引与现场差异拉大,幻觉率会回弹到 22 次。此时需在 PR 前手动 nia index --preview,让 Agent 同时看到「索引版」与「本地版」,再决定用哪一份。
局限与对冲
- 私有化定价按「索引行数」计费,大型 monorepo 易踩预算;可只把
src/和packages/core纳管,其余用.niaignore剔除。 - 对「尚未合并的接口变更」无能为力 —— 源头还没更新,索引当然查不到;解决方法是把 feature 分支临时加进 source,合并后再移除。
- Cursor 官方 @Docs 已支持外部站点抓取,Nia 必须证明「多路召回 + 增量刷新」比单路爬虫更准;目前看符号索引与引用图是差异点,但 Cursor 追赶快,需持续调优。
下一步:把上下文层做成 GitOps
我正准备把 nia-source.yaml 放进仓库 .github/ 目录,任何变更都走 PR;合并后 GitHub Action 自动 nia index --preview --comment,把「即将更新的外部上下文 diff」回写到 PR 页面,让 Code Review 时一眼看出「Agent 将看到什么」。
当上下文像代码一样被版本化、被 Code Review,幻觉就不再是黑盒概率,而是可审计的供应链问题。
参考资料
[1] Nia 主创 Arlan 在 HN 的架构自述:https://news.ycombinator.com/item?id=46194828
[2] Nia 内部幻觉率 benchmark:https://www.nozomio.com/blog/nia-oracle-benchmark