Day 03 · 路径 B

Monorepo 接入 · 每步改什么、怎么改

仓库根 gov-agents-platform/ · 新 agent 在 apps/release-notes-bot/ · Python 包 release_notes_bot(示例名)。业务节点改法同 Day 02 步骤 4

1

生成脚手架

在 monorepo 根执行
cd gov-agents-platform
uv sync --all-packages
uv run agentctl new agent release-notes-bot \
  --pattern supervisor \
  --specialists "diff_sp,changelog_sp" \
  --critic both

生成后应出现(builder.py 在包根,不在 nodes/):

apps/release-notes-bot/
├── pyproject.toml
├── evals/golden.jsonl
├── tests/test_smoke.py
└── release_notes_bot/
    ├── builder.py
    ├── state.py
    ├── server.py
    ├── specialists.py   # 或 specialists/ 目录
    └── nodes/ …
2

注册到平台(3 个文件)

① gov-agents-platform/pyproject.toml

[tool.uv.workspace] members 数组末尾加一行(若 agentctl 没自动加):

"apps/release-notes-bot",

② gov-agents-platform/packages/gov-agents-server/src/gov_agents_server/main.py

AGENT_REGISTRY dict 里加:

"release-notes-bot": ("release_notes_bot.server", "build_router"),

AGENT_META dict 里加:

"release-notes-bot": {
    "title": "Release Notes Bot",
    "subtitle": "从 diff 生成发布说明",
    "prefix": "/agents/release-notes-bot",
},

③ apps/release-notes-bot/pyproject.toml

确认 BOM extras 符合 pattern,例如:

dependencies = [
    "ai-trust-toolkit-bom[core,supervisor]==0.6.0",
    ...
]
[tool.uv.sources]
ai-trust-toolkit-bom = { workspace = true }
uv sync --all-packages 无报错
3

改业务文件(与独立仓相同思路)

改什么文件路径怎么改
Promptapps/.../release_notes_bot/prompts/*.md写业务 prompt · 顶部第一行加关键词供 FakeLLM 匹配
Specialist 逻辑apps/.../release_notes_bot/specialists.pyspecialists/diff_sp.py改 SP 函数体 · LLM 走 get_llm(tier="auto")
共享字段apps/.../release_notes_bot/state.py加 TypedDict 字段
串图apps/.../release_notes_bot/builder.pyadd_node / add_edge · 不在 nodes/ 下
单节点逻辑apps/.../release_notes_bot/nodes/*.py参考 Day 02 的 run_node 写法

详细 before/after 代码 → Day 02 步骤 4

4

改 server.py(Monorepo 特有)

apps/release-notes-bot/release_notes_bot/server.py

脚手架通常已生成 build_v1_router。你要改的是请求/响应映射三处:

  1. MyAgentRequest — 定义 HTTP body 字段(例 target: str
  2. _initial_state(req) — 把 request 转成 graph 初始 state
  3. _final_to_result(final) — 把 graph 输出转成 envelope.result 字段

示例(在现有 server.py 里找到对应函数改):

class ReleaseNotesRequest(BaseModel):
    repo: str
    since_tag: str = "main"

def _initial_state(req: ReleaseNotesRequest) -> dict:
    return {"repo": req.repo, "since_tag": req.since_tag, "retry_count": 0}

def _final_to_result(final: dict) -> dict:
    return {
        "repo": final.get("repo", ""),
        "release_notes": final.get("output", ""),
        "critic_passed": bool(final.get("critique_passed", True)),
    }

❌ 不要新增 @router.post("/agents/.../run") 手写路由。

5

评测样本 + 测试

apps/release-notes-bot/evals/golden.jsonl

每行一条 JSON,至少 3 条(建议 20+):

{"sample_id":"r-001","input":{"repo":"payment-svc","since_tag":"v1.0"},"ground_truth":{"has_notes":true},"tags":["smoke"]}

apps/release-notes-bot/tests/test_smoke.py

用 FakeLLM 测,不真调外网 LLM(模板通常已有,补断言即可)。

uv run pytest apps/release-notes-bot/tests/ -q
6

e2e 跑通

uv run uvicorn gov_agents_server.main:app --host 127.0.0.1 --port 8080

export PLATFORM_BASE_URL=http://127.0.0.1:8080
export AGENTCTL_USER_ID=dev
uv run agentctl invoke release-notes-bot --data='{"repo":"demo","since_tag":"main"}'
✅ 返回 JSON envelope,含 case_idstatusresult