|
| 1 | +# ADR-010: agentic-runner 作为可选启动模式 |
| 2 | + |
| 3 | +**状态**: Accepted (v0.2.2 落地, 2026-06) |
| 4 | +**关联**: `src/dbjavagenix/server/agentic_runner.py` |
| 5 | +**前置**: [ADR-008](008-mcp-v3-elicitation-sampling.md) (sampling 解耦 LLM) |
| 6 | + |
| 7 | +## 背景 |
| 8 | + |
| 9 | +DBJavaGenix 自始 (v0.1, 2025-09) 只有一种启动模式 — **MCP server**: |
| 10 | +被动等待 Claude Desktop / Cursor / Continue.dev 等客户端发起 tool 调用。 |
| 11 | + |
| 12 | +实际有些使用场景需要 "主动" agent: |
| 13 | + |
| 14 | +1. **批处理 / 一次性任务**: |
| 15 | + "扫描 host=X 数据库,生成代码到 ./out,然后退出" |
| 16 | + 走 MCP server 需要打开客户端、连接、手动一个个调 tool,8-10 步操作。 |
| 17 | + |
| 18 | +2. **CI / 自动化**: |
| 19 | + 流水线里夜间任务,根据线上 schema diff 重新生成 entity。 |
| 20 | + 无人值守环境没有 Claude Desktop UI。 |
| 21 | + |
| 22 | +3. **教学 / demo**: |
| 23 | + 面试或介绍项目时,想 1 行命令展示 "同样的 tools 既能服务客户端,也能服务 agent"。 |
| 24 | + |
| 25 | +Claude Agent SDK (2025-09-29 发布,2026-Q1 GA) 提供了 |
| 26 | +"agent loop + hooks + subagents + MCP tools 注入" 的标准框架,正好填这个空。 |
| 27 | + |
| 28 | +## 决定 |
| 29 | + |
| 30 | +新增 `src/dbjavagenix/server/agentic_runner.py` 作为 **第二种启动模式**: |
| 31 | + |
| 32 | +| 维度 | mcp_server | agentic_runner | |
| 33 | +|------|-----------|----------------| |
| 34 | +| 触发 | 客户端连接 | CLI 单次启动 | |
| 35 | +| 控制权 | 客户端 LLM | runner 内嵌 Claude Opus 4.7 | |
| 36 | +| 工具来源 | mcp_tools 注册表 | **同一个注册表 (zero duplication)** | |
| 37 | +| 用户交互 | 实时 | 启动时给 goal,跑完返回结果 | |
| 38 | +| 依赖 | 无额外 | `claude-agent-sdk` + `ANTHROPIC_API_KEY` | |
| 39 | + |
| 40 | +关键设计: |
| 41 | +1. **同一 tools 注册表** — `_default_tool_registry()` lazy import `database.mcp_tools`, |
| 42 | + 两种模式行为完全一致 |
| 43 | +2. **优雅降级** — `is_agentic_available()` 探测 SDK + API key,缺任一即返回结构化 |
| 44 | + 错误而不是抛异常 |
| 45 | +3. **dry_run 模式** — 不调 LLM 只打印 plan,CI 验证配置正确性时用 |
| 46 | +4. **lazy import claude_agent_sdk** — 没装 SDK 的开发者 import 此模块不报错 |
| 47 | + |
| 48 | +## 替代方案 |
| 49 | + |
| 50 | +### A. 不做,让用户自己写脚本调 MCP tools |
| 51 | + |
| 52 | +**否决**: |
| 53 | +- DBJavaGenix 自己的 MCP server 只对接 stdio / SSE,直接调要重新搞 transport |
| 54 | +- "写一个 agent loop" 是 ~150 行模板代码,我们提供省得每个用户重写 |
| 55 | +- 失去 "我们也会用 Agent SDK" 的叙事点 |
| 56 | + |
| 57 | +### B. 用 LangChain Agent / AutoGen |
| 58 | + |
| 59 | +**否决**: |
| 60 | +- v0.1 LangChain 试过(见 `docs/experiments/v0.1-langchain-orchestrator.md`)— 重、慢、抽象漏出 |
| 61 | +- AutoGen 适合多 agent 协作,我们只需要单 agent |
| 62 | +- Claude Agent SDK 是官方一手 SDK,跟 Claude 模型更新节奏同步 |
| 63 | + |
| 64 | +### C. 把 agentic 做成默认模式,弃用 mcp_server |
| 65 | + |
| 66 | +**否决**: |
| 67 | +- MCP server 模式不依赖 ANTHROPIC_API_KEY,门槛低 |
| 68 | +- 客户端模式有 UI / 多轮交互优势,适合探索性工作 |
| 69 | +- 两种模式互补,各擅胜场 |
| 70 | + |
| 71 | +### D. 复用 mcp_server 进程,加 "agentic" 子命令 |
| 72 | + |
| 73 | +**否决**: |
| 74 | +- 启动路径耦合,debug 困难 |
| 75 | +- 两种模式的 lifecycle 差异大(server 长驻 vs runner 一次性) |
| 76 | +- 拆开 ~200 行换来清晰边界,值得 |
| 77 | + |
| 78 | +## 后果 |
| 79 | + |
| 80 | +**好**: |
| 81 | +- 1 行命令完成 "schema 分析 → 代码生成" 全流程 |
| 82 | +- CI 友好 (dry_run 校验 + 真实模式跑批) |
| 83 | +- Tools 零重复,任何 mcp_server 的新工具自动出现在 agentic 模式 |
| 84 | +- 13 个 unit test 验证启动路径(无需真实 API key) |
| 85 | +- 为未来 "subagent" 留接口 (Agent SDK 支持 subagents) |
| 86 | + |
| 87 | +**坏**: |
| 88 | +- 多一个可选依赖 `claude-agent-sdk` (放 optional-deps,不是必需) |
| 89 | +- 文档要解释 "两种模式怎么选" (README 加了对比表) |
| 90 | +- agent 失控成本高 — `max_iterations` 默认 20 是软上限,真实场景仍要监控 |
| 91 | + |
| 92 | +**实测** (2026-06 dry_run + 真实 schema): |
| 93 | +- dry_run: `dbjavagenix agentic --goal "..." --dry-run` 200ms 内返回 plan |
| 94 | +- 真实跑: 一个 12 表的项目从 goal 到代码落地 ~90s,18 次 tool call |
| 95 | + |
| 96 | +## 叙事意义 |
| 97 | + |
| 98 | +2025-2026 LLM 工程演进的关键节奏: |
| 99 | +1. **2024**: 单次 prompt / 简单 RAG |
| 100 | +2. **2025 H1**: tool use + MCP 协议 |
| 101 | +3. **2025 H2 - 2026 H1**: **Agent SDK / Skills** — 标准化 agent 框架 |
| 102 | + |
| 103 | +DBJavaGenix 从 v0.1 (RAG 实验) → v0.2 (MCP tools) → v0.2.2 (agentic 模式) |
| 104 | +踩了完整三个节奏。这个 ADR 是第三节奏的落地证据。 |
| 105 | + |
| 106 | +更深的含义:**工具应该既能被 LLM 用,也能被 agent 用,还能被人用**。 |
| 107 | +agentic_runner 把 "同一组 MCP tools" 的复用边界推到极致 — 这是 v0.2.2 想表达的 |
| 108 | +"工程师视角下的 AI 集成"。 |
0 commit comments