循环检测(CycleDetector)
wesgine 的 CycleDetector 是唯一的引擎内终止来源——检测可证明的死循环,不是"跑太久了"。
终止哲学
引擎不因 counter 阈值(轮次/token/时间)主动终止正常运行的任务(INV-TERM-01)。
CycleDetector 检测的是:
- 完全相同的操作
- 完全相同的结果
- 反复出现
工具分类
| 分类 | 说明 | streak 行为 |
|---|---|---|
exploration | 只读工具(read/grep/search) | 高阈值,参数变化 halving |
action | 写入工具(edit/write/exec) | 中阈值,参数变化 halving |
plan | Plan 工具 | 探索预算 + 进度减半 |
分类优先级(四级 fallback)
- 硬编码 map(~20 个内置工具)
ExtraCategories(消费方声明)ToolMeta自动推断(ReadOnly=true→ exploration)- 默认:
categoryAction
阈值配置
CycleDetectConfig{
ExplorationWarnThreshold: 50,
ExplorationTermThreshold: 100,
ActionWarnThreshold: 25,
ActionTermThreshold: 50,
IdenticalCallWarnThreshold: 4,
IdenticalCallTermThreshold: 7,
ToolOverrides: map[string][2]int{
"exec": {30, 60},
"exec:readonly": {50, 100},
"edit": {30, 60},
"write": {30, 60},
"apply_patch": {30, 60},
"plan": {15, 30},
},
}
两阶段终止协议
| 阶段 | 触发 | 行为 |
|---|---|---|
| 自愈 | 首次 CycleTerm | 注入 system 纠正消息 + 重置 counter |
| HITL | 第二次 CycleTerm | 问用户"怎么办",超时 60s 自动终止 |
Progress-Aware 工具
当工具参数变化时 streak 计数 /= 2(halving)。
这区分了:
- 真循环:相同参数、相同结果
- 正常迭代:参数变化的连续编辑
ErrorStreak 伪进展检测
ErrorStreakDetector 检测连续错误——表面上有进展(调用不同工具/不同参数),但每次都失败。
扩展机制
CycleDetectConfig{
ExtraCategories: map[string]wesgine.ToolCategoryHint{
"my_readonly_tool": wesgine.CategoryExploration,
},
ExtraProgressAware: []string{"my_mutation_tool"},
}
与 Plan 的关系
- plan 归类为
categoryExploration - 合法多步更新不触发 action streak
- 应用层不得重复声明 ExtraCategories/progressAwareTools
反模式
| 禁止 | 正确做法 |
|---|---|
| 用 counter 阈值终止正常 Run | CycleDetector 是唯一终止源 |
| Plan 归为 action 类 | exploration 类 |
| 相同参数连续调用不检测 | IdenticalCallTerm 检测 |
| 无限自愈重试 | 两阶段:自愈一次,HITL 一次 |