← 返回博客
David8 分钟阅读

Claude 项目知识库撞上上下文限制:会发生什么、怎么办

把文档全塞进 Claude 或 ChatGPT 的项目知识库,迟早撞上上下文限制:先回答变差,后文件被拒。讲清症状与原因,以及把知识库搬出上下文、按需检索的做法。

Claude知识库RAGMCP

前几天在 Reddit 的 ClaudeAI 版刷到一个帖子,有人问:往 project knowledge 里塞了差不多 200k token 的资料,会发生什么?

底下有个回答我记得很清楚:那就没有空间留给对话了。你的模型全程背着两百斤的资料在跟你聊天。

这个场景太典型了。我猜不少人正在经历同一件事,只是还没意识到:文档一份一份往项目里传,用着用着,回答开始不对劲了。

一开始不是报错,是变笨

撞墙的第一个信号,往往不是「超出上下文限制」这种报错,而是模型慢慢变笨。

你问一个库里明明有答案的问题,它答得含含糊糊;你之前定好的输出格式,它开始不遵守;同一个问题问两遍,口径对不上。多数人这时候的第一反应是「模型不行了」,或者回头去改提示词,很少有人怀疑到知识库头上。

等你想起来去传一份新文件、被拒了,才看到真正的红线。可到这一步,前面的劣化已经积了一大堆。

这不是玄学。2023 年有篇论文专门测过这件事,就是 Lost in the Middle:信息放在上下文的开头和结尾,模型记得挺好;放在中间,召回率明显往下掉,曲线是个 U 型。你塞的资料越多,「中间」就越多,被漏掉的也越多。

上下文不是硬盘,是内存

想明白这件事,只需要换一个类比。

200K token 听起来像存储空间,用起来完全是另一回事:它是内存。模型每回答你一次,都要把整个上下文从头到尾再读一遍。你塞进去的每一份文档,都是它每次思考时要重新背一遍的包袱。一份 50 页的 PDF 解析完就是好几万 token,几十份下去,窗口的大半就没了,剩下的还要挤对话历史、工具输出和系统提示。

这个类比不是我发明的。Karpathy 2023 年发过一条推文,把大模型叫「新型操作系统的内核进程」:上下文窗口是 RAM,工具调用是外设,Agent 是跑在上面的进程。玩过电脑的人都懂 RAM 的规矩,常驻的东西越少越好。

更要命的是,标称的窗口大小还得打折。NVIDIA 有个基准叫 RULER,专门量「有效上下文」:标称 32K 以上的模型,只有一半能真的扛住 32K 的任务;开源模型的有效长度普遍不到标称的一半,IBM 的 Granite 标称 128K,实测大概 32K。所以标称 200K 的窗口,你按一半做预算,反而更接近真相。

Anthropic 自己的工程博客给这个现象起了个名字,context rot:注意力是一笔固定预算,token 越多,每一段分到的越少。他们给的原则很直白,找到「达成目标所需的最小高信号 token 集」,别想着把窗口塞满。

那官方对项目知识库的建议是什么呢?精简文档。方向没错,但你细品:这是让你删知识来迁就窗口。知识只减不增,这买卖做不长久。

自救三件套,各有各的坑

撞过一次墙之后,大家的自救路数基本就三条。

第一条,拆项目、删文档。把大库拆成小库,只放当前要用的。能用,但知识就碎了:跨项目的问题答不了,同一份文档三个项目各存一份,改了一处忘两处。

第二条,人肉检索。先自己去 wiki、网盘里搜出相关段落,再贴给模型。效果立竿见影,可你回头一想,这不就回到手动时代了吗?当初引入 Agent,不就是为了不干这个。

第三条,自己写检索脚本。Karpathy 后来提倡过一个 LLM wiki 的玩法:让模型把原始资料编译成互相链接的 wiki,要用的时候取。真有人用 Claude Code 干成了,YouTube 上还有完整的实操视频。

这里有个容易被断章取义的细节。Karpathy 自己说,他本来以为要上一套 fancy RAG,结果发现编译成 wiki 就够了。注意前提:他那是个人规模的资料库。编译出来的 wiki,本质上也是把知识放到上下文外面、要用再拿。文档量一上来,编译产物自己就会撞墙。公司里动辄几十 GB 的文档,没有「我资料少」这张豁免牌。

正解就一句话:知识放外面,要用再拿

把三条路的病根说穿了其实是同一个:知识住在上下文里,该检索的时候没有检索。

正解反而简单。上下文里只放「检索结果」,永远不放「整个库」。知识库独立跑在旁边,文档随便涨,一个 token 不占模型的;Agent 回答之前先检索,只把跟当前问题相关的几段送进上下文;每段带上出处,答案能指回源文件。公司里用,最后这条是硬需求,不能只有一句「模型说的」。

巧的是,这正是 Anthropic 工程团队自己推荐的做法,人家叫 just-in-time retrieval:Agent 平时手里只拿轻量的索引,路径、链接、查询语句,要用的时候再通过工具把内容加载进来。Claude Code 的 glob 和 grep 就是这个思路。他们还把话说得很死:不管窗口做到多大,context pollution 都躲不掉,「等窗口变大」不是解法。

Databricks 也做过一个对照实验:窗口大到能把全文塞进去,检索后再喂片段,答案质量还是更好。所以 RAG 真正的意义不是赶时髦,是把知识从内存搬到硬盘的架构决策。

琅嬛就是干这个的

说了这么多,落到产品上。琅嬛做的正是这一层。

文档扔进去,解析、切分、建索引全自动;中文检索走 pgvector + zhparser 混合检索那条路;Agent 通过 MCP 调用检索,进上下文的只有命中的片段和来源锚点。单个二进制就能跑,v1.0.0 之后还有 SQLite 零配置模式,本地起个 demo 不用装数据库。

多个 Agent 共享同一个库、同一套权限、同一条证据链,不用每个项目再塞一份。这个结构我在企业场景里反复验证过,那篇讲重复建设的文章里写过。

最后

项目知识库撞上上下文限制,不是提示词没写好,是知识放错了地方。

窗口留给推理,知识放到窗外,要用再拿。文档越多,这笔账越划算。

延伸阅读

Related · 延伸阅读