goose/source-notesupstream ↗
goose · version 1.45.0 · Rust 1.94.1

第 7 章:上下文工程——让有限窗口承载长任务

7.1 是什么:上下文不是一个 Vec,而是一组投影和预算

goose 的有效上下文由 system prompt、project instructions、extension instructions、可用 tools、agent-visible messages、tool resources 和 model config 共同构成。MessageMetadata.agent_visible 决定消息是否进入模型;user_visible 只影响 UI。这个双投影让 goose 可以把大量过程信息留给用户,但不把所有内容都继续塞给模型。

flowchart TB
  Session[Session history] --> Visibility[agent_visible filter]
  Visibility --> Count[token counter / usage ledger]
  Count --> Threshold{usage / context_limit > threshold?}
  Threshold -->|否| Request[正常 Provider request]
  Threshold -->|是| Compact[compact_messages]
  Compact --> Summary[结构化摘要 + continuation]
  Summary --> Request
  Tools[tool/resource instructions] --> Request
  Project[project + source-root hints] --> Request

7.2 源码怎么做:自动压缩的五个动作

判定

check_if_compaction_needed 优先使用 session 的累计 token usage;没有 usage 时用 token counter 估算。context limit 来自 provider get_context_limit,阈值默认 0.8,可由 GOOSE_AUTO_COMPACT_THRESHOLD 覆盖。provider 如果 manages_own_context(),goose 直接跳过这条防线。

摘要输入降噪

do_compact 依次尝试保留 100%、90%、80%、50%、0% 的 tool responses,并从中间向外删除工具结果,以降低“同一串日志反复占窗口”的成本。原始用户意图、技术概念、文件活动、错误修复、当前工作和下一步会被 prompt 要求组织出来。

结构化恢复

StructuredSummary 对模型返回做宽松 JSON 解析:列表里出现数字、对象或字符串都尽量 stringify;解析不到可用 JSON 时保留 raw text,避免摘要失败导致信息全丢。

可见性重写

旧消息全部变成 user-visible 但 agent-invisible;summary 和 continuation 变成 agent-only。非手动 compact 会尽量保留最近一个纯文本 user message,让模型继续回答当前问题;工具 loop 场景会使用不同 continuation 文案。

写回与恢复

Agent 先发出 progress/inline notification,再替换 session conversation,更新 compaction usage 和 retained context tokens,产出 HistoryReplaced。宿主不需要自己猜测历史被替换,直接用这个事件刷新视图。

7.3 工具对的二次压缩

长任务中,tool request/response 往往比自然语言更快膨胀。Agent 会统计本轮新增的工具对,并在 provider 不管理 context 时使用 tool-pair summarization;生成的摘要可以标记为 agent-invisible 的历史辅助信息。这样用户还能看到完整工具输出,模型只保留足够的执行语义。

7.4 为什么这样做:保留“可继续工作”的信息,而不是保留全部文本

上下文压缩的目标不是文档归档,而是让下一次模型调用还能做正确决策。因此摘要 schema 里有 fileserrors_and_fixespending_taskscurrent_worknext_step,这些字段比原始日志更接近 Agent 的决策状态。

潜在的代价也被显式承认:压缩调用本身计费;structured summary 可能丢失模型输出细节;tool response 的中间删除必须与当前任务风险权衡。因此源码保留 raw fallback、记录 usage,并让 provider 可以声明自己管理上下文。

源码定位