基于文件系统的上下文工程
文件系统提供了一个统一接口,代理可通过它灵活地存储、检索和更新近乎无限量的上下文。此模式应对了"上下文窗口有限而任务通常需要超出单个窗口容纳的信息"这一根本约束。
核心洞见是:文件支持动态上下文发现——代理按需拉取相关上下文,而非在上下文窗口中携带所有内容。这与"无论相关性如何始终包含"的静态上下文形成对比。
何时使用
在以下情况激活本技能:
- 工具输出正在膨胀上下文窗口
- 代理需要在长轨迹中持久化状态
- 子代理必须共享信息而无需直接消息传递
- 任务需要的上下文超出窗口容量
- 构建能学习并更新自己指令的代理
- 为中间结果实现草稿区
- 终端输出或日志需要被代理访问
核心概念
上下文工程会以四种可预测方式失败。第一,当代理所需上下文不在总可用上下文中时。第二,当检索到的上下文未能封装所需内容时。第三,当检索到的上下文远超所需,浪费 token 并降低性能。第四,当代理无法发现埋在许多文件中的细分信息时。
文件系统通过提供持久层解决了这些失败:代理写入一次、按需读取,卸载大体量内容的同时保留通过搜索工具检索特定信息的能力。
详细主题
静态 vs 动态上下文的权衡
静态上下文 始终包含在 prompt 中:系统指令、工具定义和关键规则。静态上下文无论任务相关性都会消耗 token。随着代理累积更多能力(工具、技能、指令),静态上下文增长并挤占动态信息的空间。
动态上下文发现 在相关时按需加载。代理接收最少的静态指针(名称、描述、文件路径),使用搜索工具在需要时加载完整内容。
动态发现更节省 token,因为只有必要的数据进入上下文窗口。它还可以通过减少可能令人困惑或矛盾的信息来提升响应质量。
权衡:动态发现要求模型正确识别何时加载额外上下文。这在当前前沿模型上效果良好,但可能在能力较弱的模型上失败,因为它们无法识别何时需要更多信息。
模式 1:文件系统作为草稿区
问题 工具调用可能返回海量输出。一次网页搜索可能返回 10k token 的原始内容。一次数据库查询可能返回数百行。如果此内容进入消息历史,它将持续存在于整个对话,推高 token 成本并可能降低对更相关信息的注意力。
解决方案 将大型工具输出写入文件,而非直接返回到上下文。代理然后使用定向检索(grep、特定行读取)来仅提取相关部分。
实现
def handle_tool_output(output: str, threshold: int = 2000) -> str:
if len(output) < threshold:
return output
# 写入草稿区
file_path = f"scratch/{tool_name}_{timestamp}.txt"
write_file(file_path, output)
# 返回引用而非内容
key_summary = extract_summary(output, max_tokens=200)
return f"[Output written to {file_path}. Summary: {key_summary}]"
然后代理可使用 grep 搜索特定模式或使用行范围 read_file 检索目标章节。
优势
- 减少长对话中 token 累积
- 保留完整输出供后续参考
- 支持定向检索而非携带一切
模式 2:计划持久化
问题 长时域任务要求代理制定计划并遵循。但随着对话延长,计划可能从注意力中消失或在摘要中丢失。代理失去对原定任务的追踪。
解决方案 将计划写入文件系统。代理可在任何时刻重读其计划,提醒自己当前目标和进度。这有时称为"通过复述操纵注意力"。
实现 以结构化格式存储计划:
# scratch/current_plan.yaml
objective: "重构认证模块"
status: in_progress
steps:
- id: 1
description: "审计当前 auth 端点"
status: completed
- id: 2
description: "设计新 token 校验流程"
status: in_progress
- id: 3
description: "实现并测试改动"
status: pending
代理在每个回合开始或需要重新定位时读取此文件。
模式 3:子代理通过文件系统通信
问题 在多代理系统中,子代理通常通过消息传递向协调代理报告发现。这创造了"电话游戏"效应——信息在每一跳的摘要中退化。
解决方案 子代理将其发现直接写入文件系统。协调代理直接读取这些文件,绕过中间的消息传递。这保真度高,并减少协调代理中的上下文累积。
实现
workspace/
agents/
research_agent/
findings.md # 研究代理写入此处
sources.jsonl # 来源追踪
code_agent/
changes.md # 代码代理写入此处
test_results.txt # 测试输出
coordinator/
synthesis.md # 协调代理读取代理输出,写入综合
每个代理相对隔离地工作,但通过文件系统共享状态。
模式 4:动态技能加载
问题 代理可能有许多技能或指令集,但大多数与任何给定任务无关。将所有指令塞入系统 prompt 浪费 token,且可能因矛盾或不相关的指导而混淆模型。
解决方案 将技能存储为文件。静态上下文中仅包含技能名称和简要描述。代理使用搜索工具在任务需要时加载相关技能内容。
实现 静态上下文包含:
可用技能(相关时用 read_file 加载):
- database-optimization: 查询调优与索引策略
- api-design: REST/GraphQL 最佳实践
- testing-strategies: 单元、集成与 e2e 测试模式
代理仅在处理数据库任务时加载 skills/database-optimization/SKILL.md。
模式 5:终端与日志持久化
问题 长时间运行进程的终端输出快速累积。将输出复制粘贴到代理输入是手动且低效的。
解决方案 自动将终端输出同步到文件。然后代理可 grep 关键片段(错误消息、特定命令),而无需加载整个终端历史。
实现 终端会话被持久化为文件:
terminals/
1.txt # 终端会话 1 输出
2.txt # 终端会话 2 输出
代理使用定向 grep 查询:
grep -A 5 "error" terminals/1.txt
模式 6:通过自我修改学习
问题 代理通常缺乏用户在交互中隐式或明确提供的上下文。传统上,这需要在会话间手动更新系统 prompt。
解决方案 代理将学习到的信息写入自己的指令文件。后续会话加载这些文件,自动整合学到的上下文。
实现 用户提供偏好后:
def remember_preference(key: str, value: str):
preferences_file = "agent/user_preferences.yaml"
prefs = load_yaml(preferences_file)
prefs[key] = value
write_yaml(preferences_file, prefs)
后续会话包括在文件存在时加载用户偏好的步骤。
注意 此模式仍在演进。自我修改需要谨慎的护栏,以防止代理随时间累积不正确或矛盾的指令。
文件系统搜索技术
模型专门经过训练以理解文件系统遍历。ls、glob、grep 和 read_file(带行范围)的组合提供了强大的上下文发现:
ls/list_dir:发现目录结构glob:查找匹配模式的文件(如**/*.py)grep:搜索文件内容模式,返回匹配行read_file带范围:读取特定行范围而不加载整个文件
对于语义稀疏但结构模式清晰的技术内容(代码、API 文档),这种组合通常优于语义搜索。
语义搜索与文件系统搜索很好地协作:语义搜索用于概念查询,文件系统搜索用于结构和精确匹配查询。
实用指导
何时使用文件系统上下文
以下情况使用文件系统模式:
- 工具输出超过 2000 token
- 任务跨越多个对话回合
- 多个代理需要共享状态
- 技能或指令超出系统 prompt 舒适容量
- 日志或终端输出需要选择性查询
以下情况避免文件系统模式:
- 任务在单回合内完成
- 上下文舒适地适合窗口
- 延迟至关重要(文件 I/O 增加开销)
- 简单模型无法使用文件系统工具
文件组织
为可发现性组织文件:
project/
scratch/ # 临时工作文件
tool_outputs/ # 大型工具结果
plans/ # 活动计划与清单
memory/ # 持久学习信息
preferences.yaml # 用户偏好
patterns.md # 学到的模式
skills/ # 可加载技能定义
agents/ # 子代理工作区
使用一致的命名约定。在 scratch 文件中包含时间戳或 ID 以消除歧义。
Token 核算
追踪 token 来源:
- 衡量静态与动态上下文比率
- 监控工具输出大小(卸载前后)
- 追踪动态上下文实际加载频率
基于测量而非假设进行优化。
示例
示例 1:工具输出卸载
输入:网页搜索返回 8000 token
之前:8000 token 加入消息历史
之后:
- 写入 scratch/search_results_001.txt
- 返回:"[结果在 scratch/search_results_001.txt。关键发现:API 速率限制 1000 req/min]"
- 代理在需要特定细节时 grep 文件
结果:~100 token 在上下文中,8000 token 按需可访问
示例 2:动态技能加载
输入:用户询问数据库索引
静态上下文:"database-optimization: 查询调优与索引"
代理动作:read_file("skills/database-optimization/SKILL.md")
结果:仅在相关时加载完整技能
示例 3:聊天历史作为文件引用
触发:达到上下文窗口限制,需要摘要
动作:
1. 完整历史写入 history/session_001.txt
2. 为新上下文窗口生成摘要
3. 包含引用:"完整历史在 history/session_001.txt"
结果:代理可搜索历史文件以恢复摘要中丢失的细节
指南
- 将大输出写入文件;将摘要和引用返回到上下文
- 将计划与状态以结构化文件存储以便重读
- 使用子代理文件工作区而非消息链
- 动态加载技能,而非全部塞入系统 prompt
- 将终端与日志输出持久化为可搜索文件
- 组合 grep/glob 与语义搜索实现综合发现
- 用清晰的命名组织文件以提升代理可发现性
- 衡量 token 节省以验证文件系统模式有效
- 为 scratch 文件实现清理以防止无界增长
- 为自我修改模式加验证护栏
集成
本技能连接到:
- context-optimization - 文件系统卸载是一种观察遮蔽形式
- memory-systems - 文件系统即记忆是简单的记忆层
- multi-agent-patterns - 子代理文件工作区支持隔离
- context-compression - 文件引用支持无损"压缩"
- tool-design - 工具应为大输出返回文件引用
参考
内部参考:
- Implementation Patterns - 详细模式实现
本集合中的相关技能:
- context-optimization - Token 缩减技术
- memory-systems - 持久存储模式
- multi-agent-patterns - 代理协调
外部资源:
- LangChain Deep Agents:代理如何使用文件系统进行上下文工程
- Cursor:动态上下文发现模式
- Anthropic:Agent Skills 规范
技能元数据
创建:2026-01-07 最后更新:2026-01-07 作者:Agent Skills for Context Engineering 贡献者 版本:1.0.0
限制
- 仅当任务明确匹配上述范围时使用本技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请停止并要求澄清。