WeClaw_69_总结与展望:Harness工程的迭代哲学与被否决的方案
第四季系列文章第 8 篇(总第 69 篇) - 迭代哲学 · 三轮评审 · 被否决方案 · Reasoning Sandwich · 双路径对称 · 未来路线
📚 专栏信息
《从零到一构建跨平台 AI 助手:WeClaw 实战指南》专栏 · 第四季
专栏定位:面向开发者和技术决策者的实战专栏,用真实案例和完整代码带你理解如何构建生产级 AI 应用
本文是第四季的收官之作,回顾整个 Harness Engineering 对齐迭代的历程——从初始评估到 V3 最终方案,总结三轮评审的淬炼过程,深入分析被否决的方案(特别是 Reasoning Sandwich 的降级),提炼工程思考,并展望未来路线。
👨💻 作者与项目
作者简介:翁勇刚 WENG YONGGANG 新概念龙虾-WeClaw 开发团队负责人,一群专注于跨平台 AI 应用的实践者 理念:"再复杂的技术,也能用代码讲清楚"
- 💻 项目地址:https://github.com/wyg5208/weclaw.git
- 🌐 官网地址:https://weclaw.link
- 📝 作者 CSDN:https://blog.csdn.net/yweng18
- ⭐ 欢迎 Star⭐、Fork🍴、贡献代码🤝
📝 摘要
本文结构概览: 回顾 WeClaw Harness Engineering 对齐迭代的完整历程——从 4.3/5.0 的初始评估,到 V1 方案的 6 个 Critical Issues,到 V2 的 3 个阻塞项,再到 V3 的可编码实施。重点分析三轮评审中暴露的深层问题:双路径不对称、流式不可逆性、API 契约假设错误。以 Reasoning Sandwich 的降级为案例,讲解"何时放弃一个设计"的工程判断。最后展望未来路线——从"增强型单 Agent"到"多 Agent 编排 + 确定性约束"的范式演进。
核心问题: 一个方案从"看起来完美"到"可以编码实施",中间需要经历什么?为什么有些设计在文档层面成立,在代码层面却崩溃?
关键成果:
- 提炼了三轮评审中的核心工程教训
- 完整的 7 差距对齐路线图和状态总览
- Reasoning Sandwich 降级的深度反思
- 未来 3-6 个月的技术演进方向
适合读者:关注 AI Agent 工程化的开发者、架构师、技术决策者
阅读时长:约 20 分钟
关键词:迭代哲学、三轮评审、被否决方案、Reasoning Sandwich、双路径对称、未来路线
一、回顾:从 4.3 分到 V3 方案
1.1 评估结论
在系列开篇(#62),我们对 WeClaw 进行了六层 Harness 成熟度评估:
Prompt Layer ████░░ 4.0
Context Layer █████░ 5.0 ← 最强层
Tools Layer ████░░ 4.0
Orchestration Layer █████░ 4.5
Multi-Agent Layer ████░░ 4.0
Safety & Observability█████░ 4.5
综合 Harness 成熟度 ████░░ 4.3 / 5.0
4.3 分——一个不错的起点,但远非终点。7 个差距领域(G1-G7)构成了迭代方向。
1.2 V1 → V2 → V3 的淬炼历程
V1 方案(初始规划)
↓ 三视角评审 → 6 Critical + 6 Warning + 4 Suggestion
V2 方案(修订版)
↓ 代码级深度评审 → 3 阻塞项 + 5 风险项
V3 方案(最终版)→ 可编码实施
每一轮评审都发现了上一轮无法发现的问题。这不是因为前面的评审不够认真,而是因为修复了表层问题后,更深层的问题才会浮出水面。就像一个洋葱:你剥掉外面那层皮,才能看到里面那层。
二、三轮评审的核心发现
2.1 V1 → V2:架构级修正
V1 方案最大的问题是"只考虑了非流式路径"。6 个 Critical Issues 中有 3 个与此相关:
| 编号 | 问题 | 根因 |
|---|---|---|
| C1 | chat_stream 全面遗漏 | 方案只描述了 _chat_impl 的注入点 |
| C2 | Checklist continue 时序错误 | 没有考虑 add_assistant_message 的执行顺序 |
| C5 | Reasoning Sandwich 不可行 | 没有考虑 reasoning 模型不支持 function calling |
V2 修复:确立了"双路径对称覆盖"原则——所有 Hook 注入必须同时覆盖 _chat_impl(非流式)和 chat_stream(流式)两条 ReAct 路径。
2.2 V2 → V3:代码级验证
V2 方案在文档层面看起来完美,但代码级评审发现了"文档说有、代码说没有"的问题:
| 编号 | 问题 | 发现方式 |
|---|---|---|
| B1 | ExecutionTracker.get_recent_calls() 不存在 | 读 agent.py L77-178,发现只有字段,无方法 |
| B2 | chat_stream 缺少 _validate_tool_relevance | 读 L2488-2530,发现流式路径遗漏此校验 |
| B3 | Reasoning Sandwich has_tool_calls=False 逻辑矛盾 | 分析模型调用时序,发现无法在调用前预知结果 |
B1 的教训:方案中写 self._execution_tracker.get_recent_calls(3),看起来合理。但如果去读代码,这个方法根本不存在——recent_success_calls 是一个字段,没有公开的访问方法。文档层面的合理性 ≠ 代码层面的可行性。
B2 的教训:这是一个潜伏的现有系统 Bug——非流式路径有 _validate_tool_relevance 校验,流式路径没有。这意味着流式模式下模型可以调用任何工具而不被拦截。新功能注入前,先修复现有路径的不对称。
B3 的教训:Reasoning Sandwich 希望在"最终回复阶段"切换到 reasoning 模型。但"最终回复"的标志是 has_tool_calls = False——这个值在模型调用返回后才知道。你无法在调用前就知道返回不会有工具调用。时序矛盾是最难发现的设计缺陷——它在逻辑上自洽,但在时序上不可能。
2.3 5 个实施风险项
| 编号 | 风险 | V3 修复 |
|---|---|---|
| R1 | 流式 Checklist 用 continue 导致 UX 混乱 | 改为后置告知模式 |
| R2 | 依赖注入入口是 gui_app.py 而非 assistant.py | 修正引用 |
| R3 | EventBus 不支持子实例 | 为角色 Agent 创建独立 EventBus() 实例 |
| R4 | AgentPool 向后兼容风险 | GENERAL 角色不传额外参数 |
| R5 | default.toml 有编码乱码区域 | 配置添加在 [agent.trace] 之后 |
三、流式不可逆性 —— 最重要的工程发现
3.1 问题的本质
WeClaw 的流式路径通过 yield delta_content 实时将文本发送给用户。这意味着:
模型生成 "好的,我已经完成了修改。"
→ yield "好的," → 用户看到了 ✅
→ yield "我已经完成了" → 用户看到了 ✅
→ yield "修改。" → 用户看到了 ✅
→ 此时检查 Checklist → 发现问题!
→ 但文本已经全部发给用户了,无法回收 ❌
这就像脱口而出了一句话——说出去的话泼出去的水,你只能补充,不能撤回。
3.2 影响范围
这个发现影响了两个关键设计决策:
CompletionChecklist 的流式策略(#67):
- 非流式路径:文本未发送,可以
continue重入循环 → 静默修正 - 流式路径:文本已发送,只能
yield追加告知提示 → 后置告知
Reasoning Sandwich 的降级(见第四节):
- 原计划在"最终回复阶段"切换到 reasoning 模型
- 但流式路径下,"最终回复"的文本已经在逐步 yield
- 无法在 yield 开始前切换模型
3.3 通用工程教训
流式架构的不可逆性是一个通用约束——不仅影响 WeClaw,也影响所有使用流式 LLM API 的应用:
| 操作 | 流式下可行性 | 替代方案 |
|---|---|---|
| 拦截并重入 | ❌ 文本已 yield | 后置告知 |
| 撤回已发送文本 | ❌ 单向流 | 不可能 |
| 切换模型(中途) | ❌ 已开始生成 | 在下一步切换 |
| 追加提示 | ✅ 新的 yield | 后置告知模式 |
四、被否决的方案 —— Reasoning Sandwich 降级全记录
4.1 原始设想
在 ReAct 循环中,不同阶段使用不同"推理强度"的模型:
Step 1-5(规划阶段) → DeepSeek-Reasoner(高推理,深度思考)
Step 6-20(执行阶段) → DeepSeek-V3(中推理,快速执行)
Step 21-25(验证阶段)→ DeepSeek-Reasoner(高推理,严格审查)
"三明治"模型:强-弱-强,规划和验证用强推理,执行用普通推理。
4.2 第一轮评审(V1→V2)发现的问题
问题1:reasoning 模型不支持 function calling
DeepSeek-Reasoner 是一个"推理专用"模型——它可以生成深思熟虑的文本,但不能调用工具。这意味着它无法在"规划阶段"调用工具(因为规划也需要调用搜索工具等)。
V2 的修复:将 Reasoning Sandwich 限制在"最终回复阶段"——此时 Agent 已经完成了所有工具调用,只需要生成最终文本回复。
4.3 第二轮评审(V2→V3)发现的矛盾
问题2:时序矛盾
即使限制在"最终回复阶段",仍然有时序问题:
# ReAct 循环中的关键代码(简化)
response = await self.model_registry.call_model(messages, tools=tools)
# 调用完成后,才知道 response 是否有 tool_calls
has_tool_calls = len(response.tool_calls) > 0
# 如果 has_tool_calls = False → 这是最终回复
# 但模型切换需要在 call_model 之前决定!
# → 你不知道这次调用会不会有 tool_calls
这是一个因果倒置:你无法在调用前预知调用结果。
4.4 降级决策
V3 将 Reasoning Sandwich 降级为实验性骨架:
class ReasoningScheduler:
"""阶段感知模型选择器(实验性)。
设计约束:
- Reasoning 模型不支持 function calling,仅用于纯文本生成
- 仅在 CompletionChecklist 触发的额外步骤中生效
(此时明确无工具调用,是 checklist 重入步骤)
"""
def should_switch(self, is_checklist_retry: bool, step_idx: int) -> str | None:
"""仅当明确为 Checklist 重入步骤时,才返回 reasoning model_key。"""
if not is_checklist_retry:
return None
if self._verification_model:
return self._verification_model
return None
关键设计:is_checklist_retry = True 是一个已知的确定性信号——当 Checklist 拦截并重入循环时,这一步明确是"自检修正步骤",不需要工具调用。此时可以安全切换到 reasoning 模型。
4.5 联合启用条件
V3 为 Reasoning Sandwich 设定了严格的启用条件(非本方案范围):
- CompletionChecklist 已稳定运行 2 周无误报
- 在
_chat_impl的 Checklistcontinue分支内添加模型切换逻辑 - 调用时不传 tools 参数(确保 reasoning 模型不需要 function calling)
4.6 教训总结
| 教训 | 说明 |
|---|---|
| 文档 ≠ 实现 | 方案文档上完美的设计,可能在代码层面有根本性矛盾 |
| 时序矛盾最隐蔽 | 逻辑自洽不代表时序可行——"先有鸡还是先有蛋"在工程中也存在 |
| 降级 ≠ 失败 | 将设计降级为骨架不是失败,而是更诚实的工程判断 |
| 确定性信号最可靠 | 不确定的信号(如 has_tool_calls)不如确定性信号(如 is_checklist_retry) |
五、其他被否决的方案
5.1 否决清单
| 方案 | 为什么否决 | 我们选择了什么 |
|---|---|---|
重构 _chat_impl 为 Pipeline | 侵入性太高,agent.py 3296行运行稳定 | Hook 注入(侵入性最小) |
| LangGraph/AutoGen 替换编排 | 外部依赖,与 EventBus/AgentPool 架构不兼容 | 自建 RoleOrchestrator |
| ToolRegistry 层面做角色限制 | 影响所有 Agent 实例,无法会话级隔离 | AgentPool 层面过滤 |
| 独立进程实现熵管理 | 过度设计,asyncio.Task 已足够 | 后台 Task |
| Checklist 用 LLM 判断 | token 成本高,延迟不可控 | 纯规则检查 |
| 流式 Checklist 用 continue 重入 | 文本已 yield 给用户,continue 导致重复 | 后置告知模式 |
5.2 否决方案的共同特征
被否决的方案都有一个共同特征:它们看起来更"优雅"或更"强大",但实际风险不可控。
- Pipeline 重构更优雅——但回归风险大
- LangGraph 更强大——但与现有架构不兼容
- LLM Checklist 更智能——但成本和延迟不可控
我们的选择标准是:风险可控 > 架构优雅 > 功能强大。
六、7 差距对齐状态总览
6.1 路线图
M0(Day 1-2): 前置基础设施修复
→ Task 0.1: ExecutionTracker.get_recent_calls()(3行) ✅ 可立即实施
→ Task 0.2: chat_stream 补全 _validate_tool_relevance(10行)✅ 可立即实施
M1(Week 1-2): 确定性约束 + Pre-completion Checklist
→ Task 1: ConstraintEngine(~200行) ✅ 依赖 M0
→ Task 2: CompletionChecklist(~200行) ✅ 无依赖,可与 Task 1 并行
M2(Week 3-4): Loop Detection + 熵管理
→ Task 3: LoopDetector(~180行) ✅ 无依赖
→ Task 4: EntropyManager(~250行) ✅ 无依赖
M3(Week 5-7): 角色化多 Agent + 自适应 Harness
→ Task 5: RoleOrchestrator(~300行)+ AgentRoles(~150行)+ TokenBudget(~150行)
→ Task 6: AdaptiveHarness(~250行) ⏳ 需 TaskTrace 数据积累 1-2 周
M4(Week 8): Reasoning Sandwich 骨架
→ Task 7: ReasoningScheduler(~150行) ⏳ 实验性,仅骨架不注入
6.2 代码量汇总
| 里程碑 | 新模块 | 新增行数 | agent.py 改动 |
|---|---|---|---|
| M0 | - | - | 13行 |
| M1 | 2 | ~400 | ~28行 |
| M2 | 2 | ~430 | ~10行 |
| M3 | 4 | ~850 | ~10行 |
| M4 | 1 | ~150 | 不注入 |
| 合计 | 9 | ~1830 | ~61行 |
6.3 配置汇总
# config/default.toml — 新增 7 个配置节
[agent.constraint_engine] # G1
enabled = false
[agent.completion_checklist] # G5
enabled = false
[agent.loop_detection] # G6
enabled = false
[agent.entropy_manager] # G3
enabled = false
[agent.roles] # G2
enabled = false
[agent.adaptive_harness] # G4
enabled = false
[agent.reasoning_sandwich] # G7(实验性)
enabled = false
所有功能默认关闭——逐项开启,灰度上线。
七、提炼:六个工程原则
从整个迭代过程中,我们提炼出六个可复用的工程原则:
原则1:双路径对称覆盖
如果系统有两条执行路径(如流式/非流式),所有新功能必须同时覆盖两条路径。
验证方法:每次新增 Hook 注入点时,在两条路径的代码中搜索同一方法名。
原则2:代码级验证优先
方案文档的合理性不等于代码层面的可行性。每个设计决策都必须对照源码验证。
验证方法:对每个方案中的代码引用,实际读取对应源文件确认方法/字段/签名存在。
原则3:Hook 注入优于架构重构
在稳定系统中新增功能时,侵入性最小的方案优先于最优雅的方案。
验证方法:评估方案时,将"改动范围"和"回归风险"作为一级评估维度。
原则4:流式不可逆性
流式输出的内容不可回收。所有在"最终回复前"的拦截逻辑,在流式路径上需要替代方案。
验证方法:每个在 _chat_impl 中使用 continue 的逻辑,检查 chat_stream 中是否可行。
原则5:降级优于崩溃
当设计存在根本性矛盾时,降级为骨架或实验性功能,比强行实施更好。
验证方法:每个新功能都有明确的"启用条件"和"降级策略"。
原则6:配置驱动灰度
所有新功能默认关闭,逐项开启。每个功能有独立的配置节。
验证方法:检查每个新功能的配置项是否有 enabled = false 默认值。
八、未来路线
8.1 短期(1-3 个月)
M0-M2 实施:完成前置修复、确定性约束、Checklist、Loop Detection、熵管理。
- 预期收益:Agent 执行可靠性提升 30-50%
- 验证指标:循环检测命中率、Checklist 触发率、约束引擎拦截率
8.2 中期(3-6 个月)
M3 实施:角色化多 Agent + 自适应 Harness。
- 预期收益:复杂任务成功率提升 40-60%
- 验证指标:角色化任务的 token 消耗 vs 单 Agent、任务完成率
Reasoning Sandwich 联合启用:在 Checklist 稳定后,尝试在自检步骤中使用 reasoning 模型。
- 前提:Checklist 误报率 <10%
8.3 长期(6-12 个月)
Harness-Bench 对标:在 Harness-Bench 的五大失败模式上,将 WeClaw 的防护覆盖率从平均 3.8 星提升到 4.5 星以上。
社区反馈循环:收集使用 WeClaw 的开发者反馈,持续优化自适应 Harness 的模式挖掘算法。
学术发表:将 WeClaw 的 Harness 工程实践整理为案例研究论文——"From Prompt Engineering to Harness Engineering: An Iterative Approach to Agent System Alignment"。
8.4 成熟度目标
当前状态(4.3/5.0) 目标状态(4.8/5.0)
Prompt Layer 4.0 → 4.5(+自适应 Prompt)
Context Layer 5.0 → 5.0(维持领先)
Tools Layer 4.0 → 4.5(+ConstraintEngine)
Orchestration Layer 4.5 → 5.0(+Checklist + LoopDetection)
Multi-Agent Layer 4.0 → 5.0(+RoleOrchestrator)
Safety & Observability 4.5 → 5.0(+EntropyManager)
综合成熟度 4.3 → 4.8
九、给同行的建议
如果你也在构建 Agent 系统并考虑 Harness Engineering 对齐,以下是我们的建议:
9.1 先评估,再规划,后实施
不要跳过评估直接做方案。WeClaw 的评估发现了 7 个差距——如果你不做评估,可能只关注了 2-3 个,遗漏了关键的差距。
9.2 多轮评审,逐层深入
第一轮评审关注架构("方向对不对"),第二轮评审关注代码("实现可不可行"),第三轮评审关注细节("边界情况有没有处理")。
9.3 尊重流式架构的约束
如果你的系统有流式输出,记住:流式是不可逆的。所有在"最终回复前"的拦截逻辑都需要流式路径的替代方案。
9.4 降级不是失败
将功能降级为"实验性骨架"是一种成熟的工程判断。它意味着你承认了当前设计的局限性,同时保留了未来改进的空间。
9.5 配置驱动灰度
永远不要一次开启所有新功能。每个功能有独立的 enabled = false 配置,逐项开启,观察效果,再决定下一个。
十、系列总结
第四季共 8 篇文章,覆盖了 WeClaw Harness Engineering 对齐的完整旅程:
| 编号 | 主题 | 核心贡献 |
|---|---|---|
| #62 | 总体技术分析 | 六层模型评估框架 + 7 差距识别 |
| #63 | 确定性约束引擎 | ConstraintEngine 设计 + 三层校验链 |
| #64 | 角色化多 Agent 协作 | RoleOrchestrator + EventBus 隔离 + Token 预算 |
| #65 | 熵管理 | EntropyManager + 四类清理任务 + 空闲调度 |
| #66 | 自适应 Harness | AdaptiveHarness + 模式挖掘 + 安全边界 |
| #67 | Pre-completion Checklist | 双路径差异策略 + 流式不可逆性 |
| #68 | Loop Detection | 三级检测 + 渐进响应 + 锚定消息注入 |
| #69(本文) | 总结与展望 | 迭代哲学 + 被否决方案 + 未来路线 |
核心信息:
Agent = Model + Harness。 当所有人都在追逐更强的模型时,真正决定 Agent 表现的,是它运行的"线束"架构。Harness Engineering 不是一次性工程,而是一个持续迭代的过程——从评估到规划,从实施到评审,从 V1 到 V3,每一步都在收敛到更好的方案。
感谢阅读第四季系列。如果你在实践中也遇到了 Harness 工程相关的挑战,欢迎在 GitHub 上讨论。
📖 相关文章
第四季全系列:
- WeClaw_62_Harness工程全景:六层模型评估与WeClaw 4.3分成熟度诊断
- WeClaw_63_确定性约束引擎:从Prompt引导到代码级强制的范式转变
- WeClaw_64_角色化多Agent协作:从并行隔离到Explorer_Planner_Coder_Reviewer分工编排
- WeClaw_65_熵管理:AI系统的垃圾回收机制
- WeClaw_66_自适应Harness:让系统从历史成功模式中学习
- WeClaw_67_Pre-completion_Checklist:AI的交付前自检清单
- WeClaw_68_Loop_Detection:检测和中断Agent的死亡循环
前三季精选:
本文是 WeClaw 专栏第四季的收官之作(总第 69 篇)。如果这个系列对你有帮助,欢迎给项目点个 Star ⭐