【译】如何利用文件系统做好上下文工程

27 阅读7分钟

这篇文章强调,文件系统让代理能灵活地存、取、改、搜无限量上下文,从而改进上下文工程,解决常见问题:过多检索、上下文超窗、小众信息难找、随时间学习等常见问题。

原文地址:blog.langchain.com/how-agents-…

深度代理的关键特性之一是它们可以访问一组文件系统工具。深度代理能用这些工具在文件系统中读、写、改、列、搜。

这篇文章会讲讲为什么我们认为文件系统对代理很重要。要理解它的帮助,先看看代理今天可能失败的原因:要么 (a) 模型不够好,要么 (b) 取不到正确的上下文。上下文工程是“把正好需要的信息塞进上下文窗口的微妙技术与科学”。理解上下文工程及其失败方式,对打造可靠代理至关重要。

上下文工程视角

可以把现代代理工程师的工作用上下文工程的视角来看。代理通常能访问大量上下文(所有支持文档、全部代码文件等)。要回答输入问题,代理需要一些重要上下文(包含解答所需的信息)。为了回答问题,代理检索了一些上下文(拉进它的上下文窗口)。

从这个视角看,代理的上下文工程可能出现多种“失败”:

  • 如果代理需要的上下文不在可用的总上下文里,它就无法成功。例如:客服代理需要某页文档来回答问题,但那页还没被索引。
  • 如果代理检索到的上下文没覆盖所需上下文,它就无法正确回答。例如:客服代理需要某页文档,那页存在且被索引,但代理没检索到。
  • 如果代理检索到的上下文远大于所需上下文,就会浪费时间或 token。例如:客服代理只需要一页,结果检索了 100 页。

我们的工作是让红圈贴近绿圈(让代理检索到的上下文尽量成为所需信息的小超集)

试着孤立出合适上下文时,会遇到一些具体挑战:

  1. Token 过多(检索上下文 >> 必要上下文)
    一些工具,如网页搜索,会返回很多 token。几次搜索就可能在对话历史里堆出上万 token。还没到 400 错误,账单和性能就先崩了。
  2. 需要大量上下文(必要上下文 > 支持的上下文窗口)
    有时代理确实需要很多信息才能回答问题。这些信息通常一次搜索拿不完,于是很多人会用“代理式搜索”——让代理多次调用搜索工具。问题是上下文很快就大到放不进窗口。
  3. 寻找小众信息(检索上下文 ≠ 必要上下文)
    代理可能需要在成百上千的文件里找埋得很深的小众信息。找不到,就检索不到回答所需的上下文。有没有替代或补充语义搜索的方法?
  4. 随时间学习(总上下文 ≠ 必要上下文)
    代理可能根本没必要的上下文可用。用户在交互中会给出线索(显式或隐式)。有没有办法把这些加入上下文,供后续迭代使用?

这些都是常见的绊脚石,我们大多遇到过不同版本。

文件系统如何让代理更强?

一句话:文件系统提供一个接口,让代理可以灵活地存、取、改无限量的上下文。

看看它如何帮助上面的场景。

Token 过多(检索上下文 >> 必要上下文)

与其把所有工具调用结果和笔记放进对话历史,不如让代理把它们写入文件系统,再在需要时按需 grep 关键字,只读必要内容。Manus 曾公开讨论过这个做法——下面这张图来自他们的博客。

沿用网页搜索的例子:我搜到 1 万 token 的原始内容,其中大部分并不总是需要。如果把它放进消息历史,1 万 token 会一直挂在那里,烧钱还拖性能。但如果把这个大结果丢进文件系统,代理就能聪明地用 grep 搜关键字,然后只把需要的内容读回上下文。

在这个例子里,代理把文件系统当作大上下文的草稿本

需要大量上下文(必要上下文 < 支持的上下文窗口)

有时代理需要大量上下文才能回答。文件系统提供了一个不错的抽象,让 LLM 能按需动态存取更多信息。例如:

  • 长周期回答需要先做计划再执行。把计划写入文件,后面可以再读回来提醒自己要做什么(比如“通过复述操控注意力”)。
  • 为了筛大量上下文,代理可能会启多个子代理。子代理在做事和学习时,与其只回复主代理,不如把知识写进文件系统(比如减少“电话游戏”效应)。
  • 有些代理需要很多操作指令。与其把全部指令塞进 system prompt(撑爆上下文),不如存成文件,让代理按需读取(比如Anthropic skills)。

寻找小众信息(检索上下文 ≠ 必要上下文)

在 LLM 浪潮初期,语义搜索很流行。但对某些文档(如技术 API 参考、代码文件),语义信息稀疏,效果会很差。

文件系统提供另一种方式:让代理用 ls、glob、grep 智能搜上下文。用过 Claude Code 的人会知道,它大量依赖 glob 和 grep 找到所需上下文。这个技巧有效有几个原因:

  • 今天的模型专门训练过去理解遍历文件系统;
  • 信息往往已经按目录结构化;
  • glob 和 grep 不仅能定位特定文件,还能定位具体的行和字符;
  • read_file 工具允许代理指定要读的行。

因此,在某些场景,使用文件系统(以及它带来的搜索能力)能获得更好的结果。

注意,语义搜索仍然有用!它可以与文件系统搜索一起用。Cursor 最近写了篇博客强调两者结合的好处。

随时间学习(总上下文 ≠ 必要上下文)

代理出错很大原因是缺少相关上下文。改进代理通常意味着确保它能访问正确的上下文。有时这意味着添加更多数据源或更新 system prompt。

更新 system prompt 的常见流程:

  1. 找到代理缺少正确指令的例子
  2. 向领域专家获取相关指令
  3. 用这些指令更新 prompt

很多时候,终端用户其实是最佳的领域专家。和代理的对话中,他们会给出重要线索(显式或隐式)。能否自动化第 3 步(用这些指令更新 prompt)?

我们认为代理的指令(或技能)与它想用的其他上下文没有区别。文件系统可以成为代理存储和更新自身指令的地方!

在用户反馈后,代理可以写文件记住重要信息。对一些快速的一次性事实很有用,尤其是用户特有的东西,比如名字、邮箱或偏好。

这还没完全解决,仍是新兴模式,但它让 LLM 随时间增长技能和指令更有希望,确保后续迭代能拿到必要上下文。

深度代理如何利用其文件系统

我们有一个开源项目 Deep Agents(PythonTypeScript),可快速构建带文件系统的代理。很多基于文件系统的上下文工程技巧都内置了!肯定还会有更多模式出现——试试 Deep Agents,并告诉我们你的想法!