AI-7D-SATS平台的harness engineering设计:让 AI Agent 从“工具堆叠”长成“工程制品”
文章目录
- 一、问题:Agent 到底是什么?
- 二、什么是驾驭工程?
- 三、AI-7D-SATS 的四层驾驭架构
- 四、第一层:Skill — 标准化的原子能力
- 4.1 严格的输入输出契约
- 4.2 BaseSkill 的模板方法模式
- 4.3 自动发现的注册中心
- 五、第二层:Agent — 驾驭体
- 5.1 三种推理策略(Strategy Pattern)
- 5.2 AgentContext — 推理状态容器
- 5.3 ReAct 循环里的决策机制
- 5.4 Plan-and-Execute 的自动重规划
- 六、第三层:Orchestrator — 薄薄的协作层
- 6.1 从 800 行 if/elif 到 100 行路由层
- 6.2 三层降级路径
- 6.3 SkillPipeline:静态链式编排
- 七、第四层:LLM Router — 给 LLM 也加一层 Harness
- 7.1 LLM Router 的解析顺序
- 7.2 FallbackManager 的健康感知
- 7.3 配套的两个支撑系统
- 八、可观测性:每一步都看得见
- 8.1 实时 SSE 事件流
- 8.2 完整 Trace 持久化
- 九、配置驱动:Agent 即数据
- 十、五条设计原则
- 十一、实际效果
- 十二、写在最后
当 AI Agent 系统逐渐复杂,我们需要一套工程化的方法来“驾驭”它。本文以 AI-7D-SATS 智能平台的真实架构为蓝本,讲清楚 Harness Engineering(驾驭工程)如何把零散的能力打磨成可观测、可配置、可演进的工程制品。
一、问题:Agent 到底是什么?
最朴素的实现是把 Agent 写成 Skill 的薄包装。“帮我生成脚本”就调脚本生成 Skill,“帮我分析根因”就调根因分析 Skill。Agent 没有思考能力,只是一个透传层。这种实现看起来“能跑”,但当业务真实复杂起来,就会暴露三个连锁问题:
1. 编排器职责膨胀
一个 800 行的 if/elif 链,所有意图、所有领域知识、所有工具调用全集中在它身上,改一处牵一片。
2. Agent 没有恢复能力
Skill 失败就是任务失败,没有重试、没有降级、没有 replan。
3. 黑盒不可观测
用户只能看到最终结果,过程中的推理、Skill 选择、决策点全在日志里漂着,没法做事后审计、调优和自进化。
这就像把一堆零散的工具随意塞进工具箱——能用,但谈不上工程。我们需要的不是工具的堆砌,而是对工具的驾驭。
二、什么是驾驭工程?
Harness 这个词在英文里有“驾驭、驯服、整合利用”的含义。驾驭工程的核心命题是:
单个能力只是原材料。经过标准化、编排、保护、路由和观测之后,它们才能成为可靠的工程制品。
一套合格的驾驭体系必须同时具备:
| 维度 | 具体含义 |
|---|---|
| 原子能力 | 最小、自治、可独立测试的功能单元 |
| 标准接口 | 让能力之间能正确对接、彼此替换 |
| 编排逻辑 | 按特定推理拓扑把能力组合成更高阶的工作 |
| 保护机制 | 故障隔离,防止局部失败级联放大 |
| 可观测性 | 运行状态实时可见,推理过程完整留痕 |
| 路由策略 | 根据任务特征把请求送到最合适的处理者 |
驾驭工程不是能力的简单集合,而是一个经过精心设计、自身就有结构和智能的独立系统。
三、AI-7D-SATS 的四层驾驭架构
我们把这套思想落地为四层模型,每一层都有自己的契约、状态和保护机制:
- 第一层:Skill— 标准化的原子能力
- 第二层:Agent— 驾驭体(推理引擎 + 状态管理 + 故障恢复)
- 第三层:Orchestrator— 薄薄的协作层
- 第四层:LLM Router— 给 LLM 也加一层 Harness
特别值得提的是第四层——LLM 驾驭层。我们不仅驾驭 Skill,也驾驭 LLM 本身。
四、第一层:Skill — 标准化的原子能力
4.1 严格的输入输出契约
每个 Skill 都通过同一份 Pydantic 契约对外:
classSkillInput(BaseModel):data:dictcontext:dictoptions:dictclassSkillOutput(BaseModel):success:boolerror:str|Nonewarnings:list[str]skill_name:strskill_version:strexecution_time_ms:intconfidence:float=1.0reasoning:str=""result:Any注意confidence和reasoning这两个字段——它们不是装饰,是后续 Agent 决策“要不要继续往下走”的核心依据。一个低置信度的输出会让上层 Agent 选择重试或换条路,这就是驾驭工程里“局部状态指导全局决策”的具体体现。
4.2 BaseSkill 的模板方法模式
所有 Skill 子类只关心一件事:_execute()里写业务逻辑。剩下的边界工作由BaseSkill.execute()统一处理:
asyncdefexecute(self,input:SkillInput)->SkillOutput:start=time.monotonic()err=self.validate_input(input)iferr:returnSkillOutput.fail(error=err)try:output=awaitself._execute(input)exceptExceptionase:output=SkillOutput.fail(error=str(e))output.skill_name=self.name output.execution_time_ms=int((time.monotonic()-start)*1000)returnoutput子类永远不需要操心计时、版本号、异常吞吐——这些一致性是模板方法保证的。标准化不是规范文档,是用代码强约束的边界。
4.3 自动发现的注册中心
SkillRegistry是一个单例,启动时通过pkgutil.iter_modules扫描app/skills/包,把所有BaseSkill子类自动注册:
def_discover_skills(self)-></