AI AutoDev Team --- 产品需求文档 (PRD) v2.1
哲学 : 不下发剧本,只下发任务。不硬编码流程,只定义边界。不预设角色,只约束行为。 版本 : v2.1 日期 : 2026-05-09 状态 : 增量修订(基于 v2.0 评估反馈) 修订内容: 新增 Phase 0、执行环境规范、LLM 调用策略、任务复杂度分类器、错误分类规范;简化 Stigmergy;修正 Phase 1 交付物;补充验证类型;调整价值主张
1. 产品哲学:从"编排"到"蜂群"
1.1 核心理念
旧思维(已抛弃):
- ❌ 预定义 5 个角色(PO/TL/Dev/QA/Ops),每个有固定剧本
- ❌ 固定状态机(需求→设计→开发→测试→部署)
- ❌ Agent 像提线木偶,只能做编排者预设的动作
蜂群思维:
- ✅ 只下发目标:"实现用户注册模块,含邮箱验证"
- ✅ 只规定边界:"用 TypeScript + Next.js,测试覆盖≥80%,不碰生产数据库"
- ✅ 只约束输出:"交付可运行的代码 + 测试 + 文档"
- ✅ 蜂群并行攻击:不是 1 个 Agent 串行,而是 N 个 Agent 同时从多角度拆解、搜索、编码、验证
- ✅ 去中心化涌现:没有总指挥,Agent 根据局部信息自主决策,群体涌现最优解
1.2 蜂群 vs 单兵:效率对比(v2.1 修订)
| 单 Agent | 蜂群 (Swarm) | 提速比 | |
|---|---|---|---|
| 信息收集 | 1 人搜索 10 个链接 | 3 人同时搜索不同关键词 | 1.5-2x |
| 技术选型 | 1 人对比 5 个库,纠结 20 分钟 | 3 人各自深入 1 个库,交叉验证 | 2-3x |
| 代码实现 | 1 人串行写多文件 | 3 人同时写不同模块 | 1.5-2x |
| Bug 修复 | 1 人反复试错 | 2 人双路排查,取先成功 | 1.5-2.5x |
| 验证 | 1 人跑测试,失败再修 | 1 人跑测试,1 人同步写边界测试 | 1.2-1.5x |
关键洞察 :蜂群提速是有条件的------任务需要可并行化 且足够复杂 。简单任务(解析 CSV、单文件修改)蜂群开销大于收益。蜂群适合技术选型调研 和复杂 Bug 排查,不适合简单重复任务。
1.3 系统定义
AI AutoDev Team (AAT) v2 + Swarm 是一个自组织蜂群软件开发系统:
- 人类输入:任务描述 + 边界约束 + 验收标准
- 系统输出:可运行的代码产物 + 执行日志 + 验证报告
- 过程黑盒:一群 Agent 像蜂群一样围绕任务并行工作、局部通信、涌现结果
2. 系统总览:极简输入 → 蜂群并行 → 可验证输出
2.1 架构极简图
bash
┌─────────────────────────────────────────────────────────────────┐
│ HUMAN INPUT │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ "实现一个支持邮箱验证码的用户注册模块" │ │
│ │ 约束: {tech: "Next.js+Prisma", cost_limit: "$5", ...} │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MISSION DECOMPOSITION │
│ AI 蜂群同时多角度拆解: │
│ Agent-A: "拆成前端+后端+数据库" │
│ Agent-B: "拆成 API+UI+验证+测试" │
│ Agent-C: "拆成安全+性能+功能" │
│ → 汇总取并集,生成最优任务树 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SWARM EXECUTION │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Agent-1 │ │Agent-2 │ │Agent-3 │ │Agent-N │ │
│ │搜索Resend│ │搜索SendGrid│ │搜索AWS SES│ │写Schema │ │
│ │并发调研 │ │并发调研 │ │并发调研 │ │并发编码 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴────────────┴────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ Swarm Mesh │ ← 局部通信、结果汇聚 │
│ │ (去中心化) │ │
│ └──────┬──────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Agent-X │ │Agent-Y │ │Agent-Z │ │
│ │集成邮箱 │ │写API │ │写前端 │ │
│ │服务 │ │端点 │ │页面 │ │
│ │(用最优) │ │(等Schema)│ │(等API) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ TOOL MESH (工具自治层) │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ VERIFICATION LAYER │
│ 每个子任务必须有可验证的交付物,不通过 → 蜂群自动修复 │
│ [API测试通过✓] [Schema验证✓] [覆盖率82%✓] [E2E通过✓] │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ HUMAN OUTPUT │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ ✅ 代码仓库 (Git 分支) │ │
│ │ ✅ 测试报告 (自动运行结果) │ │
│ │ ✅ ADR: 蜂群共识选 Resend (3人调研交叉验证) │ │
│ │ ✅ 成本报告 ($3.2 / $5.0, 蜂群并行节省 60% 时间) │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
2.2 唯一硬编码的东西
| 层级 | 硬编码内容 | 理由 |
|---|---|---|
| 输入协议 | 任务描述格式 + 约束 Schema | 人类和系统必须能对话 |
| 验证框架 | 什么是"通过"的客观标准 | 避免AI自我欺骗 |
| 安全边界 | 不能删的文件、不能调的API、预算上限 | 防止破坏 |
| 工具网关 | MCP/Skill 的标准调用协议 | 统一接口 |
除此之外,一切自治。
3. 任务系统:Mission → Verification Tree
3.1 任务分解引擎(自主拆解)
python
class MissionDecomposer:
"""
把人类的大需求,拆解成可验证的子任务树。
不依赖预设模板,完全由 AI 根据任务语义自主拆解。
"""
async def decompose(self, mission: Mission) -> TaskTree:
"""
输入: "实现用户注册模块,含邮箱验证"
输出(示例,实际由 AI 自主决定):
TaskTree {
root: "实现用户注册模块",
children: [
Task {
id: "T1",
description: "设计数据库用户表 Schema",
deliverable: "prisma/schema.prisma 中含 User 模型",
verification: "prisma validate 通过",
dependencies: [],
estimated_cost: "$0.3"
},
Task {
id: "T2",
description: "实现 /api/auth/register 端点",
deliverable: "app/api/auth/register/route.ts",
verification: "curl 请求返回 200,数据库有记录",
dependencies: ["T1"],
estimated_cost: "$0.5"
},
Task {
id: "T3",
description: "集成邮箱验证码服务",
deliverable: "可发送验证码邮件",
verification: "测试邮箱收到邮件,验证码可验证",
dependencies: [],
# AI 自主决定: 搜索对比 SendGrid/Resend/AWS SES,选性价比最高的
tool_search_hint: "email verification service"
},
Task {
id: "T4",
description: "前端注册页面",
deliverable: "app/register/page.tsx",
verification: "Playwright 测试通过",
dependencies: ["T2", "T3"]
},
Task {
id: "T5",
description: "单元测试 + 集成测试",
deliverable: "测试文件 + coverage 报告",
verification: "npm test 通过 && coverage≥80%",
dependencies: ["T2", "T3", "T4"]
}
]
}
"""
# 让 LLM 自主思考如何拆解,只约束输出格式
prompt = f"""
你是一个经验丰富的技术负责人。
任务: {mission.description}
约束: {json.dumps(mission.constraints)}
验收标准: {json.dumps(mission.acceptance_criteria)}
请把任务拆解为可独立执行的子任务树。
每个子任务必须包含:
1. 具体做什么(一句话)
2. 交付物是什么(文件路径或运行结果)
3. 怎么验证通过(可执行的具体命令或检查)
4. 依赖哪些前置任务
不要套用模板,根据任务实际性质决定粒度。
有的任务需要拆很细(如复杂算法),有的可以很粗(如简单配置)。
"""
return await llm.generate_structured(prompt, schema=TaskTree)
3.2 子任务必须可验证
python
@dataclass
class Task:
id: str
description: str
# === 交付物定义(必须具体)===
deliverable: str # "app/api/auth/register/route.ts 文件存在且可运行"
# === 验证器(必须可自动执行)===
verification: VerificationSpec
# === 依赖(其他子任务)===
dependencies: List[str] = field(default_factory=list)
# === 资源预估(AI 自主估算)===
estimated_cost: Optional[str] = None # "$0.5"
estimated_time: Optional[int] = None # 分钟
@dataclass
class VerificationSpec:
"""
验证必须客观、自动、无歧义。
"""
type: str # "file_exists", "command_exit_0", "coverage_threshold", "curl_200", "e2e_pass"
command: Optional[str] # "npm test -- --coverage"
expected: str # "coverage: 80%"
timeout_seconds: int = 120
验证示例:
| 子任务 | 验证方式 |
|---|---|
| "创建数据库表" | prisma migrate dev 执行成功,且 prisma db pull 能看到新表 |
| "API 可用" | curl -X POST http://localhost:3000/api/register 返回 {"success": true} |
| "测试覆盖" | npx jest --coverage --coverageReporters=text-summary 输出含 Lines: 82% |
| "前端可访问" | npx playwright test tests/register.spec.ts 退出码 0 |
| "文档完整" | grep -c "## API Reference" docs/README.md ≥ 1 |
5. 蜂群协调层:Swarm Coordination
5.1 蜂群核心机制
蜂群不是"多线程 Agent",而是去中心化、自组织、涌现式的群体智能系统。
机制 1: 去中心化任务队列 (Decentralized Task Queue)
没有中央调度器分配任务。Agent 自己"嗅探"任务、自主认领。
python
class DecentralizedTaskBoard:
"""
蜂群任务板------像蜜蜂发现蜜源后跳八字舞通知同伴
"""
def __init__(self):
# 任务板是共享的,但没有"分配者"
self.tasks = {} # task_id -> Task
self.claims = {} # task_id -> agent_id (谁先抢到谁做)
self.progress = {} # task_id -> 0.0-1.0
async def post_task(self, task: Task):
"""任务发布到板上(由 Decomposer 或 Agent 产生)"""
self.tasks[task.id] = task
# 发布事件,所有 Agent 都能感知
await self.emit(TaskPostedEvent(task))
async def claim_task(self, agent: Agent, task_id: str) -> bool:
"""Agent 自主认领任务"""
if task_id in self.claims:
return False # 已被认领
# Agent 自己判断:我能做这个任务吗?
task = self.tasks[task_id]
confidence = await agent.assess_capability(task)
if confidence < 0.5:
return False # Agent 自认能力不足,不抢
self.claims[task_id] = agent.id
agent.current_task = task
return True
async def abandoned_task(self, agent: Agent, task_id: str, reason: str):
"""Agent 放弃任务(如遇到困难),其他人可以重新认领"""
if self.claims.get(task_id) == agent.id:
del self.claims[task_id]
# 广播:这个任务又空了,谁能做?
await self.emit(TaskAbandonedEvent(task_id, reason))
机制 2: 冗余并行 (Redundant Parallelism)
同一任务多个 Agent 同时尝试,取最优结果。
python
class RedundantExecution:
"""
关键任务同时派 N 个 Agent 做,取最快/最好的结果
"""
async def execute_with_redundancy(self, task: Task, n: int = 2) -> TaskResult:
"""
同时启动 2-3 个 Agent 做同一个任务
"""
# 启动 N 个 Agent
agents = [self.spawn_agent() for _ in range(n)]
# 同时执行
futures = [agent.execute(task) for agent in agents]
# 谁先完成就先验证
done, pending = await asyncio.wait(
futures,
return_when=asyncio.FIRST_COMPLETED
)
# 先完成的先验证
for future in done:
result = await future
if await self.verify(result, task):
# 成功!取消其他 Agent
for p in pending:
p.cancel()
return result
# 第一个验证失败,等第二个
if pending:
done2, _ = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
for future in done2:
result = await future
if await self.verify(result, task):
return result
# 全部失败,合并错误信息交给蜂群诊断
errors = [f.exception() for f in futures if f.exception()]
return await self.swarm_diagnose(task, errors)
适用场景:
| 任务类型 | 并行度 | 理由 |
|---|---|---|
| 技术选型调研 | 3 | 不同 Agent 各深入 1 个方案,交叉验证 |
| Bug 修复 | 2 | 同时尝试不同修复策略 |
| 架构设计 | 2 | 同时产出 2 个方案,对比取优 |
| 单元测试 | 1 | 确定性高,无需冗余 |
| 复杂算法实现 | 2 | 不同实现思路,跑 benchmark 选优 |
机制 3: 局部通信 (Local Communication)
Agent 不和所有人通信,只和"邻居"通信(减少信息噪音)。
python
class LocalCommunicationMesh:
"""
Agent 只和相关的 Agent 通信,不是全连接广播
"""
def get_neighbors(self, agent: Agent, context: SwarmContext) -> List[Agent]:
"""
邻居定义(动态变化):
1. 做同一个父任务的 Agent
2. 当前任务的上下游依赖 Agent
3. 使用相同技术栈的 Agent(可以分享工具使用经验)
"""
neighbors = set()
# 同任务组的 Agent
if agent.current_task:
neighbors.update(
a for a in context.agents
if a.current_task and a.current_task.parent_id == agent.current_task.parent_id
)
# 依赖关系的 Agent
for dep_id in agent.current_task.dependencies:
dep_agent = context.find_agent_by_task(dep_id)
if dep_agent:
neighbors.add(dep_agent)
return list(neighbors)
async def whisper(self, from_agent: Agent, message: SwarmMessage):
"""向邻居发送信息"""
neighbors = self.get_neighbors(from_agent, self.context)
for neighbor in neighbors:
await neighbor.inbox.put(message)
# 如果信息特别重要(如发现了一个好用的工具),标记为"强烈推荐"
if message.priority == "discovery":
# 邻居可能会继续传播给它的邻居(信息扩散)
await self._gossip(neighbor, message, ttl=3)
机制 4: 痕迹标记 (Stigmergy) --- 简化版
v2.1 变更:移除痕迹衰减机制,改为简单 key-value 记录。衰减机制复杂度高但实际价值有限。
像蚂蚁用信息素标记路径,Agent 用"数字痕迹"标记环境。
python
class StigmergyEnvironment:
"""
数字痕迹系统------Agent 在环境中留下标记,影响其他 Agent 的行为。
简化版:简单的 key-value 存储,无衰减。
"""
def __init__(self):
self.trails = {} # location -> StigmergyMark
async def mark(self, agent: Agent, location: str, mark_type: str, content: str):
"""Agent 在环境中留下痕迹"""
self.trails[location] = {
"agent_id": agent.id,
"location": location,
"type": mark_type, # "good_path" / "bad_path" / "tip"
"content": content,
"timestamp": datetime.utcnow().isoformat(),
}
async def sniff(self, location: str) -> Optional[dict]:
"""Agent 感知环境中的痕迹"""
return self.trails.get(location)
async def list_all(self, mark_type: str = None) -> List[dict]:
"""获取所有痕迹,可按类型过滤"""
if mark_type:
return [t for t in self.trails.values() if t["type"] == mark_type]
return list(self.trails.values())
简化原因:
- 痕迹衰减(0.9^hour)在实践中价值有限,任务重复率低
- 简单 key-value 更易实现和维护
- 如果后续发现简单版本不够用,可以再增加衰减机制
痕迹类型:
| 痕迹类型 | 含义 | Agent 行为影响 |
|---|---|---|
good_path |
"这条路走得通" | 倾向于跟随 |
bad_path |
"这里有大坑" | 避开 |
tip |
"用 X 工具效率翻倍" | 优先尝试 |
场景示例:
- Agent-1 尝试 SendGrid 失败,留下
bad_path(SendGrid 配置复杂) - Agent-2 嗅到痕迹,改试 Resend 成功,留下
tip(Resend 只需一行代码) - Agent-3 直接选 Resend
机制 5: 涌现共识 (Emergent Consensus)
没有投票机制,共识通过群体行为自然涌现。
python
class EmergentConsensus:
"""
群体共识------不是投票,而是看大多数人怎么做
"""
async def converge(self, swarm: Swarm, decision: str) -> Consensus:
"""
例如:选哪个邮件服务?
"""
# 收集所有 Agent 的"倾向"(不是投票,是观察它们实际选什么)
tendencies = {}
for agent in swarm.agents:
if agent.current_task and "email" in agent.current_task.description.lower():
# 看 Agent 实际在代码里引入了什么包
choice = agent.detect_imported_package()
tendencies[choice] = tendencies.get(choice, 0) + 1
# 涌现结果:大多数人实际走的路
if tendencies:
winner = max(tendencies, key=tendencies.get)
confidence = tendencies[winner] / sum(tendencies.values())
return Consensus(
choice=winner,
confidence=confidence,
basis="emergent_behavior", # 基于实际行为,不是投票
dissent= [c for c in tendencies if c != winner] # 少数派选择
)
5.2 蜂群动态拓扑
蜂群的组织结构不是固定的,根据任务动态变化。
python
class DynamicSwarmTopology:
"""
蜂群根据任务类型自动调整组织结构
"""
async def form_swarm(self, mission: Mission) -> Swarm:
"""根据任务性质决定蜂群形态"""
# 任务分类
if mission.is_exploratory(): # 探索性任务(如技术选型)
return await self._form_scout_swarm(mission, size=5)
# 5 个 Agent 分散探索不同方向
elif mission.is_complex_feature(): # 复杂功能开发
return await self._form_pipeline_swarm(mission, size=3)
# 3 个 Agent 流水线:1 架构 + 2 编码(并行不同模块)
elif mission.is_bug_fix(): # Bug 修复
return await self._form_striker_swarm(mission, size=2)
# 2 个 Agent 同时尝试不同修复方案
elif mission.is_refactoring(): # 重构
return await self._form_guardian_swarm(mission, size=2)
# 1 个重构 + 1 个实时验证
async def _form_scout_swarm(self, mission, size: int) -> Swarm:
"""
侦察蜂群:分散探索,定期归巢汇报
"""
agents = [self.spawn_agent() for _ in range(size)]
# 给每个 Agent 分配不同的探索方向
directions = self._diversify_directions(mission, n=size)
for agent, direction in zip(agents, directions):
agent.assign_direction(direction)
# 定期归巢(同步点)
swarm = Swarm(agents=agents, sync_interval=300) # 每 5 分钟同步一次
return swarm
5.3 蜂群执行协议
python
class SwarmExecutionProtocol:
"""
蜂群执行主循环
"""
async def run(self, swarm: Swarm, mission: Mission):
# 1. 蜂群同时多角度拆解任务
decompositions = await asyncio.gather(*[
agent.decompose(mission) for agent in swarm.agents[:3]
])
# 合并去重,生成最优任务树
task_tree = self._merge_decompositions(decompositions)
# 2. 发布到去中心化任务板
for task in task_tree.tasks:
await self.task_board.post_task(task)
# 3. 蜂群自主认领 + 执行
while not self.all_tasks_done(task_tree):
# 每个空闲 Agent 自己嗅探任务板,抢任务
idle_agents = [a for a in swarm.agents if a.is_idle()]
await asyncio.gather(*[
self._agent_work_loop(agent) for agent in idle_agents
])
# 定期同步(归巢)
await asyncio.sleep(10)
await self._swarm_sync(swarm)
async def _agent_work_loop(self, agent: Agent):
"""单个 Agent 的自治工作循环"""
while True:
# 1. 感知环境(嗅探痕迹)
env_context = await self.stigmergy.sniff_surroundings(agent)
# 2. 发现可认领的任务
available = self.task_board.get_unclaimed()
# 3. 自主评估哪个任务适合我
candidates = [
(task, await agent.assess_fit(task, env_context))
for task in available
]
candidates.sort(key=lambda x: x[1], reverse=True)
# 4. 尝试认领最适合的
for task, score in candidates:
if score < 0.4:
break # 没有适合我的任务,休息
if await self.task_board.claim_task(agent, task.id):
# 5. 执行
result = await agent.execute(task)
# 6. 验证
if await self.verify(result, task):
await self.task_board.complete_task(task.id, result)
# 留下 good_path 痕迹
await self.stigmergy.mark(agent, StigmergyMark(
location=task.id, type="good_path", strength=0.8
))
else:
# 留下 caution 痕迹
await self.stigmergy.mark(agent, StigmergyMark(
location=task.id, type="caution",
content=str(result.error), strength=0.6
))
# 放弃任务,让其他 Agent 尝试
await self.task_board.abandoned_task(agent, task.id, str(result.error))
break # 做完一个,重新评估
# 7. 如果没有可做的,等一会儿再嗅探
await asyncio.sleep(5)
5.4 蜂群 vs 单 Agent 效率对比(v2.1 修订)
修订:下调提速比预期,增加适用场景说明。
| 场景 | 单 Agent | 蜂群 (3 Agent) | 提速比 | 适用条件 |
|---|---|---|---|---|
| 技术选型调研 | 30 分钟串行 | 10 分钟并行 + 5 分钟交叉 | 2-3x | 需调研 3+ 方案 |
| 多模块功能开发 | 2 小时串行 | 50 分钟并行 + 10 分钟集成 | 1.8-2.2x | 模块可并行 |
| Bug 修复 (未知原因) | 1 小时试错 | 20 分钟双路 + 自动对比 | 1.5-2.5x | 失败原因未知 |
| 复杂重构 | 3 小时 | 1.5 小时并行重构 + 实时验证 | ~2x | 有实时验证 |
| 文档编写 | 20 分钟 | 12 分钟分块并行 | ~1.5x | 文档可分块 |
| 简单脚本/CURD | 5 分钟 | 8 分钟(蜂群开销更大) | < 1x | 不建议用蜂群 |
成本权衡 :蜂群用 1.5-2x 的 API 费用,换 1.5-2.5x 的时间节省。仅适用于可并行化的复杂任务。简单任务退化为单 Agent。
6. Agent 执行环境规范 (新增)
本章定义 Agent 的运行环境,是 Phase 0 的核心交付物。没有稳定的执行环境,Agent 自治是空谈。
6.1 沙盒隔离级别
python
@dataclass
class SandboxConfig:
"""
Agent 运行环境配置,分为三个隔离级别。
"""
level: str # "minimal" / "standard" / "relaxed"
# 文件系统权限
read_paths: List[str] # 允许读取的路径
write_paths: List[str] # 允许写入的路径
forbidden_paths: List[str] # 禁止访问的路径 (即使在 read_paths 中)
# 网络访问
allowed_domains: List[str] # 允许访问的域名白名单
max_request_size_mb: int = 10
# 命令执行
allowed_commands: List[str] # 允许执行的系统命令
shell_enabled: bool = False
# 资源限制
max_memory_mb: int = 1024
max_cpu_percent: int = 80
max_execution_seconds: int = 300 # 单次任务超时
隔离级别定义:
| 级别 | 适用场景 | 特点 |
|---|---|---|
minimal |
验证/测试任务 | 只读 + 无网络 + 无 shell |
standard |
普通开发任务 | 读写项目目录 + 允许的域名 + 有限命令 |
relaxed |
复杂调试任务 | 读写HOME + 全网络 + shell 权限 |
6.2 工具接口定义
所有 Agent 工具必须通过 Tool Gateway 调用,禁止直接执行系统命令。
python
class ToolGateway:
"""
工具网关:统一管理 Agent 可用的所有工具。
每个工具必须有明确的输入/输出定义和错误处理。
"""
async def execute(self, tool: ToolCall) -> ToolResult:
"""
统一入口,返回结构化结果。
失败时返回 ToolResult(error=...) 而非抛出异常。
"""
def available_tools(self) -> List[ToolSpec]:
"""
返回当前可用的工具列表及调用方式。
Agent 通过此接口自主选择工具。
"""
# 工具分类
class FileSystemTools:
"""文件系统工具"""
read_file(path: str) -> str
write_file(path: str, content: str) -> bool
list_dir(path: str) -> List[str]
exists(path: str) -> bool
class CommandTools:
"""命令执行工具"""
run_shell(command: str, timeout: int = 60) -> CommandResult
run_script(script_path: str, args: List[str]) -> CommandResult
class SearchTools:
"""搜索工具"""
web_search(query: str) -> List[SearchResult]
code_search(query: str, repo: str) -> List[CodeResult]
knowledge_base_search(query: str) -> List[KBResult]
class HttpTools:
"""HTTP 工具"""
http_get(url: str) -> HttpResult
http_post(url: str, body: dict) -> HttpResult
class DatabaseTools:
"""数据库工具"""
db_query(sql: str) -> QueryResult
db_execute(sql: str) -> ExecutionResult
6.3 工具调用失败处理
工具调用必须返回结构化结果,不能依赖异常来处理业务错误。
python
@dataclass
class ToolResult:
success: bool
data: Any = None
error: Optional[str] = None
error_code: str = "TOOL_ERROR" # 错误分类代码
retryable: bool = False # 是否可重试
cost_usd: float = 0.0
@staticmethod
def ok(data: Any, cost: float = 0.0) -> "ToolResult":
return ToolResult(success=True, data=data, cost_usd=cost)
@staticmethod
def fail(error: str, code: str, retryable: bool = False, cost: float = 0.0) -> "ToolResult":
return ToolResult(success=False, error=error, error_code=code, retryable=retryable, cost_usd=cost)
错误码分类:
| 错误码 | 含义 | 是否可重试 |
|---|---|---|
TOOL_NOT_FOUND |
工具不存在 | 否 |
TOOL_EXECUTION_FAILED |
工具执行失败 | 视情况 |
SANDBOX_PERMISSION_DENIED |
权限不足 | 否 |
NETWORK_TIMEOUT |
网络超时 | 是 |
RESOURCE_EXCEEDED |
资源超限 | 否 |
INVALID_INPUT |
输入参数错误 | 否 |
6.4 执行引擎架构
python
class AgentExecutor:
"""
Agent 执行引擎:管理单个 Agent 的生命周期。
"""
async def execute_task(self, task: Task, context: ExecutionContext) -> TaskResult:
"""
标准执行流程:
1. 创建/获取沙盒
2. 加载任务上下文
3. 执行 Agent 逻辑循环
4. 验证结果
5. 清理沙盒
"""
sandbox = await self.sandbox_manager.get_or_create(
task_id=task.id,
config=context.sandbox_config
)
try:
# 加载约束到沙盒环境变量
await sandbox.set_env("CONSTRAINTS", json.dumps(context.constraints))
# Agent 执行循环
agent = Agent(id=context.agent_id)
state = AgentState.INITIAL
while state != AgentState.DONE:
state = await self._tick(agent, task, sandbox)
# 超时检查
if context.elapsed_seconds > task.max_execution_seconds:
return TaskResult.error("TIMEOUT", f"任务执行超过 {task.max_execution_seconds} 秒")
# 资源检查
if sandbox.exceeded_resource_limits():
return TaskResult.error("RESOURCE_EXCEEDED", "沙盒资源超限")
# 验证
return await self._verify_and_return(task, sandbox)
finally:
await sandbox.release() # 释放沙盒,归还池中
async def _tick(self, agent: Agent, task: Task, sandbox: Sandbox) -> AgentState:
"""
Agent 执行循环的单次迭代。
"""
# 1. Agent 思考下一步
action = await agent.think(context=sandbox.current_state)
# 2. 通过网关执行工具
result = await self.tool_gateway.execute(action)
# 3. 更新状态
sandbox.update_state(result)
# 4. 检查是否完成
if result.is_terminal():
return AgentState.DONE
return AgentState.RUNNING
6.5 状态持久化
Agent 重启后能从断点恢复,不丢失任务进度。
python
@dataclass
class ExecutionSnapshot:
"""执行快照:记录 Agent 执行过程中的关键状态"""
task_id: str
agent_id: str
state: AgentState
current_step: int
sandbox_path: str # 沙盒工作目录路径
tool_call_history: List[ToolCall]
created_at: datetime
updated_at: datetime
class SnapshotManager:
"""快照管理器:定期保存/恢复执行状态"""
async def save(self, snapshot: ExecutionSnapshot):
"""保存执行快照到数据库"""
async def restore(self, task_id: str) -> Optional[ExecutionSnapshot]:
"""根据 task_id 恢复执行快照"""
async def checkpoint(self, task_id: str):
"""
检查点:保存当前状态,返回恢复点 ID。
用于 Agent 超时后重新拾取任务。
"""
恢复流程:
- 根据
task_id查询最新ExecutionSnapshot - 重新创建沙盒,加载
sandbox_path中的文件 - 从
current_step继续执行 - 重新执行最后一条 ToolCall(确保幂等性)
7. 自治执行层:Agent 自治协议
4.1 Agent 不是角色,是执行单元
python
@dataclass
class Agent:
"""
Agent 是通用执行单元,不是预定义角色。
每个 Agent 根据当前任务自主决定:
- 用什么工具
- 查什么资料
- 怎么做最好
"""
id: str
current_task: Optional[Task] = None
# Agent 的"能力"是动态的,不是预设的
capabilities: Dict[str, float] = field(default_factory=dict) # {"react": 0.8, "sql": 0.6}
# Agent 的"记忆"是累积的,不是清空的
experience: List[Experience] = field(default_factory=list)
class AgentAutonomyProtocol:
"""
Agent 自治协议: 只给约束,不给剧本。
"""
async def execute(self, agent: Agent, task: Task) -> TaskResult:
# === Step 1: 理解任务 ===
understanding = await self._comprehend(task)
# === Step 2: 自主搜索信息 ===
# Agent 自己决定需要什么信息
knowledge_gaps = await self._identify_gaps(understanding)
for gap in knowledge_gaps:
info = await self._search(gap)
understanding = self._assimilate(understanding, info)
# === Step 3: 自主选工具 ===
# Agent 自己决定用什么工具完成
tools = await self._select_tools(task, understanding)
# === Step 4: 自主执行 ===
result = await self._execute_with_tools(task, tools)
# === Step 5: 自我验证 ===
verified = await self._verify(result, task.verification)
if not verified:
# 自主诊断问题
diagnosis = await self._diagnose(result, task)
# 自主决定修复策略
fix_strategy = await self._decide_fix(diagnosis)
result = await self._execute_fix(fix_strategy)
return result
4.2 自主搜索能力
python
class AutonomousSearch:
"""
Agent 自主搜索所需信息,不是人类喂给它。
"""
async def search_for_task(self, task: Task) -> Knowledge:
"""
Agent 自己判断需要什么信息。
"""
# 让 LLM 决定搜索策略
search_plan = await llm.generate(f"""
任务: {task.description}
你需要完成这个任务。但你现在什么都不知道。
请列出你需要搜索了解的信息清单,按优先级排序。
例如:
- "Next.js 14 App Router 的 API route 怎么写"
- "Prisma 的 email 字段怎么加唯一索引"
- "Resend API 的发邮件示例代码"
"""")
results = {}
for query in search_plan.queries:
# 多源并行搜索
results[query] = await self._multi_source_search(query)
return self._synthesize(results)
async def _multi_source_search(self, query: str) -> SearchResults:
"""多源搜索,不限定来源"""
sources = await asyncio.gather(
# 搜索代码仓库历史
self._search_codebase(query),
# 搜索本地知识库
self._search_knowledge_base(query),
# 搜索网络 (如果有 web search tool)
self._search_web(query),
# 搜索已安装的包文档
self._search_package_docs(query),
# 搜索 MCP/Skill 可用工具
self._search_mcp_registry(query),
)
return self._rank_by_relevance(sources)
4.3 自主工具选择
python
class AutonomousToolSelection:
"""
Agent 根据任务自主选择和组合工具。
不依赖预设的工具列表。
"""
async def select_tools(self, task: Task, context: Knowledge) -> ToolChain:
"""
Agent 自主决定用什么工具链。
"""
# 发现可用工具
available = await self.discovery.scan()
# LLM 自主决策
tool_chain = await llm.generate_structured(f"""
任务: {task.description}
你已了解的信息: {context.summary}
可用工具:
{json.dumps(available, indent=2)}
请选择合适的工具组合来完成任务。
你必须考虑:
1. 工具是否能完成所需功能
2. 工具之间是否能协同
3. 是否有更简单的替代方案
4. 成本和可靠性
输出工具链和理由。
""")
return tool_chain
4.4 遇到障碍自主解决
python
class ObstacleHandler:
"""
Agent 遇到障碍时的自主决策。
"""
async def handle(self, agent: Agent, task: Task, error: Error) -> Resolution:
"""
不预设错误处理流程,让 AI 自己诊断和解决。
"""
diagnosis = await llm.generate(f"""
任务: {task.description}
当前状态: {agent.current_state}
遇到的错误: {error.message}
错误上下文: {error.context}
请诊断:
1. 这个错误的根本原因是什么?
2. 有哪些可能的解决方案?
3. 每个方案的风险和成本?
4. 你推荐哪个方案?
""")
# 根据诊断自主执行修复
if diagnosis.recommended_action.type == "search_alternative":
# 搜索替代方案
alternative = await agent.search(diagnosis.recommended_action.query)
return await agent.retry_with(alternative)
elif diagnosis.recommended_action.type == "decompose_further":
# 任务太复杂,需要进一步拆分
subtasks = await MissionDecomposer().decompose(task)
return await agent.execute_parallel(subtasks)
elif diagnosis.recommended_action.type == "escalate":
# 无法自主解决,上报
return Escalation(reason=diagnosis.root_cause, suggested_help=diagnosis.needs)
elif diagnosis.recommended_action.type == "retry_with_adjustment":
# 调整参数重试
return await agent.retry_with_adjustment(diagnosis.adjustment)
6. 人机协作层:Human-in-the-Loop
6.1 核心思想:AI 不是孤岛
蜂群再智能,也有必须人类介入的边界:
- 💰 资金操作:充值 API 额度、购买云服务
- 🔑 密钥配置:填写 API Key、配置 OAuth
- 🏗️ 资源申请:开通服务器权限、申请域名备案
- ✅ 关键决策:技术选型分歧需要人类拍板、架构方向确认
- 🔒 安全审批:生产环境部署、数据库变更、密钥轮换
AI 的职责不是绕过人类,而是:
- 精准识别何时必须人类介入
- 清晰表达需要什么、为什么需要、什么时候要
- 优雅暂停工作流,不阻塞其他可并行任务
- 自动恢复人类响应后立即继续
- 主动跟进长时间未响应时提醒
6.2 人机交互类型
| 类型 | 场景 | AI 行为 | 人类响应方式 |
|---|---|---|---|
| 信息收集 | 需要业务背景知识 | 提问并给出选项 | 选择或文字回复 |
| 权限申请 | 需要 API Key / Token | 生成申请表单 | 填写并提交 |
| 资金操作 | API 额度不足 | 生成充值链接 + 成本说明 | 点击支付 |
| 决策确认 | 技术选型分歧 | 给出对比报告 + 推荐 | 确认或否决 |
| 安全审批 | 生产部署 | 生成变更清单 + 风险说明 | 批准或驳回 |
| 验收确认 | 功能完成待上线 | 生成演示 + 测试报告 | 确认或打回 |
6.3 人机协作协议
python
class HumanInTheLoop:
"""
人机协作中枢:AI 主动、清晰、礼貌地向人类求助
"""
async def request(self, agent: Agent, need: HumanNeed) -> HumanResponse:
"""
AI 向人类发起请求的标准流程
"""
# 1. 生成请求(结构化、可执行)
request = await self._craft_request(agent, need)
# 2. 记录到待处理队列(支持异步)
ticket = await self._create_ticket(request)
# 3. 通知人类(多渠道)
await self._notify_human(request, urgency=need.urgency)
# 4. 暂停当前 Agent(但不阻塞整个蜂群)
agent.state = "WAITING_FOR_HUMAN"
# 5. 等待响应(轮询 + WebSocket 推送)
response = await self._wait_for_response(ticket, timeout=need.timeout)
# 6. 恢复执行
agent.state = "RESUMED"
return response
async def _craft_request(self, agent: Agent, need: HumanNeed) -> HumanRequest:
"""
生成清晰、可执行的人类请求
"""
if need.type == "API_KEY":
return HumanRequest(
title=f"需要配置 {need.service} API Key",
body=f"""
## 为什么需要
Agent [{agent.id}] 正在执行任务 [{agent.current_task.id}],
需要调用 {need.service} 来完成 [{need.purpose}]。
## 影响
如果不配置,该任务将无法继续,但其他不依赖此服务的任务仍可并行执行。
## 操作步骤
1. 访问 [{need.service_url}]
2. 创建 API Key(选择权限:{need.required_scopes})
3. 点击下方输入框粘贴
## 预计成本
{need.estimated_cost}/月
""",
action_type="INPUT", # 需要人类输入
input_schema={"api_key": "string"},
deadline=need.deadline,
fallback="如果24小时未响应,将尝试使用免费替代方案"
)
elif need.type == "RECHARGE":
return HumanRequest(
title="API 额度不足,需要充值",
body=f"""
## 当前状况
剩余额度:${need.remaining_balance}
本次任务预计消耗:${need.estimated_cost}
缺口:${need.shortfall}
## 推荐充值
金额:${need.recommended_amount}
理由:可覆盖未来 {need.coverage_sprints} 个 Sprint
## 支付链接
[{need.payment_url}]
## 紧急程度
{need.urgency}
""",
action_type="CLICK", # 点击链接即可
fallback="如果2小时未充值,将自动降级到 cheaper model 继续"
)
elif need.type == "DECISION":
return HumanRequest(
title=f"技术选型需要您拍板:{need.decision_topic}",
body=f"""
## 背景
蜂群在 [{need.task_context}] 遇到选型分歧:
{self._format_options(need.options)}
## 蜂群涌现倾向
基于实际行为分析,{need.emergent_winner} 被更多 Agent 采用。
## 推荐
{need.recommendation}
## 操作
请选择:{[o.name for o in need.options]}
或回复您的理由,蜂群将按您的决策执行。
""",
action_type="SELECT",
options=[o.name for o in need.options],
fallback="如果4小时未响应,将采用蜂群涌现共识继续"
)
6.4 人机通信渠道
python
class HumanNotification:
"""
多渠道触达人类,确保请求不被遗漏
"""
async def send(self, request: HumanRequest, profile: UserProfile):
"""根据紧急程度选择渠道组合"""
channels = []
# 所有请求都进 Dashboard
channels.append(DashboardNotification(request))
# 紧急请求额外推送
if request.urgency == "HIGH":
if profile.has_email:
channels.append(EmailNotification(request))
if profile.has_slack:
channels.append(SlackDM(request))
if profile.has_phone:
channels.append(SMSNotification(request))
# 关键决策(资金/安全)强制多渠道
if request.type in ["RECHARGE", "SECURITY_APPROVAL"]:
channels.append(PushNotification(request)) # 浏览器推送
await asyncio.gather(*[c.send() for c in channels])
async def _dashboard_ui(self, request: HumanRequest) -> dict:
"""Dashboard 中的交互卡片"""
return {
"type": "human_request",
"title": request.title,
"body": request.body,
"actions": self._render_actions(request),
"deadline": request.deadline,
"blocking_tasks": request.blocking_tasks,
"other_tasks_still_running": request.non_blocking_tasks,
}
6.5 优雅暂停与恢复
python
class GracefulPause:
"""
需要人类时,只暂停阻塞路径,其他蜂群继续飞
"""
async def handle_human_request(self, swarm: Swarm, ticket: Ticket):
"""
处理需要人类介入的场景
"""
# 找到被阻塞的任务
blocked_task = ticket.blocking_task
# 找到依赖此任务的其他任务(也被阻塞)
downstream = swarm.task_tree.get_downstream(blocked_task)
# 找到不依赖此任务的任务(继续执行)
independent = [t for t in swarm.task_tree.tasks if t not in downstream and t != blocked_task]
# 暂停阻塞链
for task in downstream:
task.state = "PAUSED_WAITING_HUMAN"
agent = swarm.find_agent_by_task(task)
if agent:
agent.state = "IDLE" # 释放 Agent 去做其他事
# 独立任务继续跑
await swarm.continue_parallel(independent)
# 等待人类响应
response = await self.wait_for_ticket(ticket)
# 恢复阻塞链
if response.approved:
for task in [blocked_task] + downstream:
task.state = "READY"
# 重新分配 Agent 执行
await swarm.task_board.post_task(task)
return response
6.6 人机协作 Dashboard
ini
┌─────────────────────────────────────────────────────────────────┐
│ [Logo] AI AutoDev Team [🔔 3 条待处理] [余额: $47.3] │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 待您处理 (3) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🔴 紧急: API 额度不足 (阻塞 2 个任务) │ │
│ │ 剩余 $2.1,任务预计 $5.4,需要充值 $10 │ │
│ │ [ 立即充值 ] [ 先暂停,我稍后处理 ] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🟡 决策: 数据库选型 (阻塞 1 个任务) │ │
│ │ Agent 们用了 PostgreSQL 和 MySQL,需要您确认 │ │
│ │ 推荐: PostgreSQL (原因: JSONB 支持更好) │ │
│ │ [ 确认 PostgreSQL ] [ 选 MySQL ] [ 其他方案 ] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🔵 信息: 需要业务确认 │ │
│ │ "注册时是否需要手机号验证?" │ │
│ │ [ 需要 ] [ 不需要 ] [ 仅邮箱即可 ] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ 正在运行 (不受阻塞影响) │
│ ├─ 前端页面开发 ............................... 78% │
│ ├─ 单元测试编写 ............................... 45% │
│ └─ 文档生成 ................................. 90% │
│ │
└─────────────────────────────────────────────────────────────────┘
6.7 常见人机协作场景
场景 1:API Key 缺失
markdown
Agent-3 正在集成邮件服务,需要 Resend API Key。
AI 行为:
1. 检测环境变量:RESEND_API_KEY 未设置
2. 检测 Resend 文档:需要 API Key
3. 生成请求:"需要配置 Resend API Key"
4. 暂停 Agent-3 的邮件相关任务
5. Agent-1 (前端) 和 Agent-2 (测试) 继续不受影响
人类响应:
→ 点击 Dashboard 输入框 → 粘贴 API Key → 点击确认
AI 行为:
6. 验证 Key 可用(发送测试邮件)
7. 恢复 Agent-3 执行
8. 记录到环境配置(下次复用)
场景 2:预算不足
markdown
蜂群执行中,剩余额度 $2.1,当前 Sprint 预估还需 $5.4。
AI 行为:
1. 预测:按当前消耗速度,30 分钟后额度耗尽
2. 评估:降级到 GPT-4o-mini 可以撑 2 小时,但质量下降
3. 生成请求:"API 额度不足,建议充值 $10"
4. 附带:历史消耗趋势图、推荐充值金额理由
人类响应:
→ 点击充值链接 → 支付 $10 → 系统检测到额度更新
AI 行为:
5. 恢复所有 Agent 全力运行
6. 记录:此 Sprint 因充值中断 15 分钟
场景 3:技术选型分歧
markdown
3 个 Agent 分别选了 PostgreSQL、MySQL、SQLite。
AI 行为:
1. 收集各 Agent 的选型理由(Stigmergy 痕迹)
2. 分析:PostgreSQL 被 2 个 Agent 实际采用,SQLite 被 1 个
3. 生成 ADR(架构决策记录)草案
4. 生成请求:"数据库选型需要确认"
5. 附带:对比表、蜂群倾向、推荐
人类响应:
→ 选择 PostgreSQL → 添加备注 "同意,长期项目需要扩展性"
AI 行为:
6. 采用 PostgreSQL 的 Agent 继续
7. 采用 SQLite 的 Agent 自动迁移到 PostgreSQL
8. 最终 ADR 记录人类决策理由
场景 4:安全审批
markdown
蜂群完成任务,准备部署到生产环境。
AI 行为:
1. 检测:涉及数据库 Schema 变更(新增 User 表)
2. 生成变更清单:DDL 语句、回滚脚本、影响范围
3. 生成请求:"生产部署需审批"
4. 附带:风险评估、回滚方案、测试报告
人类响应:
→ 查看变更清单 → 确认测试通过 → 点击批准
AI 行为:
5. 执行部署(在维护窗口)
6. 监控 5 分钟,确认无异常
7. 生成部署报告
6.8 人机协作原则
| 原则 | 说明 |
|---|---|
| 不阻塞全局 | 需要人类的任务暂停,其他独立任务继续 |
| 一次说清 | 请求包含:背景、影响、操作步骤、截止时间、备选方案 |
| 减少摩擦 | 提供一键操作(点击确认、一键充值),不让用户输入复杂内容 |
| 上下文保留 | 人类响应后,AI 知道之前发生了什么,无需重复解释 |
| 礼貌提醒 | 快到期时礼貌提醒,不骚扰,提供"稍后处理"选项 |
| 学习偏好 | 记录人类的常见决策模式,下次主动推荐 |
7. 边界约束系统(唯一硬编码的规则)
5.1 约束类型
python
@dataclass
class ConstraintSystem:
"""
人类只定义边界,不定义过程。
"""
# === 技术约束 ===
tech_stack: Optional[List[str]] = None # ["nextjs", "prisma", "typescript"]
forbidden_tech: Optional[List[str]] = None # ["jquery", "php"]
# === 安全边界 ===
forbidden_paths: List[str] = field(default_factory=list) # ["/etc", "~/.ssh"]
forbidden_operations: List[str] = field(default_factory=list) # ["rm -rf /", "drop table"]
network_allowlist: Optional[List[str]] = None # ["api.github.com", "registry.npmjs.org"]
# === 资源约束 ===
budget_usd: float = 10.0 # 本次任务预算上限
time_limit_minutes: int = 120
token_limit: int = 100000
# === 质量约束 ===
min_test_coverage: float = 80.0
required_deliverables: List[str] = field(default_factory=list) # ["code", "tests", "docs"]
# === 范围约束 ===
scope_in: List[str] = field(default_factory=list) # 必须包含
scope_out: List[str] = field(default_factory=list) # 明确排除
# 约束检查器
class ConstraintEnforcer:
"""所有 Agent 行为必须通过约束检查"""
async def check(self, action: AgentAction, constraints: ConstraintSystem) -> bool:
# 检查安全边界
if action.fetches.any(path in constraints.forbidden_paths):
return False, f"禁止访问 {path}"
# 检查预算
if action.estimated_cost + self.spent > constraints.budget_usd:
return False, f"超出预算: {action.estimated_cost} > 剩余 {constraints.budget_usd - self.spent}"
# 检查技术栈
if action.uses_tech not in constraints.tech_stack:
return False, f"不允许使用 {action.uses_tech}"
return True, "通过"
5.2 约束示例
yaml
# 人类输入的约束(YAML 格式)
mission: "实现用户注册模块,含邮箱验证码"
constraints:
tech_stack:
- nextjs
- prisma
- typescript
- tailwindcss
forbidden_tech:
- jquery
- php
- python # 前端项目不许混 Python
budget_usd: 5.0
time_limit_minutes: 90
quality:
min_test_coverage: 80
required_deliverables:
- code
- tests
- architecture_decision_record # 为什么选 Resend 而不是 SendGrid
- demo_screenshot
security:
forbidden_operations:
- "DELETE FROM"
- "DROP TABLE"
- "rm -rf"
forbidden_paths:
- "/etc"
- "~/.ssh"
network_allowlist:
- "registry.npmjs.org"
- "api.resend.com"
scope:
in:
- "用户注册表单"
- "邮箱验证码发送"
- "验证码校验"
- "密码存储(bcrypt)"
out:
- "OAuth 第三方登录"
- "手机号验证码"
- "管理后台"
8. 验证层:不通过就不算完成
6.1 验证即契约
python
class VerificationEngine:
"""
每个子任务必须有客观、自动、无歧义的验证。
AI 自己生成验证方式,人类只审查验证是否合理。
"""
async def verify(self, task: Task, result: TaskResult) -> VerificationResult:
"""
根据任务定义的 verification spec 自动验证。
"""
spec = task.verification
if spec.type == "file_exists":
exists = await self._check_file_exists(spec.path)
return VerificationResult(passed=exists, detail=f"{spec.path} 存在: {exists}")
elif spec.type == "command_exit_0":
proc = await asyncio.create_subprocess_shell(
spec.command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=spec.timeout_seconds)
passed = proc.returncode == 0
return VerificationResult(
passed=passed,
detail=f"命令: {spec.command}\n退出码: {proc.returncode}\n输出: {stdout.decode()[:500]}"
)
elif spec.type == "coverage_threshold":
coverage = await self._parse_coverage_report(result.test_output)
passed = coverage >= spec.min_coverage
return VerificationResult(
passed=passed,
detail=f"覆盖率: {coverage}% (要求 ≥ {spec.min_coverage}%)"
)
elif spec.type == "custom_script":
# 运行自定义验证脚本
result = await self._run_custom_verifier(spec.script_path, result)
return result
### 6.2 验证类型补充 (v2.1 新增)
> 原文档验证类型覆盖不足,新增以下类型以提高验证覆盖率。
```python
@dataclass
class VerificationType(Enum):
"""扩展的验证类型列表"""
# === 基础验证 (原有) ===
FILE_EXISTS = "file_exists" # 文件存在性
COMMAND_EXIT_0 = "command_exit_0" # 命令退出码为 0
COVERAGE_THRESHOLD = "coverage_threshold" # 测试覆盖率
CURL_200 = "curl_200" # HTTP 请求返回 200
E2E_PASS = "e2e_pass" # E2E 测试通过
# === 新增:代码质量验证 (v2.1) ===
LINT_PASS = "lint_pass" # 代码风格检查通过 (ESLint/Pylint)
TYPE_CHECK = "type_check" # 类型检查通过 (TypeScript/mypy)
NO_SECURITY_VULNS = "no_security_vulns" # 无安全漏洞 (Semgrep/Bandit)
# === 新增:功能正确性验证 (v2.1) ===
SCHEMA_VALID = "schema_valid" # 数据库 Schema 验证通过
API_CONTRACT = "api_contract" # API 响应符合 OpenAPI Schema
LOGIC_ASSERT = "logic_assert" # 业务逻辑断言 (自定义检查)
# === 新增:运行时行为验证 (v2.1) ===
MEMORY_USAGE = "memory_usage" # 内存使用在限制内
RESPONSE_TIME = "response_time" # 响应时间符合要求
CONCURRENT_PASS = "concurrent_pass" # 并发测试通过
# === 新增:数据验证 (v2.1) ===
DB_MIGRATION = "db_migration" # 数据库迁移成功
DB_ROLLBACK = "db_rollback" # 数据库回滚测试通过
DATA_INTEGRITY = "data_integrity" # 数据完整性检查通过
验证类型使用场景:
| 验证类型 | 适用场景 | 示例 |
|---|---|---|
LINT_PASS |
所有代码任务 | npx eslint src/ |
TYPE_CHECK |
TypeScript/Python 项目 | npx tsc --noEmit / mypy src/ |
NO_SECURITY_VULNS |
安全敏感任务 | semgrep --config=auto . |
SCHEMA_VALID |
数据库 Schema 变更 | prisma validate |
API_CONTRACT |
API 开发 | 验证响应 JSON 符合 Schema |
LOGIC_ASSERT |
业务逻辑验证 | 自定义断言脚本 |
RESPONSE_TIME |
API 性能验证 | curl -w "%{time_total}" |
DB_MIGRATION |
数据库迁移任务 | prisma migrate dev |
DATA_INTEGRITY |
数据处理任务 | 检查记录数、字段完整性 |
验证结果结构:
python
@dataclass
class VerificationResult:
"""验证结果"""
passed: bool
type: str # 验证类型
detail: str # 详细输出
duration_ms: int # 验证耗时
cost_usd: float = 0.0 # 验证消耗成本
error_code: str = None # 如果失败,错误码
@property
def summary(self) -> str:
status = "✅ PASS" if self.passed else "❌ FAIL"
return f"{status} [{self.type}] {self.detail[:100]}"
python
async def auto_fix(self, task: Task, result: TaskResult, verification: VerificationResult):
"""
验证不通过 → AI 自主分析原因并修复。
"""
if not verification.passed:
# 诊断失败原因
diagnosis = await llm.generate(f"""
任务: {task.description}
验证失败: {verification.detail}
请分析:
1. 为什么验证失败?
2. 代码或配置需要怎么改?
3. 修改后如何重新验证?
""")
# 执行修复
fix_result = await agent.execute(diagnosis.fix_plan)
# 重新验证
return await self.verify(task, fix_result)
yaml
### 6.2 验收报告
```yaml
# 自动生成的验收报告
mission: "实现用户注册模块"
status: PASSED # 所有子任务验证通过
tasks:
- id: T1
description: "设计数据库 Schema"
verification: "prisma validate 通过"
result: PASSED
attempts: 1
cost: "$0.2"
- id: T2
description: "实现注册 API"
verification: "curl 返回 200 && 数据库有记录"
result: PASSED
attempts: 2 # 第一次 bcrypt 配置错了,自动修复
cost: "$0.6"
- id: T3
description: "集成邮箱服务"
verification: "测试邮箱收到邮件 && 验证码可校验"
result: PASSED
attempts: 3
cost: "$1.2"
# ADR: 为什么选 Resend
decision_record: |
搜索对比了 SendGrid ($0.10/封)、Resend ($0.0001/封)、AWS SES ($0.10/封)。
对于验证码场景(低频率),Resend 免费额度足够,API 最简单,故选择。
备选: 如果量上去,可迁移到 AWS SES。
- id: T4
description: "前端注册页面"
verification: "Playwright E2E 通过"
result: PASSED
cost: "$0.8"
- id: T5
description: "测试覆盖"
verification: "coverage ≥ 80%"
result: PASSED
actual_coverage: 83.2%
cost: "$0.4"
total_cost: "$3.2 / $5.0"
total_time: "47分钟 / 90分钟"
auto_fixes: 2 # AI 自主修复了 2 次错误
human_interventions: 1 # 1 次请求 API Key 配置
escalations: 0 # 没有无法解决需要人工接管的情况
7. 工具自治层(Tool Mesh)
7.1 核心思想
Agent 不依赖预设工具列表。遇到任务时:
- 搜索------系统里有什么工具?网络上有什么?
- 评估------哪个最适合当前任务?
- 获取------没有的话自动安装/配置
- 调用------标准化接口执行
7.2 工具发现
python
class ToolDiscovery:
"""
自动发现所有可用工具和能力。
"""
async def discover_all(self) -> ToolCatalog:
catalog = ToolCatalog()
# 1. 扫描本地 OpenClaw Skills
catalog.add(await self._scan_skills("~/.agents/skills/"))
# 2. 扫描 MCP Servers
catalog.add(await self._scan_mcp_servers())
# 3. 扫描系统命令
catalog.add(await self._scan_executables())
# 4. 扫描已安装包的能力
catalog.add(await self._scan_packages())
# 5. 扫描环境 API Keys (判断可用外部服务)
catalog.add(await self._scan_api_availability())
# 6. 扫描代码仓库历史 (复用已有工具函数)
catalog.add(await self._scan_codebase_tools())
return catalog
7.3 工具自动获取
python
class ToolAcquisition:
"""
当现有工具不够时,自动搜索并获取新工具。
"""
async def acquire(self, need: str, constraints: ConstraintSystem) -> Tool:
"""
需要: "发送邮件"
约束: 只能用 Python/TypeScript,预算<$1
自动:
1. 搜索 PyPI/npm 上邮件相关包
2. 对比文档完整性、GitHub stars、最近更新
3. 在沙盒安装测试
4. 验证可用后纳入 Catalog
"""
# 搜索候选
candidates = await self._search_packages(need, constraints.tech_stack)
# 评估 (多维度)
scored = []
for cand in candidates:
score = await self._evaluate(cand, criteria=[
"stars",
"last_update_within_6_months",
"has_typescript_definitions",
"license_compatible",
"install_size_under_10mb"
])
scored.append((cand, score))
# 选择最佳
best = max(scored, key=lambda x: x[1])
# 沙盒安装验证
installed = await self._sandbox_install(best[0])
test_pass = await self._verify_tool_works(installed, need)
if test_pass:
return installed
else:
# 试下一个
return await self._try_next(scored)
8. LLM 调用策略 (新增)
本章定义 Agent 执行时使用哪个 LLM、如何动态降级、成本如何控制。 没有策略的 LLM 调用是成本失控的根源。
8.1 模型分级
python
class LLMModelTier:
"""
LLM 模型分级,按能力和成本递增。
"""
# 级别 1:低成本,小任务
HAIKU = {
"name": "claude-haiku-4-5-20251101",
"cost_per_1k_input": 0.0008,
"cost_per_1k_output": 0.004,
"context_window": 200000,
"typical_use": "简单文件操作、文本替换、模式匹配"
}
# 级别 2:中成本,常规任务
SONNET = {
"name": "claude-sonnet-4-6-20251101",
"cost_per_1k_input": 0.003,
"cost_per_1k_output": 0.015,
"context_window": 200000,
"typical_use": "代码编写、API 实现、单元测试"
}
# 级别 3:高成本,复杂任务
OPUS = {
"name": "claude-opus-4-7",
"cost_per_1k_input": 0.015,
"cost_per_1k_output": 0.075,
"context_window": 200000,
"typical_use": "架构设计、复杂 bug 诊断、多文件重构"
}
# 降级选项(OpenAI)
GPT4O_MINI = {
"name": "gpt-4o-mini",
"cost_per_1k_input": 0.00015,
"cost_per_1k_output": 0.0006,
"context_window": 128000,
"typical_use": "预算不足时的降级选项"
}
8.2 任务复杂度分类器
系统自动判断任务复杂度,决定使用哪个模型层级。
python
class TaskComplexityClassifier:
"""
任务复杂度分类器:自动评估任务需要什么级别的模型。
"""
async def classify(self, task: Task) -> LLMModelTier:
"""
根据任务特征评估复杂度。
"""
complexity_score = 0
# 因素 1:任务涉及的文件数量
if task.depends_on_files:
file_count = len(task.depends_on_files)
complexity_score += min(file_count * 0.2, 2.0) # 最多 +2
# 因素 2:是否涉及多技术栈交互
tech_stack_mix = len(task.required_tech_stacks)
complexity_score += tech_stack_mix * 0.5 # 每个技术栈 +0.5
# 因素 3:任务描述的语义复杂度
semantic_complexity = self._estimate_semantic_complexity(task.description)
complexity_score += semantic_complexity
# 因素 4:是否涉及决策/架构设计
if any(keyword in task.description.lower()
for keyword in ["设计", "架构", "方案", "选择", "决策"]):
complexity_score += 1.5
# 因素 5:是否涉及未知领域
if task.unknown_domain:
complexity_score += 1.0
# 映射到模型层级
if complexity_score < 2.0:
return LLMModelTier.HAIKU
elif complexity_score < 4.0:
return LLMModelTier.SONNET
else:
return LLMModelTier.OPUS
def _estimate_semantic_complexity(self, description: str) -> float:
"""
简单启发式评估语义复杂度。
实际实现可由 LLM 辅助判断。
"""
score = 0.0
# 句子越多越复杂
sentences = description.count("。") + description.count(".")
score += min(sentences * 0.1, 1.0)
# 连接词越多越复杂
connectors = ["并且", "而且", "同时", "此外", "但是", "然而", "然而", "所以", "因此", "然而"]
score += sum(0.15 for c in connectors if c in description)
return min(score, 2.0)
复杂度评分因素:
| 因素 | 权重 | 说明 |
|---|---|---|
| 文件数量 | 0.2/个 | 最多 +2 |
| 技术栈种类 | 0.5/种 | 跨栈越多越复杂 |
| 语义复杂度 | 0-2 | 句子数、连接词密度 |
| 决策/架构关键词 | +1.5 | 含"设计/架构/方案" |
| 未知领域 | +1.0 | 任务描述涉及陌生技术 |
8.3 动态降级策略
当预算不足或响应超时,自动降级到更便宜的模型。
python
class LLMDynamicDowngrade:
"""
LLM 动态降级策略。
"""
async def execute_with_fallback(
self,
task: Task,
preferred_tier: LLMModelTier,
budget_remaining: float
) -> LLMResult:
"""
执行 LLM 调用,必要时降级。
"""
# 预估当前层级的成本
estimated_cost = self._estimate_cost(task, preferred_tier)
# 如果预估成本超过预算的 30%,考虑降级
if estimated_cost > budget_remaining * 0.3:
preferred_tier = self._try_downgrade(preferred_tier)
# 执行调用
result = await self._call_llm(task, preferred_tier)
# 如果超时,尝试降级
if result.timeout and preferred_tier != LLMModelTier.HAIKU:
result = await self._call_llm(task, LLMModelTier.HAIKU)
return result
def _try_downgrade(self, tier: LLMModelTier) -> LLMModelTier:
"""尝试降级到下一级"""
downgrade_map = {
LLMModelTier.OPUS: LLMModelTier.SONNET,
LLMModelTier.SONNET: LLMModelTier.HAIKU,
LLMModelTier.HAIKU: LLMModelTier.GPT4O_MINI
}
return downgrade_map.get(tier, tier)
降级触发条件:
| 触发条件 | 降级策略 |
|---|---|
| 预算剩余 < 20% | 强制降一级 |
| 单次调用超时 > 30s | 降一级重试 |
| 连续 3 次 OPUS 失败 | 降级到 SONNET |
| 任务预估成本 > 预算 30% | 降级到更低层级 |
8.4 成本控制机制
python
class CostController:
"""
成本控制器:实时监控和限制 LLM 调用成本。
"""
def __init__(self, budget_usd: float, mission_id: str):
self.budget_usd = budget_usd
self.mission_id = mission_id
self.spent_usd = 0.0
self.alert_threshold = 0.8 # 80% 时告警
async def check_and_charge(self, estimated_cost: float) -> bool:
"""
检查预算是否足够,预扣费用。
返回 True 表示可以继续,False 表示预算不足。
"""
if self.spent_usd + estimated_cost > self.budget_usd:
# 预算不足,触发人类介入
await self._request_budget_increase()
return False
self.spent_usd += estimated_cost # 预扣
# 告警
if self.spent_usd > self.budget_usd * self.alert_threshold:
await self._send_budget_alert()
return True
async def _request_budget_increase(self):
"""预算不足时创建人机协作票"""
await human_ticket_manager.create(
type="RECHARGE",
title="预算不足,需要充值",
body=f"已消耗 ${self.spent_usd:.2f} / ${self.budget_usd:.2f}",
urgency="HIGH"
)
8.5 Token 使用优化
python
class TokenOptimizer:
"""
Token 使用优化:减少不必要的上下文开销。
"""
def optimize_prompt(self, prompt: str, context: dict) -> str:
"""
优化 prompt,减少 token 消耗。
"""
# 移除冗余的示例代码
prompt = self._trim_excessive_examples(prompt)
# 压缩技术文档中的空白
prompt = self._compress_whitespace(prompt)
# 只传递必要的上下文(而非全部)
if context.get("file_count", 0) > 5:
# 只传递关键文件路径,Agent 需要时再读取
key_files = self._select_key_files(context["files"], k=5)
prompt = prompt.replace(
f"相关文件: {context['files']}",
f"关键文件: {key_files}"
)
return prompt
def estimate_tokens(self, text: str) -> int:
"""
粗略估算 token 数量(实际按 Provider 计数)。
英文约 4 字符/token,中文约 2 字符/token。
"""
return int(len(text) / 3)
9. 任务复杂度分类器 (新增)
本章定义如何判断任务是"简单"还是"复杂",决定用单 Agent 还是蜂群。
9.1 复杂度分级
python
@dataclass
class TaskComplexity:
level: str # "simple" / "medium" / "complex" / "very_complex"
score: float # 0.0 - 10.0
reasons: List[str] # 为什么这么判断
recommended_mode: str # "single" / "swarm_small" / "swarm_medium" / "swarm_large"
estimated_cost_usd: float # 预估成本
class TaskComplexityScorer:
"""
任务复杂度评分器。
"""
async def score(self, task: Task) -> TaskComplexity:
"""
综合评估任务复杂度。
"""
factors = []
# 因素 1:代码库规模
codebase_size = task.codebase_size_mb or 0
if codebase_size > 100:
factors.append(("LARGE_CODEBASE", 2.0, "代码库 > 100MB"))
elif codebase_size > 50:
factors.append(("MEDIUM_CODEBASE", 1.0, "代码库 50-100MB"))
# 因素 2:跨文件程度
files_affected = task.estimated_files_affected or 0
if files_affected > 10:
factors.append(("MANY_FILES", 2.0, f"涉及 {files_affected} 个文件"))
elif files_affected > 5:
factors.append(("SOME_FILES", 1.0, f"涉及 {files_affected} 个文件"))
# 因素 3:技术栈数量
tech_count = len(task.required_tech_stacks or [])
if tech_count > 3:
factors.append(("MULTI_STACK", 1.5, f"涉及 {tech_count} 个技术栈"))
# 因素 4:决策点数量
decisions = task.decision_points or 0
if decisions > 5:
factors.append(("MANY_DECISIONS", 2.0, f"需要 {decisions} 个决策"))
elif decisions > 2:
factors.append(("SOME_DECISIONS", 1.0, f"需要 {decisions} 个决策"))
# 因素 5:不确定性
if task.has_unknown_dependencies:
factors.append(("UNCERTAINTY", 1.5, "存在未知依赖"))
if task.has_external_api:
factors.append(("EXTERNAL_API", 1.0, "需要调用外部 API"))
# 计算总分
total_score = sum(f[1] for f in factors)
# 映射到等级
if total_score < 2.0:
level = "simple"
mode = "single"
elif total_score < 4.0:
level = "medium"
mode = "swarm_small" # 2 Agent
elif total_score < 6.0:
level = "complex"
mode = "swarm_medium" # 3 Agent
else:
level = "very_complex"
mode = "swarm_large" # 5 Agent
return TaskComplexity(
level=level,
score=total_score,
reasons=[f[2] for f in factors],
recommended_mode=mode,
estimated_cost_usd=self._estimate_cost(total_score)
)
9.2 复杂度分级定义
| 等级 | 分值 | 特征 | 推荐模式 | 预估成本 |
|---|---|---|---|---|
| 简单 (simple) | < 2 | 单文件、单一技术栈、无决策 | 单 Agent | < $0.5 |
| 中等 (medium) | 2-4 | 2-5 个文件、多技术栈、有 API 调用 | 2 Agent 蜂群 | $0.5-1.5 |
| 复杂 (complex) | 4-6 | 多文件、复杂逻辑、多个决策点 | 3 Agent 蜂群 | $1.5-3.0 |
| 非常复杂 (very_complex) | > 6 | 大代码库、多技术栈、高不确定性 | 5 Agent 蜂群 | $3.0-8.0 |
9.3 复杂度与蜂群规模决策表
| 任务类型 | 复杂度 | 推荐方案 | 并行度 |
|---|---|---|---|
| 简单脚本修改 | simple | 单 Agent | 1 |
| API 实现(单端点) | medium | 单 Agent 或 2 Agent 冗余 | 1-2 |
| 多端点 API 开发 | complex | 3 Agent(1 架构 + 2 编码) | 3 |
| 技术选型调研 | medium | 3 Agent(各调研 1 个方案) | 3 |
| Bug 修复(已知原因) | simple | 单 Agent | 1 |
| Bug 修复(未知原因) | complex | 2 Agent 双路排查 | 2 |
| 复杂重构 | very_complex | 2 Agent(1 重构 + 1 验证) | 2 |
| 新功能模块开发 | complex | 3 Agent(前端 + 后端 + 测试) | 3 |
| 端到端功能(页面+API+DB) | very_complex | 3-5 Agent 流水线 | 3-5 |
9.4 自动决策流程
python
async def decide_execution_mode(task: Task, budget: float) -> ExecutionPlan:
"""
自动决定执行模式。
"""
complexity = await complexity_scorer.score(task)
# 预算检查
if complexity.estimated_cost_usd > budget * 0.5:
# 如果预估成本超过预算的 50%,尝试降低复杂度
complexity = await _reduce_complexity(task)
# 生成执行计划
if complexity.level == "simple":
return ExecutionPlan(mode="single", agent_count=1)
elif complexity.level == "medium":
return ExecutionPlan(mode="swarm_small", agent_count=2)
elif complexity.level == "complex":
return ExecutionPlan(mode="swarm_medium", agent_count=3)
else: # very_complex
if budget > 10.0:
return ExecutionPlan(mode="swarm_large", agent_count=5)
else:
# 预算不足,降低并行度
return ExecutionPlan(mode="swarm_medium", agent_count=3)
10. 错误分类与处理规范 (新增)
本章定义 Agent 执行过程中可能遇到的错误类型及标准处理方式。
10.1 错误分类体系
python
class ErrorCategory(Enum):
"""
错误分类:定义所有可处理的错误类型。
"""
# === 可自愈错误(Agent 自动处理)===
TRANSIENT = "TRANSIENT" # 瞬时错误,如网络抖动
RETRYABLE = "RETRYABLE" # 可重试错误,如超时
VALIDATION = "VALIDATION" # 验证失败,如输入不合法
# === 需人工处理错误(创建 HumanTicket)===
RESOURCE = "RESOURCE" # 资源不足,如 API Key 缺失、额度不足
PERMISSION = "PERMISSION" # 权限不足,如禁止路径访问
DECISION = "DECISION" # 需要决策,如技术选型分歧
SECURITY = "SECURITY" # 安全相关,如生产环境变更
# === 不可恢复错误(任务失败)===
UNSUPPORTED = "UNSUPPORTED" # 不支持的功能
TIMEOUT = "TIMEOUT" # 执行超时
CORRUPT = "CORRUPT" # 数据损坏
@dataclass
class ErrorClassification:
category: ErrorCategory
code: str # 具体错误码
message: str # 人类可读的错误描述
retryable: bool # 是否可重试
requires_human: bool # 是否需要人类介入
resolution: str # 解决建议
10.2 错误处理决策树
python
async def handle_error(
error: Exception,
context: ExecutionContext
) -> ErrorResolution:
"""
错误处理决策树。
"""
classification = classify_error(error)
# 可自愈错误:自动重试
if classification.category in [ErrorCategory.TRANSIENT, ErrorCategory.RETRYABLE]:
if classification.retryable and context.attempt < 3:
return ErrorResolution(
action="RETRY",
message=f"自动重试 ({context.attempt + 1}/3)",
backoff_seconds=classification.backoff_seconds
)
else:
# 重试耗尽,标记为失败
return ErrorResolution(
action="FAIL",
message=f"重试 {context.attempt} 次后仍失败: {classification.message}"
)
# 验证失败:诊断并修复
if classification.category == ErrorCategory.VALIDATION:
diagnosis = await _diagnose_validation_error(error, context)
if diagnosis.can_fix:
return ErrorResolution(
action="SELF_FIX",
diagnosis=diagnosis
)
else:
return ErrorResolution(
action="ESCALATE",
reason=diagnosis.reason
)
# 需要人类介入:创建 Ticket
if classification.requires_human:
ticket = await human_ticket_manager.create(
type=classification.human_ticket_type,
title=classification.message,
body=classification.resolution,
urgency=classification.urgency,
blocking_tasks=[context.task_id]
)
return ErrorResolution(
action="PAUSE_WAIT_HUMAN",
ticket_id=ticket.id
)
# 不可恢复错误
return ErrorResolution(
action="FAIL",
message=classification.message
)
10.3 常见错误处理规范
| 错误场景 | 分类 | 处理方式 | 重试策略 |
|---|---|---|---|
| 网络超时 | TRANSIENT | 等 2s 重试 | 最多 3 次 |
| LLM 调用失败 | RETRYABLE | 等 5s 重试 | 最多 3 次 |
| 文件不存在 | VALIDATION | 诊断并重新获取 | 不重试 |
| API Key 缺失 | RESOURCE | 创建 HumanTicket | 不重试 |
| 预算不足 | RESOURCE | 创建 HumanTicket | 不重试 |
| 权限不足 | PERMISSION | 创建 HumanTicket | 不重试 |
| 技术选型分歧 | DECISION | 创建 HumanTicket | 不重试 |
| 执行超时 5min | TIMEOUT | 任务失败 | 不重试 |
| 沙盒崩溃 | TRANSIENT | 重新创建沙盒 | 最多 2 次 |
10.4 错误恢复流程
python
async def error_recovery_loop(
task: Task,
executor: AgentExecutor,
max_attempts: int = 3
) -> TaskResult:
"""
错误自动恢复循环。
"""
for attempt in range(max_attempts):
try:
result = await executor.execute_task(task)
if result.success:
return result
# 失败,分析原因
classification = classify_error(result.error)
if classification.requires_human:
# 需要人类,暂停等待
return result
if classification.retryable and attempt < max_attempts - 1:
# 重试
await asyncio.sleep(classification.backoff_seconds)
continue
# 不可恢复失败
return result
except SandboxCrash:
# 沙盒崩溃,重新创建
if attempt < max_attempts - 1:
executor.sandbox_manager.recreate()
continue
return TaskResult.error("SANDBOX_CRASH", "沙盒连续崩溃")
return TaskResult.error("MAX_ATTEMPTS", f"达到最大重试次数 {max_attempts}")
11. 前端设计:只展示结果,不 micromanage
8.1 设计哲学
| 不展示 | 展示 |
|---|---|
| Agent 内部对话 | 当前进度百分比 |
| Agent 选了什么工具 | 任务完成/失败状态 |
| Agent 之间怎么争论 | 验证是否通过 |
| 每次 LLM 调用 | 成本累计 |
| Worktree 内部文件 | 最终交付物链接 |
8.2 核心页面
任务提交页
bash
┌─────────────────────────────────────────────────────────────┐
│ [Logo] AI AutoDev Team [余额: $47.3] │
├─────────────────────────────────────────────────────────────┤
│ │
│ 新任务 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 描述任务... │ │
│ │ "实现一个支持邮箱验证码的用户注册模块,包含前端表单 │ │
│ │ 和后端 API" │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 约束 (可选) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐│
│ │ 技术栈 │ │ 预算 │ │ 质量标准 ││
│ │ □ Next.js │ │ $ 5 │ │ □ 测试覆盖 ≥ 80% ││
│ │ □ Prisma │ │ │ │ □ 包含 E2E 测试 ││
│ │ □ TypeScript │ │ 时间: 90分钟 │ │ □ 包含 ADR 文档 ││
│ └─────────────┘ └─────────────┘ └─────────────────────────┘│
│ │
│ 安全边界 │
│ ☑ 禁止访问 /etc ☑ 禁止 rm -rf ☑ 禁止 DROP TABLE │
│ │
│ [ 🚀 开始执行 ] │
│ │
└─────────────────────────────────────────────────────────────┘
执行监控页(极简)
less
┌─────────────────────────────────────────────────────────────┐
│ 任务 #1284: 用户注册模块 [⏳ 执行中 | 已用 $2.1] │
├─────────────────────────────────────────────────────────────┤
│ │
│ 进度: ████████████████░░░░ 67% │
│ │
│ 子任务状态: │
│ ✓ 数据库 Schema ✓ 注册 API ⏳ 邮箱集成 │
│ ○ 前端页面 ○ 测试覆盖 │
│ │
│ [ 实时日志 ] [ 交付物 ] [ 验证报告 ] │
│ │
│ --- 实时日志 (最近 5 条) --- │
│ 14:32:01 [OK] T1 数据库验证通过 │
│ 14:32:15 [OK] T2 API 测试通过 (200 OK) │
│ 14:35:22 [INFO] T3 搜索邮件服务: 选中 Resend (免费额度充足) │
│ 14:36:01 [WARN] T3 第一次验证码发送失败,自动重试中... │
│ 14:36:45 [OK] T3 验证码发送成功,正在集成... │
│ │
└─────────────────────────────────────────────────────────────┘
结果报告页
ini
┌─────────────────────────────────────────────────────────────┐
│ 任务 #1284 已完成 ✅ │
├─────────────────────────────────────────────────────────────┤
│ │
│ 交付物 │
│ 📁 代码仓库: git@github.com/.../feat/register-module │
│ 📊 测试报告: 覆盖率 83.2% | 12 passed, 0 failed │
│ 📝 ADR 文档: 为什么选 Resend 而不是 SendGrid │
│ 🖼️ 演示截图: [点击查看] │
│ │
│ 资源消耗 │
│ 费用: $3.2 / $5.0 时间: 47分钟 / 90分钟 │
│ LLM 调用: 23 次 自动修复: 2 次 │
│ │
│ [下载 ZIP] [查看 PR] [部署到预览环境] [标记成功] │
│ │
└─────────────────────────────────────────────────────────────┘
9. 后端架构:极简核心
9.1 核心只有 3 个服务
bash
┌─────────────────────────────────────────────────────────────┐
│ API Gateway (FastAPI) │
│ /mission/create /mission/{id}/status │
│ /mission/{id}/results /health │
├─────────────────────────────────────────────────────────────┤
│ Mission Controller │
│ 接收任务 → 调用 Decomposer → 调度 Agents → 收集结果 │
│ 只做调度,不做任何业务逻辑 │
├─────────────────────────────────────────────────────────────┤
│ Agent Worker Pool │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Agent-1 │ │ Agent-2 │ │ Agent-N │ (动态扩缩容) │
│ │ 自治执行 │ │ 自治执行 │ │ 自治执行 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Verification Engine │
│ 运行验证命令 → 返回通过/失败 → 触发修复或上报 │
├─────────────────────────────────────────────────────────────┤
│ Tool Mesh Gateway │
│ 统一工具接口: MCP + Skills + System Commands + Web Search │
└─────────────────────────────────────────────────────────────┘
9.2 数据模型(极简)
sql
-- 只需要 3 张表
CREATE TABLE missions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
description TEXT NOT NULL,
constraints JSONB NOT NULL DEFAULT '{}',
status VARCHAR(20) DEFAULT 'pending', -- pending/running/completed/failed
result JSONB,
cost_usd DECIMAL(10,4) DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now(),
completed_at TIMESTAMPTZ
);
CREATE TABLE tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
mission_id UUID REFERENCES missions(id),
description TEXT NOT NULL,
deliverable TEXT NOT NULL,
verification_type VARCHAR(50),
verification_command TEXT,
status VARCHAR(20) DEFAULT 'pending',
attempts INTEGER DEFAULT 0,
cost_usd DECIMAL(10,4) DEFAULT 0,
result JSONB
);
CREATE TABLE execution_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
mission_id UUID REFERENCES missions(id),
task_id UUID REFERENCES tasks(id),
level VARCHAR(20), -- INFO/WARN/ERROR/OK
message TEXT,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT now()
);
10. 执行流程(端到端)
css
Human: "实现用户注册模块"
│
▼
┌─────────────────────────────────────┐
│ MissionController.create_mission() │
│ 保存任务,生成 mission_id │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ MissionDecomposer.decompose() │
│ LLM 自主拆解为子任务树 │
│ 每个子任务含验证方式 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ AgentPool.dispatch() │
│ 分配 Agent 执行子任务 │
│ Agent 自己决定怎么做 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Agent 执行循环: │
│ 1. 理解任务 │
│ 2. 搜索需要的信息 │
│ 3. 选工具 │
│ 4. 执行 │
│ 5. 自我验证 │
│ 6. 不通过 → 诊断 → 修复 → 重验 │
│ 7. 通过 → 提交结果 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ VerificationEngine.run_all() │
│ 按任务定义的验证方式自动验证 │
│ 全部通过 → mission 完成 │
│ 有失败 → 返回 Agent 修复 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 生成验收报告 │
│ 通知 Human │
└─────────────────────────────────────┘
11. 与 v1 的关键区别
| v1 (旧) | v2 + Swarm (新) | |
|---|---|---|
| 角色 | 固定 5 人 (PO/TL/Dev/QA/Ops) | 无角色,通用 Agent |
| 流程 | 固定状态机 | 无状态机,任务树 + 蜂群自治 |
| 执行模式 | 单 Agent 串行 | N Agent 蜂群并行,冗余攻击 |
| 通信 | 全透明广播 | 局部通信 + 痕迹标记 (Stigmergy) |
| 共识 | 民主投票 | 涌现共识 (观察实际行为) |
| 拓扑 | 固定结构 | 动态拓扑 (侦察/流水线/突击/守护) |
| 工具 | 预设列表 | 自主发现、评估、获取 |
| 信息 | 全透明广播 | Agent 自主搜索所需信息 |
| 错误 | 重试 3 次/降级 | 蜂群冗余并行 + 自主诊断修复 |
| 技术选型 | 人类指定或民主投票 | 蜂群分散调研,涌现最优 |
| 交付标准 | 人类审查 | 自动验证 + 验收报告 |
| 失败上报 | 进入 BLOCKED | Agent 自主决定 escalate 或继续尝试 |
| 人机协作 | 无,AI 孤岛运行 | 主动求助人类:充值/密钥/决策/审批 |
| 文化/情绪 | 人类社会模拟 | 删除------过度设计,聚焦任务本身 |
12. 风险与应对
| 风险 | 应对 |
|---|---|
| AI 选错工具 | 验证层把关 + 约束系统限制可选范围 |
| AI 陷入循环 | 任务级超时 + 预算上限强制退出 |
| AI 生成不安全代码 | 约束系统禁止危险操作 + 沙盒执行 |
| 验证标准不合理 | 人类审查首次任务的验证定义,后续复用 |
| 成本不可控 | 硬性预算上限,超支强制终止 |
| 产出质量不稳定 | 硬性质量约束(覆盖率、测试通过),不通过不算完成 |
13. 实现路线图
Phase 0: 单 Agent 执行框架验证 (2 周) --- 新增
目标: 验证单 Agent 能在隔离环境中稳定完成任务,不依赖蜂群机制。
核心问题
- Agent 的执行环境(沙盒、权限)是否足够稳定?
- 工具调用(文件读写、命令执行、搜索)是否可靠?
- 验证框架能否捕获常见的失败模式?
- 单 Agent 完成不同类型任务的成功率是多少?
任务清单
- 沙盒容器环境搭建 (Docker)
- Agent 执行引擎基础版 (执行 → 验证 → 上报结果)
- 基础工具接口定义 (Tool Gateway)
- 验证框架 v1 (文件存在、命令退出码 0、curl 返回 200)
- 错误分类体系 (见第 14 章新增内容)
- 状态持久化 (Agent 重启后恢复任务进度)
交付
验证单 Agent 能稳定完成以下 10 种不同类型任务,每种至少成功 3 次:
- 读取 CSV 文件并输出统计
- 编写一个 HTTP API 端点
- 修改现有代码文件中的 bug
- 编写单元测试(覆盖率 ≥ 60%)
- 搜索并理解一个陌生 API 的用法
- 在数据库中创建/查询/删除记录
- 写一个正则表达式处理文本
- 配置一个简单的 CI/CD 步骤
- 生成一个 README 文档
- 重构一个函数的代码风格
验收标准: 10/10 任务类型全部通过,单次任务成本控制在 $0.5 以内。
Phase 1: 单 Agent 自治 (2 周) --- 修订交付物
原交付物"写一个 Python 脚本解析 CSV"过于简单,修订为实际意义的任务。
- 任务提交 + 约束系统
- 单 Agent 自主执行 (搜索 → 选工具 → 执行 → 验证)
- 工具发现层 (扫描本地 Skills/MCP)
- 基础验证框架 (文件存在、命令退出码 0)
交付 : 能自主完成一个完整的 功能模块(如"用户注册模块:后端 API + 前端表单 + 数据库 Schema + 单元测试"),包含:
- 可运行的代码
- 测试覆盖率 ≥ 70%
- 验证通过
- 单次任务成本 ≤ $2.0
前置条件: Phase 0 验收通过后,方可进入 Phase 1。
Phase 2: 蜂群并行 (2 周)
- 去中心化任务板 (Agent 自主认领)
- 蜂群拆解 (3 Agent 同时多角度拆解,取最优)
- 冗余并行执行 (同任务 2-3 Agent 同时做,取先成功)
- 局部通信 + 痕迹标记 (Stigmergy)
交付: 3 Agent 蜂群并行完成 "Next.js 登录页面 + API + 数据库",提速 2x+
Phase 3: 蜂群智能 (2 周)
- 动态拓扑 (侦察/流水线/突击/守护蜂群形态)
- 涌现共识 (技术选型由实际行为自然收敛)
- 蜂群诊断 (Bug 修复多路并行排查)
- 成本权衡 (自动判断何时用蜂群、何时用单 Agent)
交付: 能自主决策 "这个任务值得派蜂群还是单兵"
Phase 4: 生产化 (2 周)
- Web Dashboard (展示蜂群拓扑、Agent 状态、痕迹热图)
- Git 集成 (蜂群并行分支自动合并)
- CI/CD 触发 (GitHub Actions 自动跑验证)
- 预算控制 (蜂群成本上限、自动降级为单 Agent)
交付: 人类在 Web 提交任务,蜂群自动并行攻击,监控面板实时可看,出 PR
14. 数据模型(完整版)
第 9 章是极简概念模型,本章是可直接用于建表的完整设计。
14.1 ER 关系图
ruby
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Mission │ 1:N │ Task │ N:1 │ Agent │
│ (任务批次) │◄─────►│ (子任务) │◄─────►│ (执行单元) │
└──────┬──────┘ └──────┬──────┘ └─────────────┘
│ │
│ 1:N │ 1:N
▼ ▼
┌─────────────┐ ┌─────────────┐
│ HumanTicket │ │StigmergyMark│
│ (人机协作票) │ │ (痕迹标记) │
└─────────────┘ └─────────────┘
│ │
│ N:1 │ N:1
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Swarm │◄─────►│ SwarmAgent │
│ (蜂群实例) │ 1:N │ (蜂群成员) │
└─────────────┘ └─────────────┘
14.2 表结构
mission --- 任务批次
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 任务唯一标识 |
| description | TEXT | 人类输入的任务描述 |
| constraints | JSONB | 完整约束对象(技术栈/预算/时间/质量) |
| acceptance_criteria | JSONB | 验收标准列表 |
| status | VARCHAR(20) | pending/decomposing/running/paused_human/completed/failed |
| swarm_mode | VARCHAR(20) | single/scout/pipeline/striker/guardian |
| budget_usd | DECIMAL(10,4) | 预算上限 |
| spent_usd | DECIMAL(10,4) | 已消耗 |
| started_at | TIMESTAMP | 开始时间 |
| completed_at | TIMESTAMP | 完成时间 |
| human_tickets_count | INT | 产生的人机协作票数 |
| result_summary | TEXT | AI 自动生成的执行总结 |
task --- 子任务
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 子任务 ID |
| mission_id | UUID FK → mission | 所属任务批次 |
| parent_id | UUID FK → task | 父任务(树形结构) |
| description | TEXT | 做什么 |
| deliverable | TEXT | 交付物定义 |
| verification_type | VARCHAR(50) | file_exists/command_exit_0/coverage_threshold/curl_200/e2e_pass |
| verification_command | TEXT | 验证命令 |
| verification_expected | TEXT | 预期结果 |
| status | VARCHAR(20) | pending/claimed/running/paused_human/completed/failed/abandoned |
| claimed_by | UUID FK → agent | 认领者 |
| dependencies | UUID[] | 依赖的其他 task_id |
| estimated_cost_usd | DECIMAL(10,4) | 预估成本 |
| actual_cost_usd | DECIMAL(10,4) | 实际成本 |
| attempts | INT | 尝试次数 |
| created_at | TIMESTAMP | 创建时间 |
| completed_at | TIMESTAMP | 完成时间 |
| error_log | TEXT | 最后一次错误信息 |
agent --- 执行单元
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | Agent 唯一标识 |
| status | VARCHAR(20) | idle/running/waiting_human/error/terminated |
| capabilities | JSONB | {"react": 0.8, "sql": 0.6, "docker": 0.9} |
| current_task_id | UUID FK → task | 当前执行任务 |
| swarm_id | UUID FK → swarm | 所属蜂群 |
| model_tier | VARCHAR(20) | claude/gpt4o/gpt4o-mini(可动态降级) |
| lifetime_cost_usd | DECIMAL(10,4) | 累计消耗 |
| session_start | TIMESTAMP | 本次会话开始 |
| last_heartbeat | TIMESTAMP | 最后心跳 |
| ip_address | VARCHAR(50) | 沙盒容器 IP |
| container_id | VARCHAR(100) | Docker 容器 ID |
swarm --- 蜂群实例
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 蜂群 ID |
| mission_id | UUID FK → mission | 所属任务 |
| topology | VARCHAR(20) | scout/pipeline/striker/guardian |
| agent_count | INT | Agent 数量 |
| sync_interval_sec | INT | 同步间隔 |
| status | VARCHAR(20) | forming/running/syncing/dissolved |
| formed_at | TIMESTAMP | 组建时间 |
| dissolved_at | TIMESTAMP | 解散时间 |
swarm_agent --- 蜂群成员关系
| 字段 | 类型 | 说明 |
|---|---|---|
| swarm_id | UUID FK → swarm | 蜂群 ID |
| agent_id | UUID FK → agent | Agent ID |
| role_in_swarm | VARCHAR(20) | explorer/builder/verifier/coordinator(动态角色) |
| joined_at | TIMESTAMP | 加入时间 |
| left_at | TIMESTAMP | 离开时间 |
| tasks_completed | INT | 在蜂群中完成的任务数 |
| PK: (swarm_id, agent_id) |
human_ticket --- 人机协作票
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 票号 |
| mission_id | UUID FK → mission | 所属任务 |
| task_id | UUID FK → task | 触发此票的任务(可为空) |
| type | VARCHAR(20) | api_key/recharge/decision/security_approval/info_request |
| title | TEXT | 标题 |
| body | TEXT | 详细说明(Markdown) |
| urgency | VARCHAR(20) | low/medium/high/critical |
| status | VARCHAR(20) | pending/notified/responded/resolved/expired |
| blocking_tasks | UUID[] | 被阻塞的任务列表 |
| action_type | VARCHAR(20) | input/click/select/approve |
| input_schema | JSONB | 如果需要输入,定义字段 |
| options | TEXT[] | 如果是选择,提供选项 |
| fallback | TEXT | 超时后的自动 fallback 行为 |
| deadline | TIMESTAMP | 截止时间 |
| response | JSONB | 人类的响应内容 |
| responded_at | TIMESTAMP | 响应时间 |
| created_at | TIMESTAMP | 创建时间 |
stigmergy_mark --- 痕迹标记
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 标记 ID |
| mission_id | UUID FK → mission | 所属任务(全局痕迹可为空) |
| agent_id | UUID FK → agent | 留下痕迹的 Agent |
| location | TEXT | 位置(文件路径/API/工具名) |
| type | VARCHAR(20) | good_path/bad_path/caution/tip |
| content | TEXT | 痕迹内容 |
| strength | DECIMAL(3,2) | 强度 0.0-1.0 |
| decay_rate | DECIMAL(3,2) | 衰减率(默认 0.9/小时) |
| created_at | TIMESTAMP | 创建时间 |
| expires_at | TIMESTAMP | 过期时间 |
tool_catalog --- 工具目录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 工具 ID |
| name | VARCHAR(100) | 工具名 |
| source | VARCHAR(20) | skill/mcp/system/pypi/npm/github |
| install_spec | TEXT | 安装方式(pip install / npm install / git clone) |
| capabilities | JSONB | 功能描述(LLM 可理解的语义) |
| usage_example | TEXT | 使用示例 |
| cost_per_call | DECIMAL(10,6) | 单次调用成本 |
| reliability_score | DECIMAL(3,2) | 可靠性评分(0-1,基于历史) |
| last_used_at | TIMESTAMP | 最后使用时间 |
| success_rate | DECIMAL(5,2) | 历史成功率(%) |
execution_log --- 执行日志
| 字段 | 类型 | 说明 |
|---|---|---|
| id | UUID PK | 日志 ID |
| mission_id | UUID FK → mission | 所属任务 |
| task_id | UUID FK → task | 所属子任务 |
| agent_id | UUID FK → agent | 执行 Agent |
| level | VARCHAR(20) | INFO/WARN/ERROR/OK/HUMAN |
| message | TEXT | 日志内容 |
| cost_usd | DECIMAL(10,6) | 本步消耗 |
| tokens_in | INT | 输入 token 数 |
| tokens_out | INT | 输出 token 数 |
| model | VARCHAR(50) | 使用的模型 |
| created_at | TIMESTAMP | 时间戳 |
14.3 索引设计
sql
-- 任务查询优化
CREATE INDEX idx_task_mission_status ON task(mission_id, status);
CREATE INDEX idx_task_claimed_by ON task(claimed_by) WHERE claimed_by IS NOT NULL;
-- 蜂群活跃查询
CREATE INDEX idx_agent_status_swarm ON agent(status, swarm_id);
CREATE INDEX idx_agent_heartbeat ON agent(last_heartbeat) WHERE status = 'running';
-- 人机协作
CREATE INDEX idx_ticket_status_deadline ON human_ticket(status, deadline)
WHERE status IN ('pending', 'notified');
-- 痕迹搜索
CREATE INDEX idx_mark_location ON stigmergy_mark(location);
CREATE INDEX idx_mark_mission_type ON stigmergy_mark(mission_id, type);
-- 日志时序
CREATE INDEX idx_log_mission_time ON execution_log(mission_id, created_at DESC);
15. 部署与运维架构
15.1 开发环境:Docker Compose
yaml
# docker-compose.dev.yml
version: "3.8"
services:
api:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://aadev:aadev@postgres:5432/aadev
- REDIS_URL=redis://redis:6379
- LITELLM_PROXY_URL=http://litellm:4000
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
volumes:
- ./workspace:/app/workspace # 代码产出挂载到宿主机
- /var/run/docker.sock:/var/run/docker.sock # Agent 启动沙盒容器
depends_on:
- postgres
- redis
- litellm
dashboard:
build: ./web
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://localhost:8000
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: aadev
POSTGRES_PASSWORD: aadev
POSTGRES_DB: aadev
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
litellm:
image: ghcr.io/berriai/litellm:latest
ports:
- "4000:4000"
environment:
- LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY}
volumes:
- ./litellm-config.yaml:/app/config.yaml
command: ["--config", "/app/config.yaml"]
# 可选:ChromaDB 用于向量检索(代码相似度)
chroma:
image: chromadb/chroma:latest
ports:
- "8001:8000"
volumes:
- chromadata:/chroma/chroma
volumes:
pgdata:
chromadata:
15.2 生产环境:Kubernetes
yaml
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: aadev
---
# k8s/api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aadev-api
namespace: aadev
spec:
replicas: 2 # API 无状态,可水平扩展
selector:
matchLabels:
app: aadev-api
template:
metadata:
labels:
app: aadev-api
spec:
serviceAccountName: aadev-agent # 允许启动沙盒 Pod
containers:
- name: api
image: aadev/api:latest
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: aadev-secrets
key: database-url
- name: REDIS_URL
valueFrom:
configMapKeyRef:
name: aadev-config
key: redis-url
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock # 或配置 containerd
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
---
# k8s/agent-sandbox.yaml
# Agent 沙盒以独立 Pod 运行,资源隔离
apiVersion: v1
kind: Pod
metadata:
generateName: aadev-agent-
namespace: aadev
spec:
restartPolicy: Never
containers:
- name: agent
image: aadev/agent-sandbox:latest
resources:
limits:
memory: "1Gi"
cpu: "1000m"
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
runAsNonRoot: true
15.3 监控体系
指标采集(Prometheus)
yaml
# prometheus.yml
scrape_configs:
- job_name: 'aadev-api'
static_configs:
- targets: ['aadev-api:8000']
metrics_path: /metrics
scrape_interval: 15s
- job_name: 'aadev-agents'
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- aadev
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: aadev-agent
action: keep
关键监控指标
| 指标 | 类型 | 告警阈值 | 含义 |
|---|---|---|---|
aadev_mission_duration_seconds |
Histogram | P99 > 2h | 任务执行时间 |
aadev_agent_cost_usd |
Counter | 单个 > $5/小时 | Agent 消费速度 |
aadev_budget_utilization |
Gauge | > 80% | 预算使用率 |
aadev_task_failure_rate |
Gauge | > 30% | 任务失败率 |
aadev_human_ticket_pending |
Gauge | > 5 | 积压的人机协作票 |
aadev_agent_heartbeat_age |
Gauge | > 5min | Agent 心跳延迟 |
aadev_swarm_sync_duration |
Histogram | P99 > 30s | 蜂群同步耗时 |
aadev_stigmergy_mark_count |
Counter | --- | 痕迹标记数量 |
aadev_tool_call_latency |
Histogram | P99 > 10s | 工具调用延迟 |
Grafana 面板设计
less
┌─────────────────────────────────────────────────────────────────┐
│ 🐝 AAT 蜂群监控 Dashboard │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 活跃任务 │ │ 活跃Agent │ │ 待处理 │ │ 今日消费 │ │
│ │ 12 │ │ 8/20 │ │ 3 票 │ │ $47.3 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 蜂群拓扑实时图 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ [Mission-1284] 用户注册模块 │ │
│ │ │ │
│ │ ┌───┐ ┌───┐ ┌───┐ │ │
│ │ │A-1│◄────►│A-2│◄────►│A-3│ Scout Swarm │ │
│ │ └─┬─┘ └─┬─┘ └─┬─┘ │ │
│ │ │ T1:done │ T2:run │ T3:run │ │
│ │ ▼ ▼ ▼ │ │
│ │ [DB表] [API端点] [邮件集成] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 任务流水线 │
│ Mission-1284: ████████████░░░░ 67% ($3.2/$5.0) │
│ ├─ T1 设计数据库 [████████████done] $0.2 │
│ ├─ T2 API实现 [████████░░░░run] $0.8 │
│ ├─ T3 邮件集成 [████████░░░░run] $1.2 ⚠️ waiting_human │
│ └─ T4 前端页面 [░░░░░░░░░░░░pend] $0.0 │
│ │
│ 成本趋势 (24h) │
│ $ ████████████████████░░░░░░░░░░ 峰值: $12.3 (14:00) │
│ │
│ 人机协作队列 │
│ 🔴 API Key 配置 | 15min前 | 阻塞2任务 | [处理] │
│ 🟡 数据库选型 | 32min前 | 阻塞1任务 | [处理] │
│ │
└─────────────────────────────────────────────────────────────────┘
15.4 日志系统(Loki)
yaml
# 日志标签规范
# 所有 Agent 日志统一格式:
{
"timestamp": "2026-05-08T14:32:01Z",
"level": "INFO",
"mission_id": "uuid",
"task_id": "uuid",
"agent_id": "A-3",
"swarm_id": "uuid",
"event": "tool_selected",
"message": "选中 Resend 邮件服务",
"cost_usd": 0.002,
"tokens_in": 1200,
"tokens_out": 350,
"model": "claude-3-5-sonnet",
"trace_id": "uuid" # 分布式追踪
}
15.5 告警规则
yaml
# alertmanager-rules.yaml
groups:
- name: aadev-budget
rules:
- alert: BudgetCritical
expr: aadev_budget_utilization > 0.9
for: 2m
labels:
severity: critical
annotations:
summary: "预算即将耗尽"
description: "Mission {{ $labels.mission_id }} 预算使用率 {{ $value | humanizePercentage }}"
- name: aadev-agent
rules:
- alert: AgentDown
expr: aadev_agent_heartbeat_age > 300
for: 1m
labels:
severity: warning
annotations:
summary: "Agent 心跳丢失"
- name: aadev-human
rules:
- alert: HumanTicketStalled
expr: aadev_human_ticket_pending > 0 <and> time() - human_ticket_created_at > 3600
for: 5m
labels:
severity: warning
annotations:
summary: "人机协作票积压超过1小时"
15.6 运维 SOP
| 场景 | 操作 |
|---|---|
| API 额度耗尽 | Dashboard 自动触发 HumanTicket,同时降级到 gpt-4o-mini |
| Agent 沙盒崩溃 | K8s 自动重启 Pod,任务重新进入任务板 |
| 数据库连接池耗尽 | 限制并发 Agent 数,自动扩容 Postgres 连接池 |
| 人类长时间未响应 | 执行 fallback 策略(降级/跳过/免费替代方案) |
| 蜂群分裂(Agent 失联) | 自动重分配任务到其他 Agent,标记失联 Agent 为 dead |
| 磁盘满(代码产出) | 自动清理 7 天前的临时工作区,保留最终交付物 |
附录
A. 输入输出协议
typescript
// 人类输入
interface MissionInput {
description: string; // 自然语言任务描述
constraints?: {
tech_stack?: string[]; // 允许的技术栈
budget_usd?: number; // 预算上限
time_limit_minutes?: number; // 时间上限
quality?: {
min_test_coverage?: number;
required_deliverables?: string[];
};
security?: {
forbidden_operations?: string[];
forbidden_paths?: string[];
};
scope?: {
in?: string[]; // 必须包含
out?: string[]; // 明确排除
};
};
}
// 系统输出
interface MissionResult {
status: "completed" | "failed" | "escalated";
tasks: TaskResult[];
total_cost_usd: number;
total_time_minutes: number;
deliverables: {
code_url?: string;
test_report?: string;
coverage_percent?: number;
adr_documents?: string[];
};
execution_summary: string; // AI 生成的执行总结
}
B. 目录结构
ini
aadev-v2/
├── api/
│ ├── main.py # FastAPI 入口
│ ├── missions.py # 任务 API
│ └── verification.py # 验证 API
├── core/
│ ├── decomposer.py # 任务拆解
│ ├── controller.py # Mission 控制器
│ └── verifier.py # 验证引擎
├── agent/
│ ├── worker.py # Agent 执行单元
│ ├── autonomy.py # 自治协议
│ └── search.py # 自主搜索
├── toolmesh/
│ ├── discovery.py # 工具发现
│ ├── selector.py # 工具选择
│ ├── acquisition.py # 工具获取
│ └── gateway.py # 统一网关 (MCP/Skills/System)
├── constraints/
│ └── enforcer.py # 约束检查
├── sandbox/
│ └── docker_runner.py # Docker 沙盒
├── web/
│ └── [Next.js Dashboard]
└── tests/
└── e2e/
结语 : v2 + Swarm 的核心是 "自治 + 并行涌现 + 人机协作"。人类只定义"要什么"和"不能做什么"。AI 蜂群自主决定"怎么做"、"谁来做"、"并行还是串行"。当遇到资金、密钥、决策、审批等必须人类介入的事,AI 会主动、清晰地求助,而非硬撑或静默失败。验证是唯一的硬契约------不通过就不算完成。蜂群用 2-3x 成本换 2-4x 速度,紧急任务全蜂群出击,简单任务单兵搞定。