不是把 workflow "换个引擎跑" · 而是把 11 步固定 pipeline 升级成"能力箱 + 智能调度"。 Orchestrator 每次拿到用户请求 · 现场规划要调哪些 skill · 用什么顺序 · 哪些可以并行 · 哪些直接跳过复用。 同一套 skill · 覆盖新建 / 升级 / 局部重生成 / 保留复用 4 类场景 · 不再靠硬编码 if/else 堆代码。
在 agent_v2/ 独立目录下 · 平行新建一套 Orchestrator 编排 Skill 的 Agent 系统 —— 老 workflow 一行代码不动 · 一张表不改 · 两套系统平行运行 · 用户前端开关切换。
agent_v2/ · 独立 skill DB 表 · 独立 run/artifact 表 · 独立 API 端点。老版一行代码不动 · 一张表不改。ProjectAsset)· intake confirmation · 底层 LLM 传输原语(provider 路由 / api_key / capability profile) · 基础设施(PG/Redis)· 配额闸门(assert_can_generate_report) · 积分扣费通道(CreditLedgerEntry + ImageGenerationJob)。独立:数据流水线 + 业务状态 + agent 编排逻辑。v2 入口必须显式接配额闸门 · 出图必须走扣费通道 · 否则收入泄漏。state 里的字段名 · 谁在什么时候调都能工作。backend/app/agent_v2/skills/*.yaml · 独立 agent_v2_skill_versions 表 · 生产 DB 只能通过 PR 变更 · 每日 CI 校验 drift · seed 不再无条件覆盖。LLM agent 有 3 种主流架构 pattern · 每种适合不同场景。全部用 ReAct 会成本失控 · 全部用固定 workflow 就退回老版。 正确姿势 · 每层用最合适的 pattern —— 这是 v2 的架构基石。
| 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 里指定) | 硬编码 |
| 适合场景 | 开放式对话 / 单任务 | 多步任务 / 需要步骤预览 | 只知道死板流程 |
核心洞察:PackHorizon 不同环节需求不同 —— intake 是开放式对话(用户随便问)· 报告生成需要让用户能看到步骤(点生成前知道 agent 要干啥)· 单 skill 内部又需要自主搜索抓取。 用一种 pattern 覆盖所有场景 = 商业自杀。
web_search(联网找灵感)· image_recognize(识别用户发的竞品图)·
brand_kb(查这个品牌历史项目)· past_projects(查用户以前做过的方向)·
reference_lib(查内部案例库)。
packaging-intelligence 自己决定搜几次 / 抓几个 URL / 什么时候够了停 ·
copy-compliance 自己决定查哪些品类规则 · 检查哪些高危词。
老 intake-dialogue 只会"照着 script 反问" —— 用户问"辣条包装现在什么创意"就懵。 新的 intake agent 有工具箱 · 自主决定用哪个工具帮用户 · 同时不忘继续收集 confirmation 字段。
Orchestrator 拿到 confirmation + 用户请求 · 先出 plan · 再执行。以下 4 个真实场景 · Orchestrator 各自出不同 plan · 但用同一套 10 skill 能力箱。
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"的干净机制。
alembic current 确认两个 head 都已 stamp/applied · 否则 merge 后 upgrade head 会把未应用的 migration 拉进生产;6e7f8091a2b3 / 9d0e1f2a3b4c)· 生成空 revision;alembic upgrade head 验证。
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 · 财务/配额/用量三个报表共用
project_id / user_id · 复用老版这些实体backend/app/agent_v2/ 目录骨架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)
langgraph>=0.2.55 + langgraph-checkpoint-postgrespackaging_stage_prompts.py 里的 prompt 但不是拷贝 —— v2 的 prompt 要重新设计成"能调工具"的 ReAct 风格 · 声明 tools: 段
agent_v2/loaders.py::apply_skills(dry_run=bool) —— 读 YAML 计算 hash · 只有 hash 变化才 insert 新 version + SET is_current · 禁止无条件覆盖。加 verify_drift() 校验 repo YAML 跟 DB is_current 是否一致
verify_drift.py · drift 时飞书报警到 Park Horizon 群 · README 写明"改 v2 skill 只能通过 PR + apply"
prompt_versions / workflow_run / stage_artifact / seed 逻辑零改动
P1.1 独立任务:先建 ReAct model_runtime 层(3d · 从零搭) —— 老版这层能力为零。
P1.2-P1.5:在 runtime 之上跑 Orchestrator + 3 skill spike · 验证 plan 质量。
tools · 不解析 tool_calls · 无流式。ReAct 循环 + 工具执行器 + tool 消息回填 · 三层都要新建 · 复用老版只到 _request_chat_completion 底层原语。
agent_v2/services/react_runtime.py · 支持 tools 声明 · tool_call 解析 · tool 消息回填 · max_iterations 上限 · repair loop_request_chat_completion · 不复制 provider/api_key 配置PackagingState TypedDict · load_skill(skill_code) loader · state 里 fan-out 字段用 Annotated[dict, merge_by_id]packaging_intelligence / brand_strategy / copy_compliance 三个 skill · 内部 ReAct · gate + repair loopdocs/decisions/2026-XX-agent-v2-go-nogo.md
核心约束:老 workflow 一行代码不动 · 前端开关 opt-in。
v2 独有:多了 Orchestrator UI(plan 预览)+ Skill 10(logo 替换师)· 比 v1 Phase 2 稍复杂。
{plan: [skill_id, ...], parallel_groups: [...], skip: [...], reason: str})POST /api/agent_v2/reports/generate · body 含 orchestrator_hint · 入口必须 call assert_can_generate_report(user) · 超配额同样 429today_report_count 改成查 UNION 视图 report_runs_all · 计入 v2 run(否则 v2 无限白嫖)app.tasks.agent_v2_tasks.run_report · task_routes 到 agent_v2_queue · celery_app.py imports 加 agent_v2_tasksdocker-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 补服务表report.max_parallel_jobs_v2 并发闸 + packhorizon:report:scheduler:lock:v2 分布式锁 + _mark_stale_v2_running_runs(否则崩溃 run 永远 running 无人清)· 也可在 orchestrator 内做 semaphore + heartbeat 兜底ImageGenerationJob + _prepare/_commit_direction_image_charge → CreditLedgerEntry · 否则付费方向出图不扣积分。二选一:A 复用老 run_image_generation_job(推荐 · 保计费)· B 自建独立表(需完整复刻扣费 ledger 逻辑)· D11 待决report_generation/image_generation 队列零改动agent_v2_queue 的任务被 agent-v2-worker 消费(不 pending)CreditLedgerEntry/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 事件流partial_regen 模式 · 只跑指定 skill;
2 report-presentation 支持"只替换某 section"而非整块重装;
3 前端报告页每个 section 加"重新生成"按钮 · 单点触发。
agent_v2_stage_artifacts 只该 skill 的 artifact 更新reuse_from_run_id 字段;
2 复用前先校验 agent_v2_stage_artifacts.hash 跟当前 skill 版本的 input hash 是否匹配;
3 hash 不匹配 → 拒绝复用 · 报警运营。
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 出图)agent_v2/intake/ 目录 · intake ReAct agent 实现;
2 confirmation 收集机制 · 兼容老版数据结构(共用 ProjectAsset + confirmation 落表);
3 前端 intake 页 v2 版 · 支持 tool 结果富文本回复(搜索结果卡片 · 识图结果 · 参考图轮播)。
追溯页跟 v1 骨架级差别 —— 顶部先展示 Orchestrator 的 plan("这次跑了 4 skill · 跳过 6 · 因为是升级只换 logo")· 让人一眼看懂 agent 为什么这样跑。 Timeline 也不再是固定 11 步 · 而是动态显示这次真的跑了哪些 skill · 跳过的用灰色 · 复用的标"复用旧输出"。
upgrade_type=logo_only · 旧包装 asset 已上传 · 品牌策略/合规/创意方向都已有 · 无需重新收集。只需要跑 logo 替换 + 新旧对比 · 报告部分复用旧模板。
docs/decisions/| # | 决策点 | 触发时机 | 决策人 | 影响 |
|---|---|---|---|---|
| D1 | Prompt drift 修复方向 | Phase 0 前 | 后端+PM | 以生产 V36 为准(推荐)vs repo V24 · 建议前者 |
| D2 | Pattern 组合确认(三层) | Kick-off | 后端+PM+老板 | 确认 ReAct + P&E + ReAct · 或调整某层选型 |
| D3 | Phase 1 GO / NO-GO | M2 前 | 后端+PM+老板 | 决定是否投 3-5 周做 Phase 2 |
| D4 | Orchestrator LLM 选型 | P1.4 前 | 后端 | 用 Claude Sonnet 4.5 / GPT-5 / DeepSeek · 影响 plan 质量与成本 |
| D5 | 用户能否手动改 Plan | P2.5 前 | PM+前端 | 只显示(推荐)vs 可编辑 · vip 客户可编辑 |
| D6 | UI 开关默认状态 | 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 报告展示页 & 追溯页全新写 |
| D11 | v2 出图账务路径 | P2.4 前 | 后端+PM | A 复用老 run_image_generation_job + ImageGenerationJob(推荐 · 保 CreditLedgerEntry 扣积分)/ B v2 自建独立表(需复刻完整扣费 ledger) |
| # | 风险 | 概率 | 影响 | 应对 |
|---|---|---|---|---|
| R1 | Orchestrator Plan 质量不稳定(v2 新) | 高 | 高 | Planner 用 few-shot 4 场景 · JSON schema 强约束 · Plan 用小模型跑 fallback safety net · M1 看板监控合理率 |
| R2 | Plan 让用户等太久(v2 新) | 中 | 中 | Planner 用 Haiku 快模型(2 秒内)· Streaming 显示 plan · 用户满意度 vs 老版对比 |
| R3 | 两版长期共存维护成本 | 高 | 中 | 共用 skill_versions DB · 只编排逻辑不同 |
| R4 | Orchestrator + Skill 双层 LLM 成本翻倍 | 中 | 中-高 | Planner 用小模型 · Skill 内部 max_iterations 上限 · 单份成本上限 ¥5 |
| R5 | Skill fan-out 并行放大 API 成本 | 中 | 中-高 | 并行度可配 · 供应商余额告警 · 主推同步其他异步 |
| R6 | Phase 2 撞产品迭代 | 高 | 中 | 分阶段可停 · 老 workflow 继续接需求 · agent_v2 独立 team owner |
| R7 | 灰度期用户体感差 | 低 | 高 | 前端 fallback + 秒回滚 · Plan 预览让用户能拒绝 |
| R8 | LangGraph 版本坑 | 低 | 中 | 用 0.2.55+ · Send / PostgresSaver 已 GA |
| R9 | Skill 复用逻辑 bug(v2 新) | 中 | 高 | stage_artifact 复用前必哈希校验 · replay 单元测覆盖 4 场景 · 出错自动回退 workflow |
| R10 | 老版报告在 v2 追溯页 404(无 agent_events 数据) | 高 | 低 | Law 06 明确 · 追溯页只对 v2 run 开放 · 老版 run 走老版原 report 页 · UI 上入口分离 |
| R11 | 两版长期共存维护成本 · 双份维护 | 高 | 中 | 诚实标 · 独立 skill 表意味着 prompt 改动要在两版分别做 · 用飞书群通知内容运营 · 不再粉饰"共用 DB 省成本" |
| R12 | alembic 双 head 未 merge · v2 加迁移致部署报错 | 高 | 高 | Phase 0 P0.6 必须先做 · merge 现有两个 head 再建 v2 migration · 否则老版也部署不了 |
| R13 | Seed 无条件覆盖污染 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 |
| R15 | v2 报告绕过每日配额闸门 · 收入泄漏(CC 三轮 P0) | 高 | 高 | 老 assert_can_generate_report 只数 WorkflowRun。P2.4 强制 v2 入口 call 同一 gate + today_report_count 改查 UNION 视图 report_runs_all。e2e 验收:v2 超限被 429 |
| R16 | agent_v2_queue 无 worker 消费 · 任务永久 pending(CC 三轮 P0) | 高 | 高 | 老 worker 命令写死 --queues report_generation。P2.4 强制新增 agent-v2-worker compose 服务 · flower 依赖 · 部署 doc · e2e 验收:投递即被消费 |
| R17 | v2 出图绕过 CreditLedgerEntry 扣积分 · 收入泄漏 | 中 | 高 | D11 待决 A/B · 无论选哪种 · P2.4 验收必测「v2 付费方向出图正确扣积分」 |
| R18 | v2 无 report_scheduler 治理 · 崩溃 run 永远 running · fan-out 无并发闸 | 中 | 中 | P2.4 复刻 v2 版并发闸 + 分布式锁 + _mark_stale_v2_running_runs · 或在 orchestrator 内做 semaphore + heartbeat 兜底 |