返回 · 现在 vs Agent 化 业务对比
V2 · Orchestrator + Skills

PackHorizon
报告生成 Agent 化Orchestrator 编排 · Skill 动态调用

不是把 workflow "换个引擎跑" · 而是把 11 步固定 pipeline 升级成"能力箱 + 智能调度"。 Orchestrator 每次拿到用户请求 · 现场规划要调哪些 skill · 用什么顺序 · 哪些可以并行 · 哪些直接跳过复用。 同一套 skill · 覆盖新建 / 升级 / 局部重生成 / 保留复用 4 类场景 · 不再靠硬编码 if/else 堆代码。

Doc agent-migration-implementation-v2 Version v2 · 2026-07-09 Total ~4 months Risk
三层架构一览
1
Intake · 对话收集
Autonomous Agent · ReAct
2
Orchestrator · 编排
Plan-and-Execute
3
Skills · 能力箱
Skill Agent · ReAct 内部循环
目录 · 12 大章节
§0 · 目标 & 6 铁律

一句话目标 + 6 条不可动摇的边界

One-liner Goal

agent_v2/ 独立目录下 · 平行新建一套 Orchestrator 编排 Skill 的 Agent 系统 —— 老 workflow 一行代码不动 · 一张表不改 · 两套系统平行运行 · 用户前端开关切换。

Law 01
完全独立系统
v2 是平行新建不是重构 —— 独立代码目录 agent_v2/ · 独立 skill DB 表 · 独立 run/artifact 表 · 独立 API 端点。老版一行代码不动 · 一张表不改。
Law 02
共用只限静态资产 & 身份
共用:用户账号 · 素材上传(ProjectAsset)· intake confirmation · 底层 LLM 传输原语(provider 路由 / api_key / capability profile) · 基础设施(PG/Redis)· 配额闸门(assert_can_generate_report) · 积分扣费通道(CreditLedgerEntry + ImageGenerationJob)。独立:数据流水线 + 业务状态 + agent 编排逻辑v2 入口必须显式接配额闸门 · 出图必须走扣费通道 · 否则收入泄漏。
Law 03
Plan 必须可预览
Orchestrator 出的 plan 要能给用户看("这次跑 8 步 · 跳过 4 步 · 预计 3:20")· 用户点生成前能看到 agent 要干啥
Law 04
Skill 是能力不是步骤
10 个 skill 各自独立 · 无隐含顺序假设 · 输入输出都用 state 里的字段名 · 谁在什么时候调都能工作。
Law 05
Prompt 独立版本化 & CI drift
v2 skill 定义(prompt + gate + tools)在 backend/app/agent_v2/skills/*.yaml · 独立 agent_v2_skill_versions 表 · 生产 DB 只能通过 PR 变更 · 每日 CI 校验 drift · seed 不再无条件覆盖
Law 06
追溯只覆盖 v2
追溯页只显示 v2 run · 老版 run 走老版原有 report 页 · 不做跨引擎统一 trace(避免破坏老版路径 + 老版无 agent_events 数据)。
§1 · 三层架构总览

为什么用 3 种不同 pattern · 不是全部一种

LLM agent 有 3 种主流架构 pattern · 每种适合不同场景。全部用 ReAct 会成本失控 · 全部用固定 workflow 就退回老版。 正确姿势 · 每层用最合适的 pattern —— 这是 v2 的架构基石。

3 种 Pattern 对比 · 各自适合什么

Pattern A · ReAct Agent C · Plan-and-Execute ⭐ Workflow (老)
决策方式 LLM 每步临场决定 先规划全局 · 再按 plan 执行 编译期写死
灵活度 最高 中高
可预测 & 步骤预览 差 · 无法预知 LLM 决策 好 · plan 出来就能预览
成本 3-5x(每步都 LLM 决策) 1.5-2x(只 plan/replan 时) 1x
Fan-out 并行 难 · 破坏 ReAct 语义 天然支持(plan 里指定) 硬编码
适合场景 开放式对话 / 单任务 多步任务 / 需要步骤预览 只知道死板流程

三层混合架构 · 每层选对 pattern

核心洞察:PackHorizon 不同环节需求不同 —— intake 是开放式对话(用户随便问)· 报告生成需要让用户能看到步骤(点生成前知道 agent 要干啥)· 单 skill 内部又需要自主搜索抓取。 用一种 pattern 覆盖所有场景 = 商业自杀

Layer
01
Intake 对话收集 · Autonomous Agent · ReAct 模式
用户随便问什么 · Agent 自主判断该调什么工具。工具箱: web_search(联网找灵感)· image_recognize(识别用户发的竞品图)· brand_kb(查这个品牌历史项目)· past_projects(查用户以前做过的方向)· reference_lib(查内部案例库)。

目标:边聊边收集齐 confirmation 字段 · 用户点确认卡后进入下一层。
Why ReAct 用户随时插话 · 开放式 · 无明确 end goal · 需要极致灵活。ReAct 让 LLM 现场决策最合适。
↓ 用户点"生成报告"
Layer
02
Orchestrator 编排 · Plan-and-Execute 模式
拿到 confirmation + 用户请求 → LLM 先出 plan:"这次跑哪些 skill / 什么顺序 / 哪些并行 / 哪些复用" · plan 显示给用户看("预计跑 8 步 · 时长 3:20")· 用户可干预 · 按 plan dispatch skills · 每步完成后 replanner 评估是否要调整。

目标:动态决定这次任务怎么跑 · 覆盖新建 / 升级 / 局部重生成 / 保留复用 4 类场景。
Why P&E 用户能看到 plan · vip 客户能调 plan · 需要 Fan-out 并行 · 上下文要干净不能爆炸。
↓ Orchestrator dispatch 到 skills
Layer
03
Skill 内部执行 · ReAct 循环
单个 skill 内部 · LLM 自己决定怎么完成任务。例: packaging-intelligence 自己决定搜几次 / 抓几个 URL / 什么时候够了停 · copy-compliance 自己决定查哪些品类规则 · 检查哪些高危词。

目标:让每个 skill 像一位真专家 · 不用我们写死"先搜 A 再搜 B"。
Why ReAct 单 skill 内部有明确目标 · 但完成过程需要自主 · 工具调用次数不定 · ReAct 天然适合。
§2 · Intake · Autonomous Agent

用户随便问什么 · agent 自主调工具答

老 intake-dialogue 只会"照着 script 反问" —— 用户问"辣条包装现在什么创意"就懵。 新的 intake agent 有工具箱 · 自主决定用哪个工具帮用户 · 同时不忘继续收集 confirmation 字段。

Intake Agent 的工具箱
用户在对话过程中随时可能提出各种需求 —— 要看竞品 / 识别图 / 查历史 / 找灵感 —— agent 从工具箱里自主挑合适的调:
web_search image_recognize brand_kb.query past_projects reference_lib image_generate (mood)
"辣条包装行业现在有什么新的创意?"
agent 判断:行业动态类 → web_search
→ tool_call: web_search("辣条包装设计 2026 创新")
→ 返回 8 条 · 卫龙 XX / 麻辣王子 XX / ...
→ 汇总回复 + 顺势反问:"你偏好哪种方向?"
发一张竞品图 · "识别一下这是啥风格"
agent 判断:识图任务 → image_recognize
→ tool_call: image_recognize(user_uploaded.jpg)
→ 返回描述:极简 / 冷淡 / 白底 / 手绘 logo
→ 回复:"这是冷淡风 · 你想避开还是保留?"
"我们品牌之前做过什么设计?"
agent 判断:品牌历史 → brand_kb.query
→ tool_call: brand_kb.query(brand_id)
→ 返回:3 年前"清爽系列" · 主色 #2E7D32
→ 回复:"3 年前做过 · 要延续还是刷新?"
"推荐几个国际参考"
agent 判断:参考灵感 → reference_lib + web_search
→ 并行调 2 工具
→ 内部 5 条 + 网络 4 条 · 挑最匹配的 3 个
→ 回复 3 张参考图 + 简短解读
关键约束 · agent 不管答了什么问题 · 最终要把用户拉回收集齐 confirmation · 只有 confirmation 齐了才能弹确认卡进入下一层 · 避免陷入无尽闲聊。
§3 · Orchestrator · 4 场景动态编排

同一套 skill · Orchestrator 动态编排 · 覆盖 4 类场景(3 类是 v2 独占新能力)

Orchestrator 拿到 confirmation + 用户请求 · 先出 plan · 再执行。以下 4 个真实场景 · Orchestrator 各自出不同 plan · 但用同一套 10 skill 能力箱

10 个 Skill · Orchestrator 的能力箱

skill 01
情报研究员
竞品调研 · 品类趋势 · 视觉参考
工具:web_search / web_extract
skill 02
品牌顾问
定位分析 · 差异化路径 · slogan
工具:brand_kb / reference_lib
skill 03
文案合规员
品类合规规则 · 高危词检查
工具:compliance_router
skill 04
创意员
概念发散 · 15 个候选方向
工具:reference_lib / mood_gen
skill 05
设计总监
评审收敛 · 5 维打分 · 选 6 方向
工具:quality_scorer
skill 06
设计师(可 fan-out × 6)
深化单一方向 · 视觉细节 + 文案
工具:reference_lib
skill 07
图片生成师(可 fan-out)
按 brief 生成包装可视化
工具:image_generate
skill 08
对比员(升级专用)
新旧对比 · 保留 / 变化差异标注
工具:image_compare / image_recognize
skill 09
报告总监
装配 9 sections · 生成最终 HTML
工具:report_template
skill 10
Logo 替换师(新加)
保留原包装结构 · 只替换 logo
工具:image_edit / image_generate

4 个真实场景 · Orchestrator 各自出不同 plan

场景 01 · 全新方案
新品牌 · 从零设计一款包装
"我要给一款新的无糖气泡水做包装 · 25-35 岁人群"
Orchestrator Plan: ▶ 顺序: 情报 → [品牌 || 合规] → 创意 → 总监 → 设计师×6 → 图×6 → 报告 跳过 · Logo 替换师 (跳过) 跳过 · 对比员 (跳过 · 无旧包装)
预计 4:12 · 8 skill
场景 02 · 升级 · 只换 logo
升级项目 · 保留视觉只换 logo
"原包装配色和结构都保留 · 只把 logo 换成新版"
Orchestrator Plan: 跳过 · 情报 · 品牌 · 合规 · 创意 (跳过 · 有旧数据复用) 跳过 · 总监 · 设计师 (跳过 · 结构不变) ▶ 顺序: Logo 替换师 → 图×3 (新 logo 变体) → 对比员 → 报告
预计 1:30 · 4 skill
场景 03 · 局部重生成
已有报告 · 只重跑市场调研
用户点报告里"重新生成 · 市场调研"
Orchestrator Plan: 跳过 · 其他 9 skill 全部跳过 ▶ 只跑: 情报研究员 (更新 stage_artifact) → 报告部分刷新
预计 1:30 · 1 skill
场景 04 · 保留策略换风格
保留策略 · 只换视觉方向
"策略我很满意 · 只想换个视觉方向 · 避开原风格"
Orchestrator Plan: 跳过 · 情报 · 品牌 · 合规 (跳过 · 复用旧输出) ▶ 顺序: 创意 (带 hint "避开原风格") → 总监 → 设计师×6 → 图×6 → 报告
预计 3:15 · 5 skill
关键差别 · 跟老 workflow
老 workflow · 只支持 kind 二元(new / upgrade)· 场景 03 / 04 / logo 替换 根本不支持 · 用户想局部重生成或保留复用只能重跑全套。
v2 Orchestrator · 4 场景走 同一套架构 · Orchestrator 现场判断该跑哪些 · 3 个新能力(场景 02/03/04)是 v2 独占 · 加新品类只需注册一个新 skill · 不改代码 DAG · 只增 skill 定义
§4 · Phase 0 · 独立建 v2 骨架 · 1.5 周 · 零风险

不改老版一个字段 · 完全新建 v2 的表 · 目录 · YAML 加载机制

Phase 0 不碰老版 —— 建 v2 独立 DB 表(agent_v2_skill_versions 等)· 建 backend/app/agent_v2/ 独立目录 · 建 v2 自己的 YAML → DB 加载机制。
关键 · v2 seed 不复用老版的 _fill_stage_definition_defaults(有无条件覆盖 bug) · v2 用"YAML hash 变了才 apply"的干净机制。

P0.0
alembic 双 head merge · 所有事的前置
后端 0.5d
动作
Step 1:ssh 生产 → alembic current 确认两个 head 都已 stamp/applied · 否则 merge 后 upgrade head 会把未应用的 migration 拉进生产;
Step 2:merge 现有两个 head(6e7f8091a2b3 / 9d0e1f2a3b4c)· 生成空 revision;
Step 3:测试库跑 alembic upgrade head 验证。
验收
  • alembic heads 只剩 1 个
  • 生产库确认已在两个 head · 无未应用 migration
  • 老版部署链路验证不受影响
P0.1
建 v2 独立 DB 表(migration)
后端 1d
输出
alembic migration · 先 merge 双 head · 再建 5 张新表: agent_v2_skill_versions(独立 skill 定义 · 有 tools/gate 字段)· agent_v2_runs(独立 run 记录)· agent_v2_stage_artifacts(独立中间产物 · 有 hash 字段)· agent_v2_events(细粒度事件)· agent_v2_llm_calls(独立表 · 记录 v2 所有 LLM 调用 · 列结构与 ModelCallLog 对齐 · cost 建议 Numeric(12,6)(老版是 String(64) · UNION 时 CAST))· 同时建 UNION 视图 report_runs_all + llm_calls_all · 财务/配额/用量三个报表共用
验收
  • alembic upgrade head 干净跑通
  • 5 张 v2 表建成 · 老版 6 张表零改动
  • 索引 & FK 到 project_id / user_id · 复用老版这些实体
P0.2
backend/app/agent_v2/ 目录骨架
后端 0.5d
输出
目录树:agent_v2/skills/*.yaml(10 skill 定义)· agent_v2/orchestrator/ · agent_v2/tools/(web_search 等)· agent_v2/state.py · agent_v2/graph.py · agent_v2/loaders.py · agent_v2/services/(v2 版的 model_runtime · 带 tool calling)
验收
  • 目录 & 空文件建成 · README 写清 skill vs stage 边界
  • pip 装 langgraph>=0.2.55 + langgraph-checkpoint-postgres
  • from app.agent_v2 import graph 无报错
P0.3
10 个 skill YAML 写入
后端+内容 2d 依赖 P0.2
输出
10 个 skill YAML · 每个含 7 段 · 参考老版 packaging_stage_prompts.py 里的 prompt 但不是拷贝 —— v2 的 prompt 要重新设计成"能调工具"的 ReAct 风格 · 声明 tools:
验收
  • 10 YAML 全部就位 · tools 段可读
  • 内容运营 review 每个 skill 的身份/输出契约
P0.4
v2 的 YAML → DB 加载机制(hash-diff)
后端 1.5d 依赖 P0.1
输出
agent_v2/loaders.py::apply_skills(dry_run=bool) —— 读 YAML 计算 hash · 只有 hash 变化才 insert 新 version + SET is_current · 禁止无条件覆盖。加 verify_drift() 校验 repo YAML 跟 DB is_current 是否一致
验收
  • hash 不变时 apply 是 no-op(测试反复跑不改 DB)
  • YAML 改 1 字符 → apply 生成新 version
  • verify_drift 有 drift 时 exit 1
  • 启动时不自动跑 apply · 必须 CLI 显式触发(避免部署静默覆盖)
P0.5
CI drift check + 飞书报警
DevOps 0.5d
输出
每日凌晨 CI 跑 verify_drift.py · drift 时飞书报警到 Park Horizon 群 · README 写明"改 v2 skill 只能通过 PR + apply"
验收
  • CI 每日跑
  • drift 报警到位
P0.6
alembic 双 head merge · 已提前为 P0.0
已上移
说明
此任务是所有 Phase 0 动作的前置 · 二轮 review 后已改成 P0.0 · 编号顺序符合执行顺序。
Phase 0 总验收
  • 6 任务全完 · v2 完整骨架就位
  • 老版 prompt_versions / workflow_run / stage_artifact / seed 逻辑零改动
  • v2 skill YAML 有独立的 hash-diff apply · 不会被 seed 静默覆盖
  • alembic 双 head 解决 · v2 表建成 · 可以进 Phase 1
§5 · Phase 1 · Spike 验证 · 2 周 · 低风险

先建 ReAct runtime · 再试跑 Orchestrator + 3 skill · 数据决策 GO / NO-GO

P1.1 独立任务:先建 ReAct model_runtime 层(3d · 从零搭) —— 老版这层能力为零。
P1.2-P1.5:在 runtime 之上跑 Orchestrator + 3 skill spike · 验证 plan 质量。

P1.1
v2 ReAct model_runtime 层 · 从零搭
后端 3d 依赖 Phase 0
背景
老版 model_runtime_service 是纯单次 completion · 不写 tools · 不解析 tool_calls · 无流式。ReAct 循环 + 工具执行器 + tool 消息回填 · 三层都要新建 · 复用老版只到 _request_chat_completion 底层原语。
输出
agent_v2/services/react_runtime.py · 支持 tools 声明 · tool_call 解析 · tool 消息回填 · max_iterations 上限 · repair loop
验收
  • 能跑通"agent 决定调 web_search → 拿结果 → 决定继续或结束"完整循环
  • max_iterations 触发时正确 raise 而不是死循环
  • 底层调用复用老版 _request_chat_completion · 不复制 provider/api_key 配置
P1.2
State schema + skill loader
后端 1d
输出
PackagingState TypedDict · load_skill(skill_code) loader · state 里 fan-out 字段用 Annotated[dict, merge_by_id]
验收
  • loader 单测 pass
  • schema 完整
P1.3
实现 3 个 skill (ReAct)
后端 2d
输出
packaging_intelligence / brand_strategy / copy_compliance 三个 skill · 内部 ReAct · gate + repair loop
验收
  • 3 skill 单跑 pass
  • gate fail → repair 生效
P1.4
Orchestrator MVP (Plan-and-Execute)
后端 1.5d 依赖 P1.3
输出
planner (LLM) 输出 JSON plan · executor 按 plan dispatch skill · replanner 每步后评估 · PostgresSaver 挂 checkpoint
验收
  • Orchestrator 能出 plan JSON
  • 能 dispatch 到 3 个 skill
  • 能从 checkpoint 续跑
P1.5
Benchmark + GO/NO-GO
后端+PM 1d
对比指标
10-20 份真实 intake 对跑老 workflow vs v2 · 比 plan 质量(合理 skip / skill 选对)+ 耗时 + token + 输出质量
GO 阈值
Plan 合理率 ≥ 85% + 质量不劣化 + 耗时 ≤ 110% + 成本 ≤ 200% 老版
验收
  • Benchmark 报告写完
  • 决策会开完 · 结论 docs/decisions/
Phase 1 总验收
  • 5 任务全完
  • GO / NO-GO 决策写入 docs/decisions/2026-XX-agent-v2-go-nogo.md
  • Plan 质量是 v2 独有的关键指标 · v1 里没有
§6 · Phase 2 · 全量落地 · 5~7 周 · 低风险

剩余 7 skill + Intake 自主 agent(P2.11)+ Orchestrator UI + 追溯页 + 2 v2 独占新能力 + UI 开关 + 灰度

核心约束:老 workflow 一行代码不动 · 前端开关 opt-in
v2 独有:多了 Orchestrator UI(plan 预览)+ Skill 10(logo 替换师)· 比 v1 Phase 2 稍复杂。

P2.1
Orchestrator planner prompt + few-shot
后端+PM 2d
输出
Planner YAML · 4 场景 few-shot 示例 · 输出 JSON schema({plan: [skill_id, ...], parallel_groups: [...], skip: [...], reason: str})
验收
  • 4 场景 planner 输出全对
  • schema 校验 pass
P2.2
3 tools 抽出(compliance_router / quality_scorer / report_template)
后端+内容 4d
输出
3 tool + 对应 YAML 数据表(7 品类合规 / 5 维权重 / 2 报告模板)
验收
  • tool 单测
  • 内容运营可 review 数据表
P2.3
剩余 7 skill 实现
后端(可派 CC) 5d
skill 清单
creative-exploration / director-selection / designer(fan-out) / image-brief(fan-out) / difference-review / report-presentation / logo-swap (v2 新)
验收
  • 7 skill 单测
  • fan-out 并行验证
  • logo-swap 单场景跑通
P2.4
v2 API + 独立 worker + 配额闸门 + 出图账务 + scheduler 治理
后端+运维 4d
输出(5 项 · 缺一项上线炸)
  1. API 端点:POST /api/agent_v2/reports/generate · body 含 orchestrator_hint · 入口必须 call assert_can_generate_report(user) · 超配额同样 429
  2. 配额跨引擎计数:today_report_count 改成查 UNION 视图 report_runs_all · 计入 v2 run(否则 v2 无限白嫖)
  3. 独立 celery task:app.tasks.agent_v2_tasks.run_report · task_routesagent_v2_queue · celery_app.py importsagent_v2_tasks
  4. 独立 worker 服务(容易漏!):docker-compose.yml + 生产 compose 新增 agent-v2-worker:celery ... worker --queues agent_v2_queue --concurrency ${CELERY_AGENT_V2_CONCURRENCY:-3} · flower 依赖列表加新 worker · docs/ops/FRONTEND_BACKEND_DEPLOYMENT.md 补服务表
  5. Scheduler 治理复刻:v2 需要自己的 report.max_parallel_jobs_v2 并发闸 + packhorizon:report:scheduler:lock:v2 分布式锁 + _mark_stale_v2_running_runs(否则崩溃 run 永远 running 无人清)· 也可在 orchestrator 内做 semaphore + heartbeat 兜底
出图账务(P1 关键决策 · D11)
v2 skill 07 fan-out 出图必须走 ImageGenerationJob + _prepare/_commit_direction_image_chargeCreditLedgerEntry · 否则付费方向出图不扣积分。二选一:A 复用老 run_image_generation_job(推荐 · 保计费)· B 自建独立表(需完整复刻扣费 ledger 逻辑)· D11 待决
验收
  • 老 API 路径 & report_generation/image_generation 队列零改动
  • e2e: v2 生成计入当日配额 · 超限被拒
  • e2e: 投递到 agent_v2_queue 的任务被 agent-v2-worker 消费(不 pending)
  • e2e: v2 付费方向出图正确扣 CreditLedgerEntry
  • 崩溃 run heartbeat 超时自动 stale · 不永久 running
  • 压测两版并跑 · 老版吞吐无退化
P2.5
前端 · UI 开关 + Plan 预览
前端 3d
交互
开关"使用新版引擎(实验)" · 默认 off · 打开后点生成 · 先显示 Plan 预览卡(预计跑几步 / 时长 / 跳过项)· 用户确认后再真跑
验收
  • 开关记住偏好
  • Plan 预览显示对
  • fail 自动 fallback 老版
P2.6
追溯页 (§7) + v2 run 状态/进度 SSE + 前端进度水合适配
前端+后端 6d
输出
Admin /reports/:id/trace 页 · 顶部 Orchestrator Plan · 中部动态时间线 · 底部 skill 展开细节。用 agent_v2_events + agent_v2_llm_calls 表数据。额外:新建 GET /api/agent_v2/runs/:id/events(SSE)+ 改造前端 useWorkspaceReportGeneration.ts(~600 行) 加 v2 run 形状适配 · LocalReportRun / liveReportRunsById 分派 engine · deliverable 判定改用 v2 事件流
验收
  • Plan / timeline / 展开细节都能看
  • replay 能重跑单 skill(后端 checkpoint 精确恢复)
  • 前端两版进度水合独立 · 互不干扰
P2.7
观测看板 M1-M5
后端+数据 3d
5 看板
M1 Orchestrator plan 质量 · M2 Skill 健康度 · M3 单份 Trace · M4 供应商成本 · M5 满意度归因
验收
  • 5 看板可打开
  • M1 异常时报警
P2.8
灰度 10% → 50% → 100%
PM+后端 3 周
节奏
W1 10% vip opt-in → W2 50% opt-in (推荐尝试)→ W3 100% opt-in (默认 on)· 老 workflow 保留 ≥ 30 天
回滚阈值
完成率 -5% / P95 > 老版 / 投诉暴增 / 成本 > 老版 2 倍 · 任一触发默认 off
验收
  • W1 完成率 ≥ workflow
  • W2 opt-in ≥ 40%
  • W3 主动关闭率 ≤ 10%
P2.9
局部重生成机制 · v2 独占新能力
后端+前端 4d 依赖 P2.3
背景
老版报告是一次性装配整块 · 无"只刷新某一节"的机制 · 场景 03 的需求老版做不到 · v2 要新建。
输出
1 orchestrator plan 支持 partial_regen 模式 · 只跑指定 skill; 2 report-presentation 支持"只替换某 section"而非整块重装; 3 前端报告页每个 section 加"重新生成"按钮 · 单点触发。
验收
  • 用户点某 section "重新生成" · 只跑对应 skill · 其他 section 不动
  • DB 里 agent_v2_stage_artifacts 只该 skill 的 artifact 更新
  • 响应时长 < 全量重跑的 20%
P2.10
保留复用 · hash 校验机制 · v2 独占新能力
后端 3d 依赖 P2.3
背景
场景 04「保留策略换风格」 需要 orchestrator 能安全跳过某些 skill 复用旧 artifact · 但要防"上游改了 · 下游还用旧数据"污染。
输出
1 orchestrator plan 支持 reuse_from_run_id 字段; 2 复用前先校验 agent_v2_stage_artifacts.hash 跟当前 skill 版本的 input hash 是否匹配; 3 hash 不匹配 → 拒绝复用 · 报警运营。
验收
  • hash 匹配 → 秒级复用 · artifact 直接引用
  • hash 不匹配 → 拒绝复用 · fallback 到全量重跑
  • 场景 04 e2e 测试 pass
P2.11
Intake 自主 agent · v2 独占新能力
后端+前端 7d 依赖 P1.1
背景
老 intake 是照剧本反问(intake_consultant_service.py 969 行 + api/intake.py 335 行)· 用户跳出剧本问"辣条包装现在有啥创意"/"识别下这张竞品图" 完全接不住。v2 intake 用 ReAct autonomous agent 在其上层承接 · confirmation 结构下游兼容。
工具箱
web_search(联网找灵感)· image_recognize(识别用户发的竞品图)· brand_kb.query(查品牌历史)· past_projects(查过往方向)· reference_lib(查内部案例库)· image_generate(mood board 出图)
输出
1 agent_v2/intake/ 目录 · intake ReAct agent 实现; 2 confirmation 收集机制 · 兼容老版数据结构(共用 ProjectAsset + confirmation 落表); 3 前端 intake 页 v2 版 · 支持 tool 结果富文本回复(搜索结果卡片 · 识图结果 · 参考图轮播)。
验收
  • 4 个真实对话场景(行业动态 / 识图 / 品牌历史 / 参考推荐)全跑通
  • confirmation 收集完整 · 跟老 intake 输出结构一致(共用下游)
  • 老 intake 保留 · v2 intake 通过前端开关触发
Phase 2 总验收
  • 11 任务全完(含 P2.9/P2.10/P2.11 三个 v2 独占新能力)
  • 老 workflow 完整保留 · 未被"顺手重构"
  • 用户主动选新版率 > 50% 才算真赢
§7 · 追溯页 · Plan + 动态时间线

打开报告 · 先看 Orchestrator 出了啥 plan · 再看每步怎么跑的

追溯页跟 v1 骨架级差别 —— 顶部先展示 Orchestrator 的 plan("这次跑了 4 skill · 跳过 6 · 因为是升级只换 logo")· 让人一眼看懂 agent 为什么这样跑。 Timeline 也不再是固定 11 步 · 而是动态显示这次真的跑了哪些 skill · 跳过的用灰色 · 复用的标"复用旧输出"。

追溯页 mockup · 场景 02 · 升级只换 logo

packhorizon.com/admin/reports/rp_8m3n2c/trace
无糖气泡水 · 升级项目 追溯 rp_8m3n2c · 2 天前完成
Engine agent_v2 耗时 1:32 跑了 4 skill 跳过 6 skill
▶ Orchestrator Plan
这次是升级项目 · 用户要保留配色只换 logo
Confirmation 显示 upgrade_type=logo_only · 旧包装 asset 已上传 · 品牌策略/合规/创意方向都已有 · 无需重新收集。只需要跑 logo 替换 + 新旧对比 · 报告部分复用旧模板。
跳过 · 情报研究员 · 复用旧输出 跳过 · 品牌顾问 · 复用旧输出 跳过 · 文案合规员 · 复用旧输出 跳过 · 创意员 · 无需(结构不变) 跳过 · 设计总监 · 无需 跳过 · 6 位设计师 · 无需 ▶ Logo 替换师 (v2 新 skill) ║ 图片生成师 × 3 (并行 · 3 个 logo 变体) ▶ 对比员 (新旧包装差异标注) ▶ 报告总监 (装配)
Timeline
Skill 版本
成本明细
Raw JSON
— Block 01 · 用户对话过程(2 轮 · 1 分 12 秒)—
第 1 轮
用户 "我想给旧包装换 logo · 其他都保留"
展开
第 1-2 轮
Intake Agent "上传新 logo · 确认原配色 #EAF5EA · 结构 330ml 易拉罐"
展开
— Block 02 · Orchestrator 规划(3 秒)—
00:00
Orchestrator · 出 Plan 识别 upgrade_type=logo_only · 决定 skip 6 skill · run 4 skill
展开
— Block 03 · Skills 执行(1 分 24 秒 · 4 skill run · 6 skill skip)—
情报 / 品牌 / 合规 / 创意 / 总监 / 6 设计师 已跳过 · 复用旧 stage_artifacts
查看复用
00:03
Logo 替换师 v1 ReAct 循环 3 圈 · 用时 42 秒
收起 重跑
▶ 任务
保留原包装 asset (bottle_v1.png) 的结构 + 配色 · 替换其中的 logo 为 new_logo.svg · 输出替换指令 brief
▶ ReAct 循环 · 第 1 圈
LLM 想:先分析原包装 logo 位置和大小 → tool_call: image_recognize(bottle_v1.png) → 返回:logo 位于瓶身正中 · 尺寸约 90×90 · 透明底
▶ ReAct 循环 · 第 2 圈
LLM 想:检查新 logo 兼容性 → tool_call: image_recognize(new_logo.svg) → 返回:矢量图 · 主色 #2E7D32 · 尺寸可缩放
▶ ReAct 循环 · 第 3 圈
LLM 想:信息够了 · 输出替换 brief 给图片师 → final_answer: {position, size, color_check, brief}
▶ Gate 校验
[pass] 保留原结构 [pass] 新 logo 色彩兼容 [pass] 尺寸比例合理
00:45
图片生成师 × 3 (并行) 3 个 logo 变体渲染 · 26 秒
展开 3 重跑
01:11
对比员 新旧包装差异标注 · 生成对比图
展开
01:22
报告总监 装配 4 sections · logo 变更专用模板
展开
追溯页 · v2 独有的核心信息
Plan 卡 · 顶部立刻回答"这次为什么这样跑" —— 4 skill run / 6 skill skip · 每个跳过都有原因(复用 / 无需)。
动态时间线 · 只显示真跑过的步骤 · 跳过的合并成一行灰色显示 · 不再假装 11 步都跑了。
Orchestrator 自身 · 也是时间线里的一步 · 有 token 有 cost · 可以点开看它 planner 的输入输出(能定位 plan 出错原因)。
§8 · 里程碑时间线

3 个月 · 8 个里程碑 · 每个 M 都有 Gate

M0
W0 · Kick-off
PRD review + 架构决策
团队过 v2 三层架构 · 决 D1 (drift 修复) · D2 (pattern 组合)
Gate团队签字 · 架构无异议
M1
W1 · Phase 0 完成
10 Skill YAML 就位 · drift 修完
apply / verify 脚本 · CI 每日跑 · 生产 stage 全部 = repo YAML
Gateverify 连 3 天 pass
M2
W2 · Phase 1 决策
Orchestrator MVP + 3 skill · Benchmark
Plan 质量 / 输出质量 / 耗时 / 成本 对比 · GO / NO-GO
GatePlan 合理率 ≥ 85%
M3
W5 · Phase 2 代码就绪
10 skill 全实现 + Orchestrator UI + 追溯页
agent_v2 独立目录 · 前端 UI 开关 + Plan 预览 · 追溯页 3 大块
Gate内部 dogfood 4 场景全跑通
M4
W7 · 10% 灰度
vip opt-in · 默认 off
观察完成率 / 主动关闭率
Gate完成率 ≥ workflow
M5
W9 · 50% opt-in
推荐尝试 · 显 Plan 卡
观察 opt-in 率 · 用户对 Plan 的反馈
Gateopt-in ≥ 40%
M6
W11 · 100% opt-in
默认 on · 用户可关
老 workflow 保留 ≥ 30 天
Gate主动关闭率 ≤ 10%
M7
W13+ · 稳定运行
Loop 1/2/3 常态化 · 加新 skill 试跑
按 §3 场景 04 需求 · 加第 11 skill 验证扩展性
Gate无 P0 事故 30 天
§9 · 关键决策点 · 10 个

必须开会 · 会议纪要写进 docs/decisions/

# 决策点 触发时机 决策人 影响
D1Prompt drift 修复方向Phase 0 前后端+PM以生产 V36 为准(推荐)vs repo V24 · 建议前者
D2Pattern 组合确认(三层)Kick-off后端+PM+老板确认 ReAct + P&E + ReAct · 或调整某层选型
D3Phase 1 GO / NO-GOM2 前后端+PM+老板决定是否投 3-5 周做 Phase 2
D4Orchestrator LLM 选型P1.4 前后端用 Claude Sonnet 4.5 / GPT-5 / DeepSeek · 影响 plan 质量与成本
D5用户能否手动改 PlanP2.5 前PM+前端只显示(推荐)vs 可编辑 · vip 客户可编辑
D6UI 开关默认状态P2.5 前PM+前端默认 off / on / 推荐尝试
D7灰度回滚阈值P2.8 前PM+后端指标下降多少触发默认 off
D8老 workflow 何时下线100% opt-in 稳定 30 天后老板+后端下线简化 vs 永不下线兜底
D9数据共享边界(已定)已完成爸爸+架构师共用:账号 · 素材 · confirmation · 底层 LLM 传输原语(provider/api_key/capability) · PG/Redis · 配额闸门(assert_can_generate_report积分扣费(CreditLedgerEntry出图账务(ImageGenerationJob)。独立:skill 表 · run 表 · artifact 表 · events 表 · llm_calls 表(cost 字段与 ModelCallLog 列结构对齐 · 建议 Numeric(12,6))· API 端点 · celery 队列 · agent 编排逻辑。财务归因用 UNION 视图 report_runs_all(engine, project_id, run_id, created_at, retry_of) · 配额/用量/成本三个报表共用同一个视图。
D10前端复用度(shell 共用 · trace/报告页新建)P2.5 前PM+前端顶部导航 · 项目列表复用 · v2 报告展示页 & 追溯页全新写
D11v2 出图账务路径P2.4 前后端+PMA 复用老 run_image_generation_job + ImageGenerationJob(推荐 · 保 CreditLedgerEntry 扣积分)/ B v2 自建独立表(需复刻完整扣费 ledger)
§10 · 风险与护栏 · 14 个

18 类风险 · 每个都有对应护栏(含 CC 三轮 review 揭示的新风险 R10-R18)

# 风险 概率 影响 应对
R1Orchestrator Plan 质量不稳定(v2 新)Planner 用 few-shot 4 场景 · JSON schema 强约束 · Plan 用小模型跑 fallback safety net · M1 看板监控合理率
R2Plan 让用户等太久(v2 新)Planner 用 Haiku 快模型(2 秒内)· Streaming 显示 plan · 用户满意度 vs 老版对比
R3两版长期共存维护成本共用 skill_versions DB · 只编排逻辑不同
R4Orchestrator + Skill 双层 LLM 成本翻倍中-高Planner 用小模型 · Skill 内部 max_iterations 上限 · 单份成本上限 ¥5
R5Skill fan-out 并行放大 API 成本中-高并行度可配 · 供应商余额告警 · 主推同步其他异步
R6Phase 2 撞产品迭代分阶段可停 · 老 workflow 继续接需求 · agent_v2 独立 team owner
R7灰度期用户体感差前端 fallback + 秒回滚 · Plan 预览让用户能拒绝
R8LangGraph 版本坑用 0.2.55+ · Send / PostgresSaver 已 GA
R9Skill 复用逻辑 bug(v2 新)stage_artifact 复用前必哈希校验 · replay 单元测覆盖 4 场景 · 出错自动回退 workflow
R10老版报告在 v2 追溯页 404(无 agent_events 数据)Law 06 明确 · 追溯页只对 v2 run 开放 · 老版 run 走老版原 report 页 · UI 上入口分离
R11两版长期共存维护成本 · 双份维护诚实标 · 独立 skill 表意味着 prompt 改动要在两版分别做 · 用飞书群通知内容运营 · 不再粉饰"共用 DB 省成本"
R12alembic 双 head 未 merge · v2 加迁移致部署报错Phase 0 P0.6 必须先做 · merge 现有两个 head 再建 v2 migration · 否则老版也部署不了
R13Seed 无条件覆盖污染 v2 skill 定义v2 用独立的 hash-diff loader · 启动不自动 apply · 不复用老版 _fill_stage_definition_defaults(那有无条件覆盖 bug · Phase 0 P0.4 已隔离)
R14前端同项目两份报告覆盖(v2 二轮 CC 发现)前端 reportsByProjectId 是单值 · 同项目先跑老版再 v2 会覆盖。P2.5 加子步:改成 Map<projectId, {legacy?, v2?}> 支持两份并存 · UI 顶部切换 tab
R15v2 报告绕过每日配额闸门 · 收入泄漏(CC 三轮 P0)assert_can_generate_report 只数 WorkflowRun。P2.4 强制 v2 入口 call 同一 gate + today_report_count 改查 UNION 视图 report_runs_all。e2e 验收:v2 超限被 429
R16agent_v2_queue 无 worker 消费 · 任务永久 pending(CC 三轮 P0)老 worker 命令写死 --queues report_generation。P2.4 强制新增 agent-v2-worker compose 服务 · flower 依赖 · 部署 doc · e2e 验收:投递即被消费
R17v2 出图绕过 CreditLedgerEntry 扣积分 · 收入泄漏D11 待决 A/B · 无论选哪种 · P2.4 验收必测「v2 付费方向出图正确扣积分」
R18v2 无 report_scheduler 治理 · 崩溃 run 永远 running · fan-out 无并发闸P2.4 复刻 v2 版并发闸 + 分布式锁 + _mark_stale_v2_running_runs · 或在 orchestrator 内做 semaphore + heartbeat 兜底
TL;DR · 一页摘要 · 老板直接看这段
做什么
把 PackHorizon 报告生成从 11 步固定 pipeline 升级成 Orchestrator 编排 Skill 的动态 agent 系统
v2 核心
三层混合架构 · Intake (ReAct 对话) · Orchestrator (Plan-and-Execute) · Skills (内部 ReAct 循环) —— 每层选对 pattern
解决什么
1 Intake 从"script bot"变"能上网能识图的顾问" · 2 报告生成从"11 步硬编码"变"Orchestrator 现场规划" · 3 3 个 v2 独占新能力(局部重生成 / 保留复用 / logo 替换)· 老版本身做不到 · P2.9/P2.10/P2.11 独立任务实现 · 4 每份报告可打开 trace 页看 Plan + 每步 · 客服 3 分钟定位投诉根因
怎么做
Phase 0(1.5 周)独立建 v2 骨架 → Phase 1(2 周)ReAct runtime + Orchestrator + 3 skill spike → Phase 2(6-8 周)全量 skill + Intake agent + 3 独占新能力 + UI + 灰度
关键约束
完全独立系统平行运行 · 老 workflow 一行代码不动 · 数据流水线全独立 · 只共用账号 / 素材 / confirmation / 基础设施 · 老版永远兜底
总周期
4 个月到稳定运行 · 期间业务不受影响
下一步
PRD review → 决 D1 + D2 → 开始 Phase 0