From 55aab673834cb8fbd4dcaa4f8f09b8226acab966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E5=AE=8F=E5=87=AF?= Date: Thu, 11 Jun 2026 22:09:35 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9C=80=E6=B1=82=E6=A2=B3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/ai-writing-内置智能体改造.md | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 frontend-web/docs/ai-writing-内置智能体改造.md diff --git a/frontend-web/docs/ai-writing-内置智能体改造.md b/frontend-web/docs/ai-writing-内置智能体改造.md new file mode 100644 index 00000000..78c124b2 --- /dev/null +++ b/frontend-web/docs/ai-writing-内置智能体改造.md @@ -0,0 +1,196 @@ +# AI 写作「四阶段内置智能体化」改造方案 + +> 目标:把 AI 写作现有的 **素材收集专家 / 写作大纲 / 作家写作 / 编辑审核** 四个功能, +> 从「硬编码的 LangGraph 节点 + 硬编码提示词」改造为由**内置功能型智能体**驱动—— +> 每个阶段对应一个可配置的内置 agent(独立人设 SOUL、可配模型、可挂技能/工具)。 + +本文给出现状梳理、目标设计、以及**分步可独立交付的实现计划**。 + +--- + +## 0. 一句话结论 + +不推倒重来。**保留现有图的编排骨架、4 个用户干预点、流式与状态机,只把每个阶段节点的「大脑」从「硬编码 prompt 直调 LLM」替换为「加载对应内置 agent 的 SOUL+配置、在子线程上跑该 agent、按结构化契约解析其输出」。** 这样前端几乎不动,复杂逻辑(严格模式、素材不足求助、逐章流式、技能检索步骤)全部保留。 + +--- + +## 1. 现状梳理(精确到文件) + +AI 写作是一条 LangGraph 图:`packages/harness/deerflow/agents/ai_writing/graph.py` + +``` +intent_parser → researcher → (pause 素材确认) → writer_outline → (pause 大纲确认) + → writer_draft → (pause 草稿确认 / 素材不足求助) → editor → (pause 编辑打回) → done +``` + +四个待改造阶段(均为**硬编码节点**,直接调 LLM、不走 agent 运行时): + +| 阶段(用户语言) | 节点文件 | 提示词 | 产出(`state.py`) | +|---|---|---|---| +| 素材收集专家 | `nodes/researcher.py` | `prompts/researcher_prompts.py` | `material_package`(keywords + materials) | +| 写作大纲 | `nodes/writer_outline.py` | `prompts/writer_prompts.py` | `current_outline`(Outline JSON) | +| 作家写作 | `nodes/writer_draft.py` | `prompts/writer_prompts.py` | `current_draft`(Markdown,逐章流式) | +| 编辑审核 | `nodes/editor.py` | `prompts/editor_prompts.py` | `review_result`(评分 + 问题列表 JSON) | + +关键事实: +- **LLM 调用方式**:节点通过 `nodes/_utils.py` 的 `get_model()` + `llm_json()` **直接调 LLM**,提示词写死在 `prompts/*.py`。**没有**走 agent 人设 / 技能 / 工具体系。 +- **模型**:全程单一 `state.model_name`(用户在写作表单里选的主模型),各阶段无法分别配。 +- **干预点 / 流式 / 严格模式 / 素材不足求助**:都在 `graph.py` 的 pause 节点和 `writer_draft` 里,逻辑较重,需原样保留。 +- **前端**:`frontend-web/src/open-canvas/contexts/AIWritingContext.tsx` 是状态机(`researching/writing_outline/writing_draft/reviewing/...`),时间线 `AIWritingTimeline.tsx` 按 `progress_events`(已带 `agent_name` 字段)渲染。 + +--- + +## 2. 可复用的现成机制(不用造轮子) + +代码库里**已经有**一套成熟的「内置功能型智能体」范式——圆桌的 `roundtable-intent / roundtable-recommender / roundtable-coordinator`: + +1. **资源即代码**:`app/gateway/routers/_roundtable_seed_assets//` + - `config.yaml`(`id` / `name` / `description`,可扩展 `model` / `skills` / `tool_groups`) + - `SOUL.md`(人设 + 职责 + 工作流 + **结构化输出契约**) +2. **种子器**:`app/gateway/routers/_roundtable_seed.py::ensure_roundtable_functional_agents` + - 启动时 + 相关路由入口自愈:目录不存在才从资源字节级落盘到 `.deer-flow/agents//` + DB(**已存在则永不覆盖**,尊重本地编辑)。 +3. **运行**:在**独立 thread** 上跑该内置 agent(见 `app/gateway/routers/intent.py`,`INTENT_AGENT_ID = "roundtable-intent"`),通过 lead agent 运行时把 SOUL.md 作系统提示,流式经 LangGraph `custom`/`messages` 通道透传。 +4. **结构化输出约定**:SOUL 规定模型末尾输出固定 **marker + ```json```**(如 `[INTENT_READY]\n```json{...}```),后端用正则解析(`intent.py::_INTENT_READY_PATTERN`)。 + +> 我们要做的,本质就是**照搬这套范式,给 AI 写作做 4 个功能型 agent**,并让对应的图节点改成「跑这个 agent + 解析其结构化输出」。 + +另有 agents 通用体系可复用:`agents` 表、`/api/agents` CRUD、智能体管理页(配模型/技能/工具)——4 个写作 agent 落盘后天然出现在这里,可被 admin 编辑。 + +--- + +## 3. 目标设计 + +### 3.1 四个内置写作智能体(建议 id / 职责) + +| Agent id | 名称 | 取代节点 | 结构化输出 marker | 产出 schema | +|---|---|---|---|---| +| `ai-writing-researcher` | 素材收集专家 | `researcher` | `[MATERIALS_READY]` | `MaterialPackage` | +| `ai-writing-outliner` | 大纲规划师 | `writer_outline` | `[OUTLINE_READY]` | `Outline` | +| `ai-writing-writer` | 作家 | `writer_draft` | `[SECTION_READY]`(逐章) | 章节 Markdown | +| `ai-writing-editor` | 编辑 | `editor` | `[REVIEW_READY]` | `ReviewResult` | + +每个 agent 自带: +- `config.yaml`:`id / name / description` +(扩展)`model`(该阶段专用模型,可空=回退用户主模型)、`skills`(如 researcher 挂检索技能)、`tool_groups`。 +- `SOUL.md`:由现有 `prompts/*.py` 内容迁移改写,**追加结构化输出契约**(严格 marker + JSON 格式 + 反例,仿 `roundtable-intent` SOUL 的「硬规则」写法,压制弱模型乱输出)。 + +### 3.2 节点改造方式(核心) + +每个阶段节点保留**输入/输出契约不变**(仍读写 `state` 的同一批字段),内部从: + +``` +# 旧:硬编码 prompt 直调 +model = get_model(config, state["model_name"]) +result = llm_json(model, SYSTEM_PROMPT, USER_PROMPT.format(...)) +``` + +改为: + +``` +# 新:跑对应内置 agent,按 marker 解析 +result = await run_writing_agent( + agent_id="ai-writing-outliner", + state=state, config=config, + user_payload=<本阶段输入>, # 意图/素材/大纲/草稿等拼成的一段输入 + marker="[OUTLINE_READY]", # 结构化输出契约 +) +``` + +新增统一助手 `nodes/_agent_runner.py::run_writing_agent(...)`:在子 thread 上跑指定内置 agent(复用 `intent.py` 的 run/stream 机制)、把流式 chunk 透传到 `custom` 通道(前端时间线不回归)、用复用的 `_utils.parse_json` 多级容错解析 marker 后的 JSON。 + +### 3.3 为什么选这个方案(A)而非全多智能体重写(B) + +- **方案 A(推荐)**:保留图骨架,逐节点替换大脑。前端基本不动;干预点/流式/严格模式/素材求助原样保留;可**按阶段灰度 + feature flag 回退**,风险可控。 +- **方案 B(不推荐)**:仿圆桌重做成多 agent 编排,需重写编排、状态、流式、4 个干预点对接,工作量数倍、回归面巨大,收益(更"纯"的多 agent)对本场景并不必要。 + +--- + +## 4. 配置与可管理性 + +- **落盘**:仿 roundtable 新增 `_ai_writing_seed_assets/` + 一个 `ensure_ai_writing_functional_agents()` 种子器,在 Gateway 启动与 ai_writing 会话入口自愈。 +- **管理界面**:4 个 agent 落盘后即出现在智能体管理页,admin 可编辑 **SOUL(人设)/ 模型 / 挂载技能**。可选:在「文章类型配置页」旁加一个「写作智能体配置」入口,或给这 4 个打一个 `tag` 便于筛选。 +- **模型优先级**:节点跑 agent 时 `该 agent config.model > 用户写作表单选的主模型 model_name`(保留现有"用户选模型"语义,新增 per-阶段覆盖能力)。 +- **技能**:researcher 现有的技能检索能力(`search/skill_search.py`)改为 `ai-writing-researcher` 的**挂载技能**,admin 可增减;检索步骤事件(`SkillStep`)形态保留给前端展示。 + +--- + +## 5. 分步实现计划(每步可独立交付 / 验收) + +### Phase 0 · 契约冻结 +- 定 4 个 agent 的 `id / name`、每个的 **marker + JSON schema**(与 `state.py` 的 `MaterialPackage/Outline/DraftArticle/ReviewResult` 严格对齐)。 +- **验收**:本文 §3.1 / §6 的契约评审通过、字段与现有 TypedDict 一一对应。 + +### Phase 1 · 内置 agent 种子化(后端,纯新增,不接管流程) +- 新建 `app/gateway/routers/_ai_writing_seed_assets/<4 个 agent>/{config.yaml, SOUL.md}`;SOUL 由现有 `prompts/*.py` 迁移改写 + 追加结构化输出契约。 +- 仿 `_roundtable_seed.py` 写 `ensure_ai_writing_functional_agents()`,挂到启动 lifespan + ai_writing 入口。 +- **验收**:启动后 4 个 agent 出现在 `.deer-flow/agents/`、DB、`/api/agents`,能在智能体管理页查看/编辑;**此阶段不改图,写作流程行为不变**。 + +### Phase 2 · 节点接入「跑内置 agent」(后端,逐阶段灰度) +- 新增 `nodes/_agent_runner.py::run_writing_agent(...)`(子线程跑 agent + 流式透传 + marker 解析)。 +- 加 feature flag:`config.yaml → ai_writing.use_builtin_agents.{editor,outliner,researcher,writer}`(默认 false=走旧节点)。 +- **接入顺序(由易到难)**: + 1. **editor**(最简单:小 JSON、无检索、无逐章流式)→ flag 打开端到端验证。 + 2. **outliner**(输出 Outline JSON)。 + 3. **researcher**(保留技能检索步骤事件、素材确认暂停)。 + 4. **writer**(最难:保留**逐章流式** + **严格模式素材不足求助** `blocked_sections`;建议**仍由节点控制"逐章循环"**,每章调一次 `ai-writing-writer`,`section_help` 暂停逻辑不动)。 +- 每接一个,旧 prompt 与旧逻辑**保留**,节点按 flag 二选一。 +- **验收**:每个阶段 flag 打开后端到端走通,产出结构与旧版一致,干预点 / 流式 / 严格模式 / 求助暂停均不回归。 + +### Phase 3 · 每阶段 agent 配置化 +- per-agent 模型覆盖生效(`agent.config.model > model_name`)。 +- researcher 的检索能力改为挂载技能,admin 可增减。 +- 智能体管理页可编辑这 4 个的 SOUL / 模型 / 技能;config 热加载,新会话即生效、不重启前端。 +- **验收**:admin 改某阶段 agent 的模型 / SOUL / 技能后,新会话立即按新配置运行。 + +### Phase 4 · 前端适配(小改) +- 时间线 / 状态文案:阶段名读对应 agent 的 `name`(`progress_events.agent_name` 已存在,基本沿用,去掉写死文案)。 +- 可选:写作表单 / 设置加「查看·配置写作智能体」入口,跳智能体管理页。 +- **验收**:前端展示各阶段对应的智能体名;配置入口可达。 + +### Phase 5 · 清理收口 +- 四阶段稳定后,默认打开全部 flag、移除旧 prompt 直调路径与 flag(prompts 历史留在 git)。 +- 更新 `offline-backend-20260512/backend/CLAUDE.md` 架构描述。 +- **验收**:回归测试通过、冗余删除、文档同步。 + +--- + +## 6. 结构化输出契约(与现有 state 对齐) + +各 agent SOUL 末尾必须输出 `marker + ```json``` 块,schema 直接对齐 `state.py`: + +- `ai-writing-researcher` → `[MATERIALS_READY]`:`{ "keywords": string[], "materials": Material[] }`(`Material` 见 `state.py`,含 `id/title/content/source/relevance_score/source_type/...`)。 +- `ai-writing-outliner` → `[OUTLINE_READY]`:`Outline = { "title": string, "sections": OutlineSection[] }`(`OutlineSection = { section_title, key_points: KeyPoint[], material_ids }`)。 +- `ai-writing-writer` → 逐章 `[SECTION_READY]`:`{ "section_title": string, "markdown": string, "needs_more_material"?: { "reason": string } }`(`needs_more_material` 触发严格模式求助 `blocked_sections`)。 +- `ai-writing-editor` → `[REVIEW_READY]`:`ReviewResult = { "verdict": "pass"|"reject", "fact_score", "logic_score", "language_score", "overall_score", "pass_threshold", "revision_notes": ReviewIssue[] }`。 + +解析复用 `nodes/_utils.py::parse_json`(多级容错),marker 正则仿 `intent.py::_INTENT_READY_PATTERN`。 + +--- + +## 7. 风险与注意 + +1. **弱模型结构化输出不稳**:SOUL 写严格格式 + 反例 + 「输出 marker 后立刻闭嘴」硬规则(仿 `roundtable-intent` SOUL §0);解析层复用 `parse_json` 多级降级。 +2. **writer 的逐章流式 + 严格模式求助最复杂**:建议**循环控制权留在节点**(每章调一次 agent),不要让 agent 一次吐全文,否则 `blocked_sections` / `section_help` / 逐章流式都要重做。 +3. **researcher 技能检索步骤事件**(`SkillStep`)前端有专门卡片:迁移时保留这些 `progress_events` 形态。 +4. **种子器 never-overwrite**:迭代 SOUL 后**老部署不会自动更新**(与圆桌同一问题)。运维更新办法:删 `.deer-flow/agents//` 重新种子,或后续给种子器加「内置功能 agent 按版本/hash 覆盖」开关。 +5. **子线程隔离**:跑写作 agent 的子 thread 与主 ai_writing thread 状态隔离,注意 checkpointer 与清理(沿用 ai_writing 既有的会话清理)。 +6. **离线内网**:researcher 的检索一律走技能(不联网),与现有「离线部署禁 web_search、走 skill」策略一致。 + +--- + +## 8. 涉及文件清单(落地时对照) + +**后端(主要改动)** +- 新增 `app/gateway/routers/_ai_writing_seed_assets/{ai-writing-researcher,ai-writing-outliner,ai-writing-writer,ai-writing-editor}/{config.yaml,SOUL.md}` +- 新增 `app/gateway/routers/_ai_writing_seed.py`(种子器,仿 `_roundtable_seed.py`) +- 新增 `packages/harness/deerflow/agents/ai_writing/nodes/_agent_runner.py`(`run_writing_agent`) +- 改 `nodes/{researcher,writer_outline,writer_draft,editor}.py`(按 flag 二选一) +- 改 `config.yaml`(新增 `ai_writing.use_builtin_agents.*` 开关;可选 per-agent 默认模型) +- 保留 `prompts/*.py`(回退用,Phase 5 删) + +**前端(小改)** +- 改 `src/open-canvas/components/ai-writing/AIWritingTimeline.tsx`(阶段名读 agent name) +- 可选:写作表单/设置加「配置写作智能体」入口(跳 `/page/...` 智能体管理页) + +**文档** +- 本文件 +- Phase 5 收口时更新 `offline-backend-20260512/backend/CLAUDE.md`