齐天大战神
49.73M · 2026-04-09
前几课你学了安全、学习、评估。本课进入 Agent 工程的核心 — 构建高质量 Agent 的工程方法论和控制 LLM 使用成本:
掌握这些知识后,你就具备了设计和优化工业级 Agent 系统的能力。
ECC 的 agent-harness-construction Skill 定义了 Agent 质量的四个约束维度:
Agent 输出质量 = f(Action Space, Observation, Recovery, Context Budget)
Action Space(动作空间)是 Agent 可以使用的工具集合。设计原则:
| 原则 | 说明 | 示例 |
|---|---|---|
| 名称稳定且显式 | 工具名一看就知道干什么 | search_code 而非 tool_3 |
| 输入 Schema 优先 | 用 JSON Schema 定义参数 | 类型检查 + 必填项 |
| 输出形状确定 | 返回结构固定 | { status, data, error } |
| 避免万能工具 | 除非隔离不可能 | 拆分 do_everything 为多个专用工具 |
不是所有工具都应该是同一粒度:
┌─────────────────────────────────────────────┐
│ 工具粒度光谱 │
│ │
│ 微工具(Micro) │
│ ├── 用途:高风险操作 │
│ ├── 示例:deploy、migrate、set_permission │
│ └── 特点:权限小、操作原子、回滚容易 │
│ │
│ 中工具(Medium) │
│ ├── 用途:常见编辑/读取/搜索 │
│ ├── 示例:edit_file、search_code、run_test │
│ └── 特点:频率高、效率和安全平衡 │
│ │
│ 宏工具(Macro) │
│ ├── 用途:来回通信成本是主要瓶颈时 │
│ ├── 示例:batch_edit、full_test_suite │
│ └── 特点:一次做很多,减少轮次 │
│ │
└─────────────────────────────────────────────┘
每个工具的返回值(Observation)应该包含四个字段:
{
"status": "success",
"summary": "Found 3 files matching pattern *.test.js",
"next_actions": [
"Run tests with: node tests/run-all.js",
"Check coverage with: npx c8 node tests/run-all.js"
],
"artifacts": [
"tests/lib/utils.test.js",
"tests/lib/package-manager.test.js",
"tests/hooks/hooks.test.js"
]
}
| 字段 | 作用 | 缺失后果 |
|---|---|---|
status | 告诉 Agent 是否成功 | Agent 不知道要不要重试 |
summary | 一行总结结果 | Agent 需要解析大量原始输出 |
next_actions | 建议下一步操作 | Agent 可能走错方向 |
artifacts | 文件路径/ID | Agent 无法引用具体产物 |
每个错误路径必须包含三个元素:
错误发生
├── root_cause_hint(根因提示)
│ "File not found: tests/foo.test.js — check if path is relative"
│
├── safe_retry_instruction(安全重试指令)
│ "Retry with absolute path: /Users/dev/project/tests/foo.test.js"
│
└── explicit_stop_condition(明确停止条件)
"If file still not found after 2 retries, report error and stop"
没有停止条件的 Agent 会无限重试 — 这是 Agent 工程中最常见的失败模式之一。
| 模式 | 适用场景 | 特点 |
|---|---|---|
| ReAct | 探索性任务,路径不确定 | 灵活,但可能发散 |
| Function-calling | 结构化确定性流程 | 高效,但不灵活 |
| Hybrid(推荐) | 大多数场景 | ReAct 规划 + 类型化工具执行 |
cost-aware-llm-pipeline Skill 提供了控制 LLM API 成本的完整方案。
核心思路:不是所有任务都需要最贵的模型。
# 模型选择逻辑(简化版)
def select_model(text_length, item_count, force_model=None):
if force_model is not None:
return force_model
if text_length >= 10_000 or item_count >= 30:
return "claude-sonnet-4-6" # 复杂任务用 Sonnet
return "claude-haiku-4-5" # 简单任务用 Haiku(3-4x 便宜)
ECC 中的模型选择策略(回顾第 15 课):
| 模型 | 定位 | 典型用途 | 相对成本 |
|---|---|---|---|
| Haiku 4.5 | 轻量快速 | 后台 Agent、代码生成、Instinct 分析 | 1x |
| Sonnet 4.6 | 主力编程 | 主开发任务、编排工作流 | 3-4x |
| Opus 4.5 | 深度推理 | 架构决策、复杂研究 | 15-20x |
遵循 ECC 的不可变原则,成本追踪使用冻结数据类:
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class CostRecord:
model: str
input_tokens: int
output_tokens: int
cost_usd: float
@dataclass(frozen=True, slots=True)
class CostTracker:
budget_limit: float = 1.00
records: tuple[CostRecord, ...] = ()
@property
def total_cost(self) -> float:
return sum(r.cost_usd for r in self.records)
@property
def budget_remaining(self) -> float:
return self.budget_limit - self.total_cost
def add(self, record: CostRecord) -> 'CostTracker':
# 返回新对象,不修改原对象
return CostTracker(
budget_limit=self.budget_limit,
records=self.records + (record,),
)
每次 API 调用:
1. 选择模型(按复杂度)
2. 调用 API
3. 记录成本(创建新 CostRecord)
4. 更新 Tracker(返回新 CostTracker)
5. 检查预算
├── 剩余 > 20% → 继续
├── 剩余 10-20% → 切换到更便宜的模型
└── 剩余 < 10% → 停止,报告预算耗尽
API 调用可能因为网络、速率限制等原因失败。成本感知的 Retry 策略:
| 错误类型 | 重试策略 | 成本考量 |
|---|---|---|
| 429 Rate Limit | 指数退避重试 | 不额外计费 |
| 500 Server Error | 最多重试 2 次 | 可能计费 |
| 超时 | 重试 1 次 | 可能计费 |
| 内容被过滤 | 调整 Prompt 后重试 | 计费 |
| 预算不足 | 降级到更便宜的模型 | 减少计费 |
当多次调用使用相同的 System Prompt 时,利用 Prompt Caching 节省成本:
第 1 次调用:发送完整 System Prompt → 缓存命中 0%
第 2 次调用:System Prompt 已缓存 → 只计费增量部分
↓
对于有大量 Skill 的 System Prompt,缓存可以节省 60-80% 的输入 Token 费用
ECC 中与 AI/Agent 开发相关的 Skill 全景:
| Skill | 聚焦领域 | 关键内容 |
|---|---|---|
claude-api | Claude API 使用 | API 调用模式、消息格式、Token 计算 |
agentic-engineering | Agent 工程方法论 | Agent 设计原则、编排模式 |
ai-first-engineering | AI 优先的开发方式 | 如何让 AI 成为开发流程核心 |
autonomous-loops | 自主循环设计 | 无人监督的 Agent 循环架构 |
agent-introspection-debugging | Agent 调试 | 如何诊断 Agent 行为异常 |
agent-eval | Agent 评估 | Agent-vs-Agent 评估方法 |
agent-payment-x402 | Agent 支付 | AI Agent 的支付协议(x402) |
autonomous-agent-harness | 自主 Agent 框架 | 完整的自主 Agent 构建方案 |
continuous-agent-loop | 持续 Agent 循环 | 长时间运行的 Agent 设计 |
agent-harness-construction | Harness 构建 | Action Space / Observation / Recovery |
cost-aware-llm-pipeline | 成本优化 | 模型路由、预算追踪、Prompt Caching |
当 Agent 在无人监督下自主运行时,必须有质量门(Quality Gate)防止失控:
while (任务未完成) {
执行一轮操作
// 质量门检查
if (轮次 >= 最大轮次) → 停止,报告 "达到最大轮次"
if (成本 >= 预算上限) → 停止,报告 "预算耗尽"
if (连续失败 >= 3) → 停止,报告 "连续失败"
if (输出验证失败) → 回退到上一个检查点
if (安全检查失败) → 立即停止
}
| 门 | 检查内容 | 触发动作 |
|---|---|---|
| 轮次门 | 当前轮次 < 最大轮次 | 超限 → 强制停止 |
| 成本门 | 累计成本 < 预算上限 | 超限 → 停止或降级 |
| 失败门 | 连续失败次数 < 阈值 | 超限 → 停止并报告 |
| 输出门 | 输出通过验证检查 | 失败 → 回退重试 |
| 安全门 | 无危险操作 | 失败 → 立即停止 |
| 漂移门 | 输出与预期方向一致 | 偏移 → 告警或停止 |
没有质量门的自主 Agent:
一个 Agent 被要求"优化代码性能"
→ 它开始重构整个代码库
→ 消耗了 $50 的 API 费用
→ 引入了 12 个新 Bug
→ 没有人发现直到第二天
有质量门的自主 Agent:
同一个 Agent 被要求"优化代码性能"
→ 第 3 轮:成本达到预算 50%,切换到 Haiku
→ 第 5 轮:测试失败,回退到上一个检查点
→ 第 8 轮:达到最大轮次,停止并输出报告
→ 总成本:$2.30,所有测试通过
对于多 Agent 工作流,预算需要提前分配:
总预算:$10.00
│
├── planner Agent: $0.50 (5%) — Haiku,快速规划
├── 主开发 Agent: $5.00 (50%) — Sonnet,核心工作
├── code-reviewer: $1.50 (15%) — Sonnet,审查质量
├── security-reviewer: $1.00 (10%) — Sonnet,安全审查
├── tdd-guide: $1.50 (15%) — Sonnet,测试驱动
└── 预留缓冲: $0.50 (5%) — 应对重试和意外
| Agent | 模型 | 预算 | 已用 | 剩余 | 状态 |
|---|---|---|---|---|---|
| planner | Haiku | $0.50 | $0.12 | $0.38 | 正常 |
| developer | Sonnet | $5.00 | $3.80 | $1.20 | 注意 |
| reviewer | Sonnet | $1.50 | $0.90 | $0.60 | 正常 |
| security | Sonnet | $1.00 | $0.00 | $1.00 | 未启动 |
| tdd | Sonnet | $1.50 | $1.20 | $0.30 | 警告 |
| 合计 | — | $10.00 | $6.02 | $3.98 | — |
为一个"自动化代码迁移 Agent"设计 Action Space:
这是本课最重要的练习。
为一个包含 3 个 Agent 的工作流设计成本预算:
假设总预算 $5.00,每个 Agent 应该分配多少?使用什么模型?预留多少缓冲?
为一个"自主运行的安全扫描 Agent"设计质量门:
阅读 agent-harness-construction Skill,然后对比以下两种 Observation 格式,说明哪种更好以及为什么:
格式 A:
Found 3 files. The files are located in the tests directory.
格式 B:
{"status": "success", "summary": "Found 3 test files", "artifacts": ["tests/a.js", "tests/b.js", "tests/c.js"], "next_actions": ["Run tests: node tests/run-all.js"]}
| 你应该记住的 | 内容 |
|---|---|
| Harness 四维度 | Action Space + Observation + Recovery + Context Budget |
| 工具粒度 | 高风险用微工具、常见操作用中工具、通信瓶颈用宏工具 |
| 成本路由 | 简单任务用 Haiku(便宜 3-4x),复杂任务用 Sonnet |
| 不可变追踪 | 每次 API 调用返回新的 CostTracker,不修改原对象 |
| 质量门 | 每轮必须检查:轮次、成本、失败次数、输出验证、安全 |
第 28 课:跨平台适配与插件机制
Agent 工程是"构建"的能力。下一课我们学习"分发"的能力 — ECC 如何适配 6 种不同的 AI 编程助手,Plugin Manifest 的格式设计,以及安装 Profile 的选择策略。
预习建议:浏览 .claude-plugin/plugin.json 和 .codex-plugin/plugin.json,比较两者的结构差异。