当前位置: 首页 > news >正文

Hello-Agents 第二部分-第九章总结:上下文工程

作者:逆境不可逃

技术永无止境

希望我的内容可以帮助到你!!!!!


大家吼 ! 我是 逆境不可逃 今天给大家带来文章《Hello-Agents 第二部分-第九章总结:上下文工程》.

Hello-Agents 官方地址:datawhalechina/hello-agents: 📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程

上篇文章《Hello-Agents 第二部分-第八章总结:记忆与检索》

https://blog.csdn.net/2401_87662859/article/details/161246945?spm=1001.2014.3001.5501

前言

本章的核心目标是把第 8 章的记忆与 RAG 能力继续往工程化方向推进:不再只问 “Agent 能记住什么、能检索什么”,而是进一步问 “每一次调用模型前,应该把哪些信息、以什么结构、在多大预算内交给模型”。这就是上下文工程Context Engineering

一句话概括:提示工程关注怎么写指令;上下文工程关注怎样持续管理模型可见的全部 token,包括系统提示、工具说明、外部检索结果、对话历史、笔记、文件内容和任务状态。它的目标不是把所有信息都塞进窗口,而是在有限注意力预算内构造高信号、低噪声、可复用、可评估的上下文。

配套代码建议按下面顺序阅读:

文件关注点
01_context_builder_basic.pyContextBuilder基础用法、ContextConfig参数、结构化上下文构建
02_context_builder_with_agent.pyContextBuilder集成到SimpleAgent,让 Agent 每轮自动构造上下文
03_note_tool_operations.pyNoteToolcreate/read/update/search/list/summary/delete基础操作
04_note_tool_integration.pyNoteToolContextBuilder协作,把历史笔记注入上下文
05_terminal_tool_examples.pyTerminalTool的文件探索、数据分析、日志分析、代码库分析和安全限制
06_three_day_workflow.py三天代码库维护流程:探索、分析、规划、复盘
codebase_maintainer.py长程代码库维护助手核心实现,整合ContextBuilder + NoteTool + TerminalTool + MemoryTool
codebase/用于演示代码分析的样例代码库
data/sales_2024.csv用于演示即时数据文件分析的样例 CSV

1. 上下文工程是什么

LLM 的一次调用本质上只看当前传入的 token。这里的 token 不只是用户问题,还包括系统提示、开发者指令、工具描述、历史消息、检索结果、记忆、文件片段和中间推理产物。上下文工程就是管理这组 token 的工程方法。

它和提示工程的区别可以这样理解:

对比项提示工程上下文工程
核心问题怎样写好 prompt怎样组织模型可见的全部信息
主要对象系统提示、任务描述、示例提示、工具、历史、记忆、RAG、文件、笔记、状态
时间尺度多数是单轮或短任务优化面向多轮、长时程、跨会话任务
工程目标让模型更容易按指令输出让模型持续获得正确、相关、适量的信息
典型风险指令含糊、格式不稳上下文污染、信息过载、长程状态丢失

本章强调的关键判断是:上下文是有限资源,并且具有边际收益递减。即使模型支持很长的上下文窗口,也不意味着越长越好。长上下文会引入更多干扰、更多相互冲突的信息和更高的推理成本,模型从长窗口中稳定找回关键信息的能力也会下降。

2. 为什么上下文工程重要

2.1 上下文腐蚀

上下文腐蚀context rot指的是:随着上下文窗口中 token 数量增加,模型从上下文中准确回忆、定位和使用关键信息的能力反而下降。它不是突然失效,而是性能逐渐退化。

原因主要有三类:

  • 注意力被拉薄:Transformer 中 token 之间存在大规模相互作用,窗口越长,模型越难稳定关注真正关键的依赖。
  • 噪声增多:无关历史、重复工具输出、过期计划和冗长日志都会稀释高价值信息。
  • 训练分布限制:模型虽然能处理长上下文,但训练中短序列和局部依赖更常见,超长、复杂、全局依赖的稳定性天然更难。

所以,构建 Agent 时不能把 “长上下文窗口” 当成免管理的仓库。真正可靠的做法是把上下文视为注意力预算,持续选择、压缩、结构化和外部化信息。

2.2 有效上下文的组成

有效上下文的目标是:用尽可能少但足够的 token,让模型最大概率产生期望行为。它通常包括三类核心元素。

系统提示

系统提示负责定义角色、边界、工作原则、工具使用规则和输出格式。常见的两个极端都不好:

  • 过度硬编码:把大量脆弱的 if-else 写进提示,维护困难,且容易和真实情况冲突。
  • 过于空泛:只说 “你是专业助手”“请准确回答”,缺少可执行的判断标准和输出要求。

更好的写法是把系统提示分区,例如[Role & Policies][Task][Tools][Output],用清晰层次表达 “必须遵守的规则” 和 “可灵活判断的策略”。

工具

工具决定 Agent 能访问哪些信息、能采取哪些行动。工具设计不只是功能问题,也是上下文问题:工具描述、入参、返回值都会消耗 token 并影响模型决策。

好的工具应该职责单一、边界清楚、参数明确、错误可恢复、输出 token 友好。工具集也应避免臃肿。如果多个工具能力重叠,模型会把大量注意力浪费在 “该用哪个工具” 上。一个小而清晰的最小可行工具集,通常比一个大而模糊的工具箱更稳定。

示例

Few-shot 示例的价值在于直接展示期望行为。示例不是越多越好,而是要多样、典型、能覆盖关键边界。对模型而言,一个高质量示例往往比一大段抽象规则更可执行。

2.3 JIT 上下文与渐进式披露

传统 RAG 常见做法是 “推理前一次性检索”:先根据 query 找一批相关片段,再统一放入上下文。第 9 章进一步强调Just-in-time上下文:不要预先加载全部资料,而是保留文件路径、查询语句、URL、笔记 ID 等轻量引用,让 Agent 在运行时通过工具按需获取。

例如代码审查中,没必要一开始把 50 个文件全部塞入上下文。更好的方式是:

  1. 先读取目录结构和 README。
  2. 根据任务定位关键模块。
  3. grep/find/head/tail查找具体函数、TODO、错误日志或配置项。
  4. 只把当前判断需要的片段放进上下文。
  5. 把阶段性结论写入笔记,后续按需拉回。

这就是渐进式披露progressive disclosure:每一步探索都会产生新的线索,新线索又指导下一步探索。目录名、文件大小、时间戳、错误栈、函数名都不是最终答案,却能帮助 Agent 决定下一步看哪里。

JIT 的优势是实时、低成本、不容易受过时索引影响;代价是更慢,需要工具设计和探索策略足够好。实践中通常采用混合策略:预置少量高价值上下文,例如 README、项目约定、当前任务说明,再允许 Agent 用工具动态检索细节。

3. 长时程任务的三类策略

长时程任务的难点不是单轮回答,而是跨很多轮、很多工具调用甚至很多天后仍然保持目标一致、状态清楚、行动连贯。本章给出三类主要策略。

策略解决的问题典型做法适用场景
压缩整合Compaction历史太长,窗口接近上限把历史高保真总结后重启上下文长对话、长调试、连续研究
结构化笔记Structured note-taking关键状态需要跨窗口保存把结论、阻塞、计划写入外部笔记项目维护、研究任务、复杂计划
子代理架构Sub-agent单一上下文难以容纳并行探索主代理规划汇总,子代理独立探索后回传摘要大规模代码库分析、复杂研究、多方向排查

压缩整合要优先保证召回,也就是不要漏掉关键决策、未解决问题、接口约束和实现细节;其次再优化精确度,删除重复工具输出和噪声。

结构化笔记是本章落地的重点。它把 “当前不该塞进上下文,但未来可能重要” 的信息放到上下文外,必要时再检索回来。

子代理架构的关键价值是隔离噪声。主代理保持干净的高层上下文,子代理在自己的窗口中做深挖,最后只返回压缩后的结论。

4. ContextBuilder:上下文构建器

ContextBuilder是本章最核心的组件。它把上下文构建抽象成一条固定流水线:

Gather -> Select -> Structure -> Compress 汇集 选择 结构化 压缩

这条流水线简称GSSC。它的设计目标是减少 Agent 中重复的上下文拼接代码,并让上下文构建过程可调试、可评估、可替换。

4.1 核心数据结构

ContextPacket是候选信息包。任何可能进入上下文的信息都先被包装成统一结构。

@dataclass class ContextPacket: content: str timestamp: datetime token_count: int relevance_score: float = 0.5 metadata: Optional[Dict[str, Any]] = None

关键字段含义:

字段作用
content实际文本内容
timestamp信息产生或更新的时间,用于新近性评分
token_count估算 token 数,用于预算控制
relevance_score与当前任务的相关性,范围通常是 0 到 1
metadata类型、来源、优先级、笔记 ID 等扩展信息

ContextConfig管理上下文构建参数。

config = ContextConfig( max_tokens=3000, reserve_ratio=0.2, min_relevance=0.1, enable_compression=True, recency_weight=0.3, relevance_weight=0.7, )

其中reserve_ratio很重要,它为系统指令等高优先级信息预留空间,避免被历史消息或检索结果挤掉。relevance_weightrecency_weight控制 “相关性” 和 “新近性” 的权衡。

4.2 Gather:多源汇集

Gather负责收集候选信息。来源包括:

  • 系统指令:最高优先级,通常必须保留。
  • MemoryTool:检索相关记忆。
  • RAGTool:检索外部知识证据。
  • 对话历史:通常只取最近若干条,防止历史淹没当前任务。
  • 自定义信息包:例如NoteTool笔记、TerminalTool输出、人工传入的状态。

这一阶段的重点是容错。每个外部数据源都应该单独捕获异常,记忆检索失败不能导致整个上下文构建失败。

4.3 Select:智能选择

Select是 GSSC 的核心。它在 token 预算内选择最值得进入上下文的信息。

选择逻辑大致是:

  1. 先分离系统指令和普通信息,系统指令优先保留。
  2. 对普通信息计算相关性分数和新近性分数。
  3. 用加权公式得到综合分数:
combined_score = relevance_weight * relevance_score + recency_weight * recency_score
  1. 过滤掉低于min_relevance的信息。
  2. 按综合分数从高到低贪心填充,直到达到 token 上限。

这里的算法不复杂,但工程上很实用。它把 “保留什么” 变成可解释的排序问题。生产环境中,相关性可以从简单关键词重叠升级为向量相似度、BM25 或混合检索。

4.4 Structure:结构化输出

Structure把选中的信息组织成稳定模板。本章推荐的骨架类似:

[Role & Policies] 角色、规则、边界 [Task] 当前用户问题或任务 [Evidence] RAG 或外部知识证据 [Context] 历史消息、记忆、笔记、工具结果 [Output] 输出格式和要求

稳定结构有三个好处:

  • 模型更容易区分 “规则、任务、证据、上下文”。
  • 人类更容易调试,能快速判断哪个分区引入了错误信息。
  • 方便做 A/B 测试和日志评估。

4.5 Compress:兜底压缩

Compress在上下文超限时触发。代码中的基础实现是分区压缩:尽量完整保留前面的结构化分区,超限部分再截断并标记 “内容已压缩”。

更成熟的压缩策略可以分层:

情况推荐策略
日志、工具输出、重复文本截断、抽样、保留首尾
对话历史摘要压缩,保留决策和未解决问题
代码文件保留签名、关键函数、错误附近片段
任务计划结构化摘要,保留状态、依赖、下一步
法规、合同、精确证据尽量不摘要,改为引用片段和来源定位

压缩不是简单变短,而是保留任务继续推进所需的状态。最危险的压缩是把 “为什么这么做”“还没解决什么”“哪些约束不能破坏” 压掉。

4.6 代码示例对应关系

01_context_builder_basic.py演示了最小用法:

config = ContextConfig( max_tokens=3000, reserve_ratio=0.2, min_relevance=0, enable_compression=True, ) builder = ContextBuilder(config=config) context_str = builder.build( user_query="如何优化Pandas的内存占用?", conversation_history=conversation_history, system_instructions="你是一位资深的Python数据工程顾问。" )

这里的核心不是 LLM 调用,而是build()返回一个结构化上下文字符串,可直接作为 system message 传给模型。

02_context_builder_with_agent.py把它封装进ContextAwareAgent.run()

optimized_context = self.context_builder.build( user_query=user_input, conversation_history=self.conversation_history, system_instructions=self.system_prompt, ) messages = [ {"role": "system", "content": optimized_context}, {"role": "user", "content": user_input}, ] response = self.llm.invoke(messages)

这说明上下文工程最好不要散落在业务代码里,而应该变成 Agent 每轮运行前的标准步骤。

5. NoteTool:结构化笔记

NoteTool是面向长时程任务的结构化外部记忆。它和第 8 章的MemoryTool不冲突,二者侧重点不同:

工具更适合保存特点
MemoryTool对话记忆、用户偏好、经验、语义知识更像智能体内部记忆,可结合向量检索
NoteTool项目状态、任务计划、阻塞点、阶段结论Markdown + YAML,人类可读,版本控制友好

5.1 为什么需要 NoteTool

长程任务中,很多信息不是一句普通记忆,而是需要持续维护的项目状态,例如:

  • 当前重构做到哪一步。
  • 哪些 blocker 还没解决。
  • 哪些方案已经被否定,原因是什么。
  • 下一步行动计划是什么。
  • 某个结论来自哪个文件或哪次分析。

这些信息如果只放在对话历史里,很快会被上下文窗口挤掉;如果每次都重新分析,又浪费时间且容易前后不一致。结构化笔记提供了一个轻量、可编辑、可检索的外部状态层。

5.2 存储格式

NoteTool 采用 Markdown 正文加 YAML 前置元数据的混合格式。典型笔记可以设计为:

--- id: note_20250119_153000_0 title: 依赖冲突问题 type: blocker tags: - dependency - urgent created_at: 2025-01-19T15:30:00 updated_at: 2025-01-19T15:30:00 --- ## 问题描述 某些第三方库版本不兼容。 ## 影响范围 业务逻辑层的 3 个模块。 ## 下一步 1. 使用虚拟环境隔离。 2. 锁定版本。 3. 分析依赖树。

这种设计的好处是:

  • 机器可解析:YAML 元数据便于按类型、标签、时间检索。
  • 人类可读:Markdown 正文能直接编辑和审阅。
  • Git 友好:纯文本天然适合版本控制。
  • 容易回注上下文:检索后可转换为ContextPacket

5.3 核心操作

03_note_tool_operations.py展示了 NoteTool 的完整生命周期:

操作作用关键参数
create创建笔记title,content,note_type,tags
read读取指定笔记note_id
update更新笔记内容或元数据note_id,content
search按关键词检索笔记query,limit
list按类型列出笔记note_type,limit
summary生成笔记统计摘要无或过滤参数
delete删除笔记note_id

建议使用固定笔记类型:

类型用途上下文优先级
blocker阻塞问题、风险、待解决缺陷最高
action下一步行动计划
task_state阶段进度、当前状态
conclusion已确认结论、设计决策中高
reference参考资料、链接、文件位置
scratch临时探索记录低,需定期整理

5.4 与 ContextBuilder 集成

04_note_tool_integration.py的关键思路是:每轮对话前先用 NoteTool 检索相关笔记,再把笔记转换成ContextPacket注入ContextBuilder

简化流程如下:

用户输入 -> 检索 blocker 和相关笔记 -> notes_to_packets() -> ContextBuilder.build(additional_packets=note_packets) -> LLM 生成回答 -> 必要时把本轮结论保存为新笔记

代码中的ProjectAssistant._retrieve_relevant_notes()采用了一个务实策略:

  1. 优先列出blocker类型笔记。
  2. 再按当前 query 搜索相关笔记。
  3. 合并去重。
  4. 限制数量,避免笔记反过来挤爆上下文。

_notes_to_packets()则负责把笔记变成上下文候选信息:

ContextPacket( content=f"[笔记:{title}]\n{body}", timestamp=parsed_ts, token_count=len(content) // 4, relevance_score=0.75, metadata={ "type": "note", "note_type": note_type, "note_id": note_id, }, )

这一步非常关键:NoteTool 本身只是存储工具,只有转换成ContextPacket后,它才进入 GSSC 选择与压缩流程。

5.5 使用建议

NoteTool 的难点不是能不能写笔记,而是笔记会不会变成新的噪声源。实践建议:

  • 每条笔记只表达一个主题,避免 “大杂烩笔记”。
  • 标题要可检索,例如 “OrderService 嵌套过深” 比 “发现一个问题” 更好。
  • blocker要少而准,避免所有问题都标成最高优先级。
  • 已解决的 blocker 应更新状态或转为 conclusion。
  • 临时笔记要定期整理,重要内容上升为 task_state 或 conclusion,重复内容归档。
  • 人类应能审阅和修改笔记,长程任务不能完全依赖模型自己维护状态。

6. TerminalTool:即时文件系统访问

TerminalTool是本章实现 JIT 上下文的关键工具。它允许 Agent 用受控命令即时探索文件系统,而不是预先把整个代码库、日志目录或数据文件全部索引进 RAG。

6.1 适用场景

05_terminal_tool_examples.py展示了四类典型场景:

场景示例命令价值
探索式导航ls,find,head快速了解目录和关键文件
数据文件分析head,wc,cut,sort,uniq低成本预览 CSV 结构和分布
日志分析tail,grep,awk定位最近错误和错误类型
代码库分析find,grep,wc查找 TODO、函数定义、代码规模

相比 RAG,TerminalTool 更适合实时、精确、低预处理成本的任务。比如查看 “最新 50 行日志” 或 “当前代码库里所有 TODO”,向量索引反而不是最直接的工具。

6.2 安全机制

让 Agent 执行命令很强大,也很危险。本章的 TerminalTool 设计了多层防护:

安全层作用示例
命令白名单只允许相对安全的只读命令允许cat/head/grep/find/wc,拒绝rm
工作目录沙箱只能访问指定 workspace 内部拒绝cat /etc/passwdcd ../../../etc
超时控制防止命令卡死或长时间扫描timeout=30
输出大小限制防止一次返回巨量内容超过上限截断

这说明 TerminalTool 不是通用 shell,而是 “安全受限的信息获取工具”。如果要扩展到写文件、执行测试、运行 git 等高风险操作,应引入更严格的审批和权限分级。

6.3 与其他工具协同

TerminalTool 的输出通常不应长期留在对话历史中,而应按价值分流:

TerminalTool 即时发现 -> 当前轮需要的片段:放入 ContextBuilder -> 重要结论:写入 NoteTool -> 用户偏好或稳定知识:写入 MemoryTool -> 大规模知识库:必要时进入 RAG 索引

例如:

  • grep -rn "TODO"的完整输出可能很长,不适合长期保留。
  • 但 “支付模块有 3 个高优先级 TODO,集中在 order_service.py” 是结论,适合写入conclusionblocker
  • “下一步先补测试再重构” 是计划,适合写入actiontask_state

7. 长程智能体实战:代码库维护助手

第 9 章最终把三个工具整合成 “代码库维护助手”。这个案例的价值在于,它不是单轮问答,而是跨天持续工作的 Agent。

7.1 场景

假设要维护一个中型 Python Web 应用,代码库包含几十个文件,存在技术债务,需要完成:

  • 探索代码结构。
  • 识别重复代码、复杂函数、缺少测试、TODO/FIXME。
  • 记录问题和风险。
  • 规划重构任务。
  • 跨会话复盘进度。

这个任务天然超过单轮上下文窗口,也不适合一次性把所有文件塞给模型。

7.2 工具分层

代码库维护助手采用分层上下文管理:

工具保存什么生命周期
即时访问层TerminalTool文件片段、目录结构、日志、命令结果当前轮或短期
会话记忆层MemoryTool近期对话、用户意图、关键交互会话内到跨会话
持久笔记层NoteToolblocker、action、task_state、conclusion跨天、跨会话
上下文编排层ContextBuilder从以上来源筛选后的高价值上下文每次模型调用前

这四层合起来解决了长程任务的核心矛盾:信息很多,但模型每次只应看到当前最有用的一部分。

7.3codebase_maintainer.py的实现重点

当前代码中的CodebaseMaintainer是更 Agentic 的版本,使用FunctionCallAgentToolRegistry,让 Agent 自主决定是否调用工具,而不是写死每一步流程。

初始化阶段:

self.memory_tool = MemoryTool( user_id=project_name, memory_types=["working"], ) self.note_tool = NoteTool(workspace=f"./{project_name}_notes") self.terminal_tool = TerminalTool(workspace=codebase_path, timeout=60) self.context_builder = ContextBuilder( memory_tool=self.memory_tool, rag_tool=None, config=ContextConfig( max_tokens=4000, reserve_ratio=0.15, min_relevance=0.2, enable_compression=True, ), )

run()的主流程是:

1. 根据用户输入检索相关笔记,尤其优先 blocker。 2. 将笔记转换为 ContextPacket。 3. 用 ContextBuilder 构建优化上下文。 4. 更新 FunctionCallAgent 的 system_prompt。 5. 让 Agent 自主调用 TerminalTool、NoteTool、MemoryTool。 6. 统计工具使用并更新对话历史。

代码里提供了三个便捷模式:

方法模式作用
explore()explore引导 Agent 侧重目录结构、README、关键模块
analyze()analyze引导 Agent 查找 TODO、复杂度、缺测试等问题
plan_next_steps()plan引导 Agent 回顾笔记并制定下一步计划

这里的mode不是硬编码流程,而是给 Agent 的方向性提示。真正的工具选择仍由 Agent 根据上下文和工具描述决定。

7.4 三天工作流

06_three_day_workflow.py把长程协作分成几个阶段:

阶段目标主要工具产物
第一天:探索代码库了解目录、模块、核心文件TerminalTool,NoteTool架构笔记、初步问题
第二天:质量分析找重复代码、复杂函数、TODO、测试缺口TerminalTool,NoteToolblocker、action
第三天:规划重构根据历史发现排序任务NoteTool,ContextBuildertask_state、重构计划
一周后:复盘检查进度并生成报告NoteToolsummary、report

这个案例体现了上下文工程的几个关键能力:

  • 跨会话连贯:前几天记录的问题能在后续规划中被召回。
  • 上下文筛选:不是所有历史都进入模型,只拉取当前相关的笔记。
  • 即时探索:需要具体文件时再用 TerminalTool 查看。
  • 自动知识管理:重要发现写入笔记,避免丢失。
  • 人机协作:人类可以手动新增、修改、审核计划笔记。

7.5 可扩展方向

这个案例还可以继续扩展:

  • 接入RAGTool,为代码库构建语义索引,用于概念级检索。
  • 拆分探索者、分析者、规划者三个子代理,提升复杂任务并行度。
  • 允许受控执行测试命令,把验证结果纳入笔记。
  • 与 git 集成,记录变更、diff 和回滚点。
  • 用 Gradio 或 Streamlit 做可视化任务看板。

8. 本章关键实践原则

  1. 上下文不是越多越好,而是越相关、越新、越结构化越好。
  2. 系统提示要稳定,但不能把复杂业务流程全部硬塞进提示。
  3. 工具集要小而清晰,工具返回值要面向 token 预算设计。
  4. 长程任务必须有外部状态层,不能只依赖对话历史。
  5. 即时访问适合动态、实时、精确的信息;RAG 适合稳定、语义化、可复用的知识。
  6. 压缩要保留决策、约束、未解决问题和下一步,而不是只追求短。
  7. 笔记必须定期整理,否则会从 “外部记忆” 变成 “外部噪声”。
  8. 高风险工具调用必须有安全边界和人类审批。

9. 运行建议

本章代码依赖.env中的 LLM 配置。README 里也给出了嵌入模型配置建议,快速测试可使用 TF-IDF:

import os os.environ["EMBED_MODEL_TYPE"] = "tfidf" os.environ["EMBED_MODEL_NAME"] = ""

推荐运行顺序:

cd D:\Project\Agent\hello-agents-1.0.2\code\chapter9 # 先运行不强依赖 LLM 的工具示例 python 03_note_tool_operations.py python 05_terminal_tool_examples.py # 再看上下文构建和 Agent 集成 python 01_context_builder_basic.py python 02_context_builder_with_agent.py # 最后看完整长程工作流 python 06_three_day_workflow.py

如果MemoryTool使用working之外的记忆类型,可能需要向量数据库或嵌入模型配置;codebase_maintainer.py中为了降低依赖,使用了memory_types=["working"]

10. 习题解析

题 1:上下文工程与提示工程

1.1 什么是上下文腐蚀?为什么 100K/200K 窗口仍需管理?

上下文腐蚀是指上下文变长后,模型对关键信息的定位、回忆和使用能力下降。它不代表模型不能读长文本,而是代表长文本中的有效注意力会被更多 token 分散。

即使有 100K 或 200K 窗口,也要谨慎管理,原因是:

  • 成本更高:输入 token 越多,费用和延迟越高。
  • 噪声更多:过期信息、重复工具输出、无关历史会影响判断。
  • 冲突更多:旧计划和新计划、旧代码和新代码可能互相矛盾。
  • 精度下降:模型可能忽略中间位置的信息,或错误引用不相关片段。

所以长窗口是缓冲区,不是垃圾桶。工程上应优先放入高价值信息,并把低价值信息放到外部存储中按需检索。

1.2 代码审查助手:一次性加载 50 个文件 vs JIT 按需检索

策略优点缺点适用场景
一次性加载全部文件实现简单,模型能直接看到全局内容,适合小代码库成本高、噪声大、容易超限,文件更新后上下文过时文件少、任务要求全局一致性、代码量可控
JIT 按需检索实时、低成本、聚焦当前问题,可处理大代码库多轮工具调用更慢,需要探索策略,可能漏查大代码库、日志分析、定位具体缺陷、持续维护

对 50 个文件的代码审查助手,推荐混合方案:先加载 README、目录结构、依赖配置和变更摘要,再通过find/grep/head按需查看关键文件。最后把审查发现写入 NoteTool,避免重复扫描。

1.3 系统提示的两个误区与平衡

过度硬编码示例:

如果用户问性能,就先查 A 文件;如果问数据库,就先查 B 文件; 如果出现 timeout,就必须回复固定模板……

问题是流程脆弱,真实项目结构变化后容易误导 Agent。

过于空泛示例:

你是一个优秀的代码审查助手,请认真分析代码并给出建议。

问题是缺少审查维度、工具使用规则、输出格式和风险等级标准。

平衡写法应包含稳定原则和可执行约束:

你是代码审查助手。优先关注正确性、安全、数据一致性、错误处理和测试缺口。 当缺少文件内容时,使用工具按需检索;不要假设未查看的代码。 输出按 P0/P1/P2 分级,每条包含文件位置、问题、影响和建议修复。

题 2:GSSC 流水线

2.1 四个阶段失效的影响

阶段失效表现对 Agent 的影响
Gather没取到关键记忆、RAG、笔记或工具结果回答缺上下文,重复提问或错误假设
Select选入无关信息,漏掉关键证据注意力被噪声占据,判断偏离任务
Structure信息混在一起,无分区和来源模型分不清规则、证据、历史,调试困难
Compress压缩过度或截断关键状态长程任务断裂,遗漏约束、计划和风险

最危险的是 Select 和 Compress。前者决定模型看什么,后者决定超限时牺牲什么。两者都应有日志和评估指标。

2.2 为 ContextBuilder 添加上下文质量评估

可以在build()后增加evaluate_context_quality(),输出三个指标:

  • 信息密度:非模板文本中有效内容占比,重复片段越多分数越低。
  • 相关性:选中 packet 的平均相关性分数。
  • 完整性:是否包含系统指令、当前任务、必要证据、历史状态、输出要求。

示例设计:

def evaluate_context_quality(context: str, packets: list[ContextPacket]) -> dict: avg_relevance = sum(p.relevance_score for p in packets) / max(len(packets), 1) total_tokens = sum(p.token_count for p in packets) unique_contents = {p.content.strip() for p in packets} duplication_rate = 1 - len(unique_contents) / max(len(packets), 1) sections = { "role": "[Role & Policies]" in context, "task": "[Task]" in context, "context": "[Context]" in context or "[Evidence]" in context, "output": "[Output]" in context, } completeness = sum(sections.values()) / len(sections) suggestions = [] if avg_relevance < 0.5: suggestions.append("相关性偏低,建议提高 min_relevance 或优化检索 query。") if duplication_rate > 0.3: suggestions.append("重复信息较多,建议去重或压缩历史工具输出。") if completeness < 1: suggestions.append("上下文分区不完整,检查系统指令、任务和输出要求。") return { "avg_relevance": avg_relevance, "token_count": total_tokens, "duplication_rate": duplication_rate, "completeness": completeness, "suggestions": suggestions, }

这个功能最好和日志结合,记录每次构建时选中了哪些 packet、丢弃了哪些 packet、为什么丢弃。

2.3 截断、滑动窗口、LLM 摘要分别适合什么?混合压缩策略怎么设计?

简单截断更适合结构清楚、重要信息集中在开头的内容,例如 README 前言、命令输出前 N 行、错误栈顶部。滑动窗口适合关注最近状态的内容,例如对话最近几轮、日志最后 200 行。LLM 摘要适合长对话、研究过程、设计讨论,因为需要抽取决策和未解决问题。

混合压缩策略:

  1. 按信息类型分类。
  2. 工具输出先去重和截断,保留命令、关键结果和错误。
  3. 对话历史用滑动窗口保留最近几轮。
  4. 深历史用 LLM 摘要,保留决策、约束、TODO 和风险。
  5. 法规、合同、代码关键片段不轻易摘要,而是保留引用位置和原文片段。
  6. 压缩后重新做质量评估,确保关键字段未丢失。

题 3:NoteTool 和 TerminalTool 扩展

3.1 笔记自动整理机制

可以把笔记分为三层:

  • 临时笔记scratch:工具探索、中间发现、未经确认的问题。
  • 任务笔记task_state/action/blocker:当前阶段需要跟踪的状态。
  • 项目笔记conclusion/reference:长期有效的设计决策、架构事实和稳定知识。

自动整理流程:

触发条件: scratch 数量超过阈值,或任务阶段结束,或上下文构建频繁命中重复笔记 整理步骤: 1. 按 tags、文件路径、主题聚类。 2. 识别重复内容和已解决内容。 3. 将高价值发现提升为 blocker/action/conclusion。 4. 给每条提升笔记补充来源和时间。 5. 将低价值 scratch 归档或删除。 6. 生成人类可审阅的整理报告。

关键是不要让 Agent 静默删除重要信息。自动整理应先生成草案,由人类审核或至少保留归档。

3.2 TerminalTool 安全机制是否足够?如何做人机审批?

当前白名单、路径验证、权限检查、超时和输出限制适合只读探索,但不足以安全支持敏感文件访问或危险操作。风险包括:

  • 白名单命令也可能泄露敏感信息,例如cat secrets.env
  • grep可能大范围扫出密钥。
  • sed/awk如果允许复杂表达式,可能产生非预期行为。
  • 写操作、测试执行、git 操作会改变系统状态。

人机协作审批流程可以这样设计:

风险等级操作处理方式
ls,find,head查看普通项目文件自动执行并记录日志
读取.env、密钥文件、用户数据、生产日志先展示原因、路径、范围,请人类批准
写文件、删除文件、数据库变更、网络请求、部署默认禁止,必须人工批准并限定参数
极高删除目录、重置仓库、修改生产配置不允许 Agent 自主执行

审批请求应包含:命令、工作目录、访问路径、目的、预期输出、潜在风险和回滚方案。审批结果也要写入 NoteTool,便于审计。

3.3 智能代码重构助手流程图

用户提出重构目标 -> ContextBuilder 构建初始上下文 -> TerminalTool 读取 README、目录结构、测试情况 -> NoteTool 写入 task_state: 初始理解 -> TerminalTool 定位目标模块和相关调用 -> Agent 分析风险和依赖 -> NoteTool 写入 blocker/action/conclusion -> 人类确认重构计划 -> 受控执行小步修改 -> 运行测试或静态检查 -> TerminalTool 收集结果 -> NoteTool 更新进度和问题 -> ContextBuilder 在下一轮只召回相关状态 -> 循环直到任务完成 -> 生成最终报告和遗留问题清单

这里最重要的是小步推进和状态外部化。每个阶段都要有可恢复的笔记记录,不能把重构过程只留在对话历史中。

题 4:长时程任务管理案例

4.1 三层上下文如何协调?

信息类型放在哪里原因
当前要看的文件片段、命令输出TerminalTool -> 当前上下文即时、局部、可能很快过期
最近几轮对话目标和偏好MemoryTool working支撑会话连贯
阻塞问题、任务计划、阶段结论NoteTool需要跨会话稳定保存
大量稳定文档、API 文档、知识库RAGTool适合语义检索和复用
每次模型调用的最终输入ContextBuilder负责筛选和编排

避免冗余和不一致的方法:

  • 每类信息有唯一主存储:计划以 NoteTool 为准,短期对话以 MemoryTool 为准。
  • 笔记需要状态字段,例如open/resolved/archived
  • 重要结论写来源和更新时间。
  • ContextBuilder 只拉取相关笔记,不把所有笔记都塞入上下文。
  • 当 Memory 和 Note 冲突时,优先使用更新时间更新、类型更权威的信息。

4.2 断点续传机制

断点续传要记录足够恢复的信息:

type: task_state status: in_progress current_phase: refactor_order_service last_completed_step: add_characterization_tests next_step: extract_stock_check_method modified_files: - services/order_service.py - tests/test_order_service.py open_blockers: - note_20250119_153000_2 validation: last_test_command: pytest tests/test_order_service.py last_test_result: failed failure_summary: test_process_order_pending_stock

恢复流程:

  1. 读取最新task_state
  2. 检查相关文件是否仍存在、是否有未提交改动。
  3. 读取 open blocker 和 action。
  4. 重新运行或查看最近验证命令结果。
  5. 让 Agent 生成 “恢复计划”,先请人类确认。
  6. 继续执行下一步。

验证恢复正确性的关键是对比笔记状态与真实环境:文件、测试、git diff、依赖版本都要重新确认,不能只相信笔记。

4.3 任务依赖管理系统

可以用 NoteTool 存储任务节点:

id: task_add_email_unique_constraint type: action status: pending priority: high depends_on: - task_check_duplicate_emails blocks: - task_run_user_migration estimated_effort: 0.5d owner: agent

调度逻辑:

  1. 读取所有action/task_state笔记。
  2. 构建依赖图。
  3. 检查环形依赖。
  4. 找出depends_on全部完成的任务作为 ready 队列。
  5. 按优先级、风险、工作量排序。
  6. 执行或建议下一步。
  7. 更新任务状态并写回 NoteTool。

这样 NoteTool 不只是记录文本,而是变成轻量任务数据库。

题 5:渐进式披露

5.1 应用场景:复杂 bug 调试

以 “线上接口偶发 500” 为例:

第一步:读取最近错误日志 -> 发现错误集中在 /orders 第二步:查看 /orders 路由 -> 发现调用 OrderService.process_order 第三步:查看 process_order -> 发现库存检查和状态更新在同一函数 第四步:搜索相关 TODO 和最近提交 -> 发现有人改过库存字段类型 第五步:运行或查看测试 -> 发现缺少并发扣库存测试 第六步:记录 blocker 和修复计划

Agent 每一步只看必要信息,后续探索由前一步结果决定。这比一次性加载全部日志、全部代码和全部历史提交更聚焦。

5.2 探索引导机制

为避免 Agent 在不重要细节上浪费时间,可以设计元认知检查:

  • 每轮工具调用前回答:我为什么需要这个信息?它会改变哪个决策?
  • 限制同类探索次数,例如连续 3 次 grep 没有新发现就换策略。
  • 优先查看高信号文件:README、入口文件、配置、错误栈指向文件、测试文件。
  • 为每个阶段设置信息目标,例如 “定位模块”“确认根因”“验证修复”。
  • 定期生成探索摘要:已知事实、未知问题、下一步最高价值动作。
  • 使用 NoteTool 记录已排除路径,避免重复探索。

可以给 Agent 一个简单策略:

每次探索后更新: 1. 已确认事实 2. 当前最可能假设 3. 仍缺的证据 4. 下一步最小代价验证动作

5.3 渐进式披露 vs 一次性加载的适用任务

渐进式披露明显占优的任务:

  1. 大代码库调试:信息量大,相关文件需要逐步定位。
  2. 日志排障:最近错误、时间窗口、服务链路决定下一步查哪里。
  3. 学术综述:先看摘要和引用网络,再深入关键论文。
  4. 安全审计:从入口、权限、数据流逐层追踪。

一次性加载可能更合适的任务:

  1. 短文本改写:原文很短,整体风格一致性重要。
  2. 小型配置审查:几十行配置一次看完整更可靠。
  3. 合同条款对比:材料规模可控,且需要全局一致地检查交叉引用。

现实中最稳的仍是混合模式:先加载任务说明、目录或摘要等高层上下文,再通过渐进式方式获取细节。

11. 本章总结

第 9 章的重点不是新增一个炫技工具,而是建立一种工程习惯:每次调用模型前,都要有意识地决定模型该看到什么、不该看到什么、看到的信息如何分区、超限时如何保留关键状态。

ContextBuilder负责把上下文构建标准化,NoteTool负责把长期状态外部化,TerminalTool负责按需获取即时信息,MemoryTool负责保留会话记忆。它们组合起来,才真正支撑长程 Agent 在复杂任务中保持连贯、聚焦和可恢复。

http://www.jsqmd.com/news/862241/

相关文章:

  • iTorrent完整指南:如何在iPhone上实现专业级种子下载管理
  • Deployment滚动更新与回滚完全指南
  • 技术债的“利息”怎么算?一个让非技术领导也能理解的比喻
  • 如何免费解锁网易云音乐无损音质:5个步骤掌握Netease_url终极工具
  • 远程办公三年,我摸索出一套不被“隐形加班”吞噬的方法
  • 留学生避开算法内卷?2026 欧美大厂极度缺人的无障碍开发蓝海赛道全景拆解
  • 【ElevenLabs新疆话语音落地实战】:20年语音AI专家亲授3大合规适配难点与5步部署清单
  • 简单掌握C++中的函数模板
  • RMAN 全库备份(Full Backup)
  • 如何在Linux系统上安装Realtek RTL8125 2.5GbE网卡驱动:完整配置指南
  • ShareGPT部署完全指南:如何在Vercel上快速搭建自己的分享平台
  • 2026年质量好的亚克力盐浴床高口碑品牌推荐 - 行业平台推荐
  • 2026谷歌I/O炸场:3.5 Flash全面碾压上代旗舰,AI行业彻底变天
  • 如何快速掌握Prism-Samples-Wpf交互性编程:InvokeCommandAction事件驱动开发终极指南
  • 跨国分布式团队协作实录:时区差不是最大障碍,信任才是
  • (二) 1. Q-learning的遗憾界分析-结合置信上界的Q-learning算法
  • 2026 年企业微信社群运营高效工具推荐
  • 机器视觉开发-使用YOLO8预训练模型检测目标
  • Linux的监测程序
  • 如何为 ChocolateyGUI 开发插件:扩展功能与自定义模块指南
  • 从灰蒙蒙到电影级质感:Midjourney 5.2→6.1色彩引擎升级对比实测,4类商业项目调色SOP紧急更新
  • Service与Ingress配置完全指南
  • mPDF实战指南:PHP环境下HTML转PDF的高性能解决方案深度解析
  • Genie入门指南:5分钟快速部署你的第一个大数据作业
  • CANN/asc-devkit C API归约函数文档
  • static-php-cli跨平台构建实战:Linux、macOS、Windows全攻略
  • CANN/pypto topk操作
  • 2026 私域运营很重要!群 SOP+AI 实测领先,私域大师7 大工具横评
  • RTSPtoWebRTC API详解:WebRTC连接建立与媒体传输全流程
  • ThinkPHP-BJYAdmin多模块架构解析:Admin、Api、Home模块分离设计指南