diff --git a/docs/design/21-unified-toolchain-design.md b/docs/design/21-unified-toolchain-design.md index 3da4e2a..9efc934 100644 --- a/docs/design/21-unified-toolchain-design.md +++ b/docs/design/21-unified-toolchain-design.md @@ -612,23 +612,52 @@ issue_closed 走 auto-pass(和 review_merged 一样),纯通知不需要 ag → 每个 agent 收到 DISCUSSION_PROMPT_TEMPLATE ``` -agent 收到的 discussion prompt(与现有 spawner.py DISCUSSION_PROMPT_TEMPLATE 一致): +### 13.2 Discussion Prompt 设计(v3 重构) + +**设计参考**:Edict(角色驱动主动发言)+ APM(自包含 Task Prompt)+ PAV 循环(输入/输出/验证)。 + +当前问题:DISCUSSION_PROMPT 只列了"你可以做什么",没引导 agent 思考"我和这个需求什么关系"。agent 读完和自己没关系就忽略了。 + +重构后 discussion prompt: ``` 你被 spawn 来参与 Gitea Issue 讨论。这是一个四相循环的讨论环节。 -## 你的任务 -{parent Issue body — goal} +## 讨论主题 +{parent Issue body 全文} -## Issue API(Gitea) -你可以随时: +## 你是谁 +你是 {agent_id}({display_name}),你的角色是 {role},你的专业能力是 {capabilities}。 +(如:你是 zhangfei-dev(张飞 翼德),角色是编码先锋,能力是编码/脚本/实现) + +## 你必须做什么 + +读完需求后,在 Issue 上 comment 回应(必须,不是可选): + +1.【定位】这个需求和你有什么关系?你的专业能力能贡献什么? +2.【建议】你对实现方案有什么建议?(技术选型、数据来源、实现路径) +3.【认领】如果你需要参与,创建 sub Issue 并在 parent Issue comment 注册: + - 创建 sub Issue:POST /repos/{repo}/issues + title: "[repo][sub][parent #{N}] 任务名" + body: "Parent: #{N}\nDepends: #M (如果有前序依赖)\n## 任务\n..." + assignees: ["{你的 agent_id}"] + - 创建后在 parent Issue comment:"[{你的角色名}] 我创建了 sub #{M}: {任务名},我负责 {简述}" +4.【风险】如果你发现风险、不合理的假设、或遗漏的环节,直接提出 + +⚠️ 每个 agent 必须 comment。即使你认为和自己无关,也要说明原因——这证明你读过并思考过了。不 comment 的 agent 会被视为未参与讨论。 + +## Comment 格式 +你的 comment 必须以角色名开头,让其他人知道你是谁: +[{角色名}] {你的观点} +例:[张飞] 我来负责策略编码,用 vnpy CtaTemplate 实现。 +例:[关羽] 这个策略需要风控,连亏 3 天应暂停。 +例:[赵云] 数据已就绪,2024-08 缺失已补齐。 +例:[姜维] 我与此需求无直接关系,但建议关注回测滑点设置。 + +## API(Gitea) - 读 Issue 详情+comments:GET /repos/{repo}/issues/{N} - 写 comment:POST /repos/{repo}/issues/{N}/comments - body: {"body": "内容(@agent-id 自动路由)"} - 创建 sub Issue:POST /repos/{repo}/issues - title: "[repo][sub][parent #{N}] 任务名" - body: "Parent: #{N}\n## 任务\n..." - assignees: ["自己"] ## 行为准则 1. 你是自主的。读 Issue、思考、行动,不要等指令。 @@ -637,18 +666,23 @@ agent 收到的 discussion prompt(与现有 spawner.py DISCUSSION_PROMPT_TEMPL 4. 产出可共享。产出写入 Issue comment,让其他人能看到你的成果(Cohesion)。 5. 不越界。安全红线不要碰,超出能力的 @ 庞统升级(Boundary)。 6. 随时讨论。执行过程中需要协作时 @ 对应 Agent,讨论是灵活的不是固定阶段的。 - -## 讨论完成后 -- 如果讨论收敛到可执行的任务,直接创建 sub Issue -- 如果有分歧或不确定,在 Issue 上 comment @ 庞统裁决 -- 如果庞统在 parent Issue 中 @ 了你认领特定任务,优先响应 ``` -**与现有实现差异**:API 从黑板 API(localhost:8083)改为 Gitea API。行为准则(Boids 四条)完全不变。 +**与现有实现差异**: +1. 新增"你是谁"段——agent 知道自己的角色和能力,有定位感 +2. 新增"你必须做什么"——4 条必须回应的维度,不是可选 +3. 新增 comment 格式——以角色名开头,其他人知道是谁在说 +4. 新增"创建 sub 后在 parent comment 注册"——parent Issue comment 流自然包含所有 agent 的表态和分工 +5. 底线约束:不 comment = 未参与——强制每个 agent 思考和表态 -### 13.2 庞统初始引导 +**输入/输出/验证标准**(PAV 循环): +| 阶段 | 输入 | 输出 | 验证 | +|------|------|------|------| +| Discussion | parent Issue body(goal)| 每个 agent 的 comment(定位+建议+认领+风险)| 所有被 spawn 的 agent 都 comment 了 | -庞统创建 parent Issue 时,可以在 Issue body 或 comment 中 @ 特定 agent 引导认领: +### 13.3 庞统初始引导 + +庞统创建 parent Issue 时,可以在 Issue body 中 @ 特定 agent 引导认领: ``` Issue body: @@ -658,11 +692,52 @@ Issue body: ## 建议分工 @zhangfei-dev 你来认领策略编码 @zhaoyun-data 你来认领数据准备 - 其他需要补充的请大家自主认领 ``` 但庞统不需要知道全部——关羽可能发现需要风控,自己创建 sub 去做。司马懿可能发现需要测试,自己创建 sub。**这是涌现,不是分配。** +### 13.4 Parent Issue 中的 sub 注册 + +agent 创建 sub Issue 后,**自己在 parent Issue 上 comment 注册**(不需要 daemon 做): + +``` +[张飞] 我创建了 sub #101: 策略编码,我来负责实现。 +技术方案:用 vnpy CtaTemplate,金叉买入死叉卖出。 +``` + +Gitea 的 Issue reference 功能会自动在 parent Issue timeline 显示 "Referenced by #N"。 +agent 的 comment + Gitea 自动引用 = parent Issue 中有完整的 sub 注册信息。 + +### 13.5 分支创建时机 + +| 阶段 | 谁创建分支? | 分支名 | +|------|-----------|-------| +| Discussion(Phase 3) | ❌ 不创建分支 | — | +| Executor(Phase 4) | agent 收到 executor prompt 后自己创建 | `{type}/{sub_issue_number}-{brief}`(type 按 Issue 类型:fix/feat/impl/docs/refactor/test) | + +**executor prompt 的 steps 中明确指定分支名**: +``` +git checkout -b fix/{issue_number}-{brief} +``` + +多分支并行场景(每个 sub Issue number 不同,分支名不同,不冲突): +``` +张飞 sub #101 → 分支 fix/101-dual-ma-strategy +关羽 sub #102 → 分支 fix/102-risk-control +司马懿 sub #103 → 分支 fix/103-strategy-test +``` + +### 13.6 L2 输入输出约束(PAV 循环) + +每种 prompt 都有明确的输入/输出/验证标准: + +| prompt 类型 | 输入 | 输出 | 验证 | +|------------|------|------|------| +| Discussion | parent Issue body(goal)| 每个 agent comment(定位+建议+认领+风险)| 所有 spawn 的 agent 都 comment 了 | +| Executor | sub Issue body + parent Issue body + 所有 comments | [Action Report](分支+PR+改动+CI)| PR 创建 + CI 通过 | +| Review(司马懿)| PR diff + sub Issue body + parent goal | Review verdict(APPROVE/REQUEST_CHANGES)| Review API 提交 | +| Round Review(庞统)| parent Issue body + 所有 sub outputs + 所有 comments | 三问评估(goal 一致性/成果覆盖/下一步)| GOAL_ACHIEVED 或新轮 sub | + --- ## §14. Agent 自建 sub Issue 模式 @@ -722,6 +797,138 @@ daemon 监听 Issue 创建 webhook → 解析标题中的 `[parent #N]` → 记 --- +## §14b. 分支与 PR 生命周期管理 + +> 解决分支、PR、Issue 之间的割裂问题,统一定义完整生命周期。 + +### 14b.1 Sub Issue 的分支/PR 生命周期 + +``` +① 创建 Sub Issue + Agent 在 discussion 阶段创建 sub Issue(assign 自己) + → 分支:还不存在 + → daemon task_state: status=pending, parent_issue=N + +② 分支创建(executor 阶段) + Agent 收到 executor prompt → git checkout -b {type}/{sub_issue_number}-{brief} + → 分支名从 sub Issue number 派生,一一对应 + → daemon task_state: status=working(通过 dispatch 触发) + +③ 编码 + Agent 在分支上编码 → commit → push + → 分支远程存在,Gitea 可见 + +④ PR 创建 + Agent 创建 PR(head: {type}/{sub_issue_number}-{brief} → base: main) + PR body 必须包含: + - `Closes #{sub_issue_number}`(让 Gitea merge 时自动关 sub Issue) + - `Parent: #{parent_issue_number}`(关联到 parent) + - 改动说明(改了什么、为什么) + → webhook: pull_request/opened → daemon task_state: status=review + +⑤ CI + PR 创建 → CI 自动触发(lint + test + frontend) + → 通过:等 Review + → 失败:toolchain handler 创建 ci_failure task → agent 修复 → push 到同分支 → CI 重跑 + +⑥ Review + 司马懿收到 Review 请求 → 读 PR diff → 提交 Review(Review API) + → APPROVED:通知 agent 合并 + → REQUEST_CHANGES:通知 agent 修改 + +⑦ 修改(如果有) + Agent 在同分支上修改 → commit → push + → PR 自动更新(不新建 PR) + → CI 重跑 → 司马懿重新 Review + → 循环回到 ⑥ + +⑧ Merge + Agent 或 Reviewer merge PR + → Gitea 自动关闭 sub Issue(因为 PR body 有 Closes #N) + → webhook: pull_request/closed(merged=true) + → daemon 终态信号:task_state status=done + +⑨ 分支清理 + Gitea 配置自动删除已合并分支(推荐) + Issue 保持 closed 状态(完整历史保留) +``` + +### 14b.2 Parent Issue 的生命周期 + +``` +① 创建(庞统) + 庞统创建 parent Issue(无 assignee) + → 触发 discussion 广播 + → parent Issue 不创建分支(parent 是讨论和编排层) + +② Discussion + Agents 讨论、创建 sub Issues、在 parent comment 注册 + +③ 执行 + 所有 sub Issues 走 §14b.1 生命周期 + +④ Round Review + 所有 sub Issues 终态 → 庞统三问 + → GOAL_ACHIEVED → 庞统关闭 parent Issue + → 需要新轮 → 庞统创建新 sub Issues → 回到 ③ + +⑤ 关闭 + 庞统关闭 parent Issue + → webhook: issues/closed → daemon 终态 +``` + +### 14b.3 核心规则 + +| 规则 | 定义 | 原因 | +|------|------|------| +| 分支 : sub Issue = 1:1 | 每个 sub Issue 一个分支 | 分支名从 Issue number 派生 | +| 分支 : PR = 1:1 | 每个分支一个 PR | Review 驳回不新建 PR,push 到同分支更新 | +| sub Issue : PR = 1:1 | 一个 sub Issue 一个 PR | 简单场景。复杂 sub 按需拆多个 sub Issue | +| PR body 必须含 Closes #N | N = sub Issue 编号 | merge 后自动关 Issue | +| PR body 必须含 Parent #M | M = parent Issue 编号 | 关联到 parent,方便追溯 | +| parent Issue 不创建分支 | parent 是讨论编排层 | 代码产出在 sub Issue 的分支 | +| discussion 不碰 git | 只读 Issue + comment + 创建 sub | 避免讨论阶段产生无意义 commit | +| 分支名格式 | {type}/{sub_issue_number}-{brief} | 按 Issue 类型:fix/feat/impl/docs/refactor/test | +| merge 后自动删分支 | Gitea 配置 | 避免分支堆积 | + +### 14b.4 多分支并行场景 + +一个 parent Issue 下多个 sub Issue 同时执行: + +``` +parent Issue #100(双均线策略) + ├── sub #101 策略编码 → 分支 feat/101-dual-ma → PR #104 + │ └── CI 跑 + Review → merge → Closes #101 + ├── sub #102 风控规则 → 分支 feat/102-risk-control → PR #105 + │ └── CI 跑 + Review → merge → Closes #102 + └── sub #103 策略测试 → 分支 test/103-strategy-test → PR #106 + └── CI 跑 + Review → merge → Closes #103 + +所有 sub 终态 → 庞统 round review → parent Issue #100 关闭 +``` + +每个 sub Issue 的分支、PR、CI、Review 独立流转,互不干扰。 + +### 14b.5 PR body 模板 + +```markdown +Closes #{sub_issue_number} +Parent: #{parent_issue_number} + +## 改动说明 +<改了什么、为什么> + +## 验证 +- [ ] CI 通过(lint + test) +- [ ] 本地测试通过(如有) + +## 改动文件 +- `src/xxx.py`: <改了什么> +- `tests/test_xxx.py`: <新增什么测试> +``` + +--- + ## §15. @mention 通知迁移 ### 15.1 当前实现