singularity-forge/docs/zh-CN/user-docs/token-optimization.md
ace-pm b29c12d5e5 refactor(native): rename gsd_parser.rs to forge_parser.rs
Final rebrand: rename remaining Rust source file to complete the gsd → forge
transition. All parser references already use forge_parser after earlier commits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:58:21 +02:00

14 KiB
Raw Blame History

Token 优化

引入于 v2.17.0

SF.17 引入了一套协同工作的 token 优化系统,在大多数工作负载下可以在不牺牲输出质量的前提下,将 token 使用降低 40-60%。这套系统由三部分构成:token profilescontext compression基于复杂度的 task 路由

Token Profiles

Token profile 是一个单一偏好项,用来统一协调 model 选择、阶段跳过和上下文压缩级别。在偏好设置中这样配置:

---
version: 1
token_profile: balanced
---

可用的 profile 有三个:

budget:最大节省(降低 40-60%

面向成本敏感型工作流。它会使用更便宜的 models跳过可选阶段并把 dispatch 上下文压缩到最低必要程度。

维度 设置
Planning model Sonnet
Execution model Sonnet
Simple task model Haiku
Completion model Haiku
Subagent model Haiku
Milestone research 跳过
Slice research 跳过
Roadmap reassessment 跳过
Context inline level Minimal:丢弃 decisions、requirements、额外 templates

适合:原型开发、小项目、已充分理解的代码库、强调成本控制的迭代。

balanced:智能默认值(默认)

默认 profile。保留关键阶段跳过那些对大多数项目边际收益不高的阶段并采用标准级别的上下文压缩。

维度 设置
Planning model 用户默认值
Execution model 用户默认值
Simple task model 用户默认值
Completion model 用户默认值
Subagent model Sonnet
Milestone research 执行
Slice research 跳过
Roadmap reassessment 执行
Context inline level Standard:保留关键上下文,丢弃低信号附加内容

适合:大多数项目、日常开发。

quality:完整上下文(不压缩)

所有阶段都会运行。所有上下文产物都会被内联。没有捷径。

维度 设置
所有 models 用户配置的默认值
所有阶段 执行
Context inline level Full:全部内联

适合:复杂架构、需要深度 research 的 greenfield 项目、关键生产环境工作。

Context Compression

每个 token profile 都会映射到一个 inline level,它控制在 dispatch prompt 里预加载多少上下文:

Profile Inline Level 包含内容
budget minimal Task plan、关键历史 summaries截断。不包含 decisions register、requirements、UAT template、secrets manifest。
balanced standard Task plan、历史 summaries、slice plan、roadmap 摘要。不包含部分辅助 templates。
quality full 全部内容:所有 plans、summaries、decisions、requirements、templates 和根文件。

压缩如何工作

Dispatch prompt builder 接受一个 inlineLevel 参数。在不同级别下,特定产物会被按规则裁剪:

Minimal 级别的裁剪:

  • buildExecuteTaskPrompt:丢弃 decisions template并把历史 summaries 截断到只保留最近一个
  • buildPlanMilestonePrompt:丢弃 PROJECT.mdREQUIREMENTS.md、decisions 以及 secrets-manifest 等补充 templates
  • buildCompleteSlicePrompt:丢弃 requirements 和 UAT template 的内联
  • buildCompleteMilestonePrompt:丢弃根级 SF 文件内联
  • buildReassessRoadmapPrompt:丢弃 project、requirements 和 decisions 文件

这些裁剪是累积式的:standard 会丢掉一部分,minimal 会丢掉更多;full 则保留全部上下文(也就是 v2.17 之前的行为)。

覆盖 Inline Level

Inline level 由 token_profile 推导而来。如果你想独立于 profile 控制阶段行为,请使用 phases 偏好设置:

---
version: 1
token_profile: budget
phases:
  skip_research: false    # 覆盖:即使是 budget也执行 research
---

显式设置的 phases 总是优先于 profile 默认值。

基于复杂度的 Task 路由

当启用 dynamic routing 时SF 会根据复杂度对每个 task 做分类,并将其路由到合适的 model tier。简单的文档修复会使用更便宜的模型而复杂的架构工作会获得所需的推理能力。

前提条件: Dynamic routing 需要在偏好设置里显式配置 models。如果没有 modelsrouting 会被跳过,所有 phases 都会使用会话启动时的 model。Token profiles 会自动设置 models

上限行为: 当 dynamic routing 启用时,每个 phase 中配置的 model 充当的是上限而不是固定绑定。Router 可以为更简单的工作降级到更便宜的 model但绝不会超过你配置的 model。

分类如何工作

Tasks 会通过分析 task plan 来分类:

信号 Simple Standard Complex
Step 数量 ≤ 3 4-7 ≥ 8
文件数 ≤ 3 4-7 ≥ 8
描述长度 < 500 chars 500-2000 > 2000 chars
代码块数 ≥ 5
信号词 任意出现

会阻止判定为 simple 的信号词: researchinvestigaterefactormigrateintegratecomplexarchitectredesignsecurityperformanceconcurrentparalleldistributedbackward compatmigrationarchitectureconcurrencycompatibility

空 plan 或格式错误的 plan 会默认归类到 standard(偏保守的选择)。

Unit Type 默认值

非 task 单元也有内置的 tier 分配:

Unit Type 默认 Tier
complete-slicerun-uat Light
research-*plan-*execute-taskcomplete-milestone Standard
replan-slicereassess-roadmap Heavy
hook/* Light

Model 路由

每个 tier 会映射到某类 model 配置:

Tier 对应 Model Phase Key 常见 Model
Light completion Haikubudget/ 用户默认值
Standard execution Sonnet / 用户默认值
Heavy execution Opus / 用户默认值

如果配置了 execution_simplesimple tasks 会优先使用它。budget profile 会自动把该键设为 Haiku。

预算压力

当接近预算上限时,分类器会自动降低 tier

已使用预算 影响
< 50% 不调整
50-75% Standard → Light
75-90% Standard → Light
> 90% 除 Heavy 之外全部 → LightHeavy → Standard

这种逐步降级方式能尽量把最复杂工作的模型质量保留下来,同时随着预算逼近上限逐步降低成本。

自适应学习Routing History

SF 会随着时间推移记录每个 tier 分配的成功 / 失败情况,并据此调整未来的分类。它默认自动生效,并持久化在 .sf/routing-history.json 中。

工作方式

  1. 每个工作单元完成后,系统会把结果(成功 / 失败)记录到对应的 unit type 和 tier 上
  2. 结果会按 pattern 跟踪,例如 execute-taskexecute-task:docs,并维护最近 50 条的滚动窗口
  3. 如果某个 pattern 下某个 tier 的失败率超过 20%,未来相同 pattern 的分类会自动上调一个 tier
  4. 系统也支持更细粒度的 tag pattern例如 execute-task:testexecute-task:frontend

用户反馈

你可以通过 /sf rate 为最近完成的工作单元提交反馈:

/sf rate over    # model 太强了,下次更倾向便宜一点
/sf rate ok      # model 选得合适,不调整
/sf rate under   # model 太弱了,下次更倾向强一点

这些反馈的权重是自动结果的 2 倍。要求 dynamic routing 已启用(最近完成的单元必须带有 tier 数据)。

数据管理

# Routing history 按项目存储
.sf/routing-history.json

# 清空历史以重置自适应学习
# (通过 routing-history 模块 API 完成)

反馈数组最多保留 200 条。每个 pattern 的结果统计使用 50 条滚动窗口,以防陈旧数据长期主导判断。

配置示例

成本优先配置

---
version: 1
token_profile: budget
budget_ceiling: 25.00
models:
  execution_simple: claude-haiku-4-5-20250414
---

使用自定义 Models 的平衡配置

---
version: 1
token_profile: balanced
models:
  planning:
    model: claude-opus-4-6
    fallbacks:
      - openrouter/z-ai/glm-5
  execution: claude-sonnet-4-6
---

面向关键工作的高质量配置

---
version: 1
token_profile: quality
models:
  planning: claude-opus-4-6
  execution: claude-opus-4-6
---

按阶段覆盖

token_profile 会设置默认值,但显式偏好始终优先:

---
version: 1
token_profile: budget
phases:
  skip_research: false       # 覆盖:保留 milestone research
models:
  planning: claude-opus-4-6  # 覆盖:即使是 budget profileplanning 也用 Opus
---

这些机制如何协同

PREFERENCES.md
  └─ token_profile: balanced
       ├─ resolveProfileDefaults() → model 默认值 + phase 跳过默认值
       ├─ resolveInlineLevel() → standard
       │    └─ prompt builders 根据 level 决定纳入哪些上下文
       ├─ classifyUnitComplexity() → 路由到 execution / execution_simple model
       │    ├─ task plan 分析steps、files、signals
       │    ├─ unit type 默认值
       │    ├─ budget pressure 调整
       │    ├─ 从 routing-history.json 做自适应学习
       │    └─ capability scoring当 `capability_routing: true` 时)
       │         └─ 7 维 model profile × task requirement vectors
       └─ context_management
            ├─ observation maskingbefore_provider_request hook
            ├─ tool result truncationtool_result_max_chars
            └─ phase handoff anchors注入 prompt builders

Profile 会在 dispatch pipeline 的起点解析一次,并一路向下流动。每一层上,显式偏好都优先于 profile 默认值。

Observation Masking

引入于 v2.59.0

在自动模式会话中tool results 会不断堆积在会话历史里并占用上下文窗口。Observation masking 会在每次 LLM 调用前,把早于最近 N 个 user turns 的 tool result 内容替换成轻量占位符。这样可以在不增加任何 LLM 开销的前提下减少 token 使用:不需要额外总结调用,也不会带来额外延迟。

Observation masking 在自动模式中默认开启。可通过偏好设置控制:

context_management:
  observation_masking: true     # 默认true设为 false 可关闭)
  observation_mask_turns: 8     # 保留最近 8 个 user turns 内的结果范围1-50
  tool_result_max_chars: 800    # 单个 tool result 超过该长度时进行截断

工作方式

  1. 每次 provider request 之前,before_provider_request hook 会检查 messages 数组
  2. 早于阈值的 tool resultstoolResultbashExecution)会被替换成 [result masked — within summarized history]
  3. 最近的 tool results仍在保留窗口内会完整保留
  4. 所有 assistant 和 user messages 始终保留,只有 tool result 内容会被 masking

它与现有的 compaction 系统配套masking 负责减少两次 compaction 之间的上下文压力,而 compaction 负责在窗口填满时执行完整上下文重置。

Tool Result Truncation

单个 tool result 如果超过 tool_result_max_chars(默认 800会被加上 …[truncated] 标记后截断。这可以防止某一次特别大的工具输出独占上下文窗口。

Phase Handoff Anchors

引入于 v2.59.0

当自动模式在 phases 之间切换research → planning → execution系统会把结构化 JSON anchors 写到 .sf/milestones/<mid>/anchors/<phase>.json。下游 prompt builders 会自动注入这些 anchors让下一阶段继承前一阶段的意图、决策、阻塞点和下一步而不必重新从 artifact 文件里推断。

这能减少上下文漂移,也就是企业级 agent 失败案例中最常见的一类问题agent 在 phase 边界上丢失了之前的决策脉络。

Anchors 会在 research-milestoneresearch-sliceplan-milestoneplan-slice 成功完成后自动写入,不需要任何配置。

Prompt Compression

引入于 v2.29.0

SF 可以在退回到 section-boundary truncation 之前,先做确定性的 prompt compression。这样在上下文超预算时可以保留更多信息。

压缩策略

在偏好设置中配置:

---
version: 1
compression_strategy: compress
---

可用策略有两个:

策略 行为 默认适用对象
truncate 在边界处整段丢弃 sectionv2.29 之前的行为) quality profile
compress 先做启发式文本压缩,如果仍超预算,再截断 budgetbalanced profiles

Compression 会确定性地去掉冗余空白、缩短啰嗦表达、去重重复内容并删除低信息量样板文本,不涉及任何 LLM 调用。

上下文选择

控制文件如何内联进 prompt

---
version: 1
context_selection: smart
---
模式 行为 默认适用对象
full 内联完整文件 balancedquality profiles
smart 对大文件(>3KB使用 TF-IDF 语义分块,只纳入相关部分 budget profile

结构化数据压缩

budgetbalanced 的 inline level 下decisions 和 requirements 会被格式化成更紧凑的表示方式,相比完整 markdown tables 可节省 30-50% tokens。

Summary Distillation

如果某个 slice 有 3 个以上依赖 summary且总量超过 summary 预算SF 会先提取结构化核心数据(providesrequireskey_fileskey_decisions),丢弃冗长 prose 段落,然后才会退回到 section-boundary truncation。

Cache Hit Rate Tracking

指标账本现在会为每个工作单元记录 cacheHitRate(输入 tokens 中来自缓存的比例),并提供 aggregateCacheHitRate() 用于统计整场会话的缓存表现。