793 lines
28 KiB
Markdown
793 lines
28 KiB
Markdown
# 视频项目—脚本 Agent 协同引入实施方案
|
||
|
||
> 目标:在不推翻现有视频项目、脚本版本、AITask、计费和人工采用流程的前提下,把当前“一次模型生成脚本”升级为可暂停、可恢复、可审计、可校验、可有限修订的脚本 Agent。
|
||
> 架构原则:松耦合、高内聚、可复用、精简化、可扩展。
|
||
> 代码基线审阅时间:2026-07-17。
|
||
|
||
## 1. 结论先行
|
||
|
||
脚本 Agent 不应等同于“把现有提示词再加长”,也不应一次引入多个可自由互相调用的 Agent。推荐方案是:
|
||
|
||
```text
|
||
一个脚本领域协调器
|
||
+ 一组职责单一的协作节点
|
||
+ 一组受控业务工具
|
||
+ 现有模型、任务、计费和脚本版本能力
|
||
+ 确定性校验优先
|
||
+ 最多一次语义评审、一次定向修订
|
||
+ 用户最终采用
|
||
```
|
||
|
||
协作节点包括:上下文收集、Brief 规划、脚本生成、规则校验、语义评审、定向修订、交接包构建。只有“生成、语义评审、语义修订”可能调用模型;数据读取、字段校验、时长镜数、卖点覆盖、禁用词和落库都由确定性代码完成。
|
||
|
||
这套设计能让脚本功能真正具备 Agent 的核心特征:读取状态、形成计划、调用受控工具、观察校验结果、在预算内决定是否修订、保存过程和等待用户确认。同时避免无限循环、模型乱选工具、重复扣费和错误自动采用。
|
||
|
||
## 2. 当前代码基线与改造边界
|
||
|
||
### 2.1 当前链路
|
||
|
||
```text
|
||
pipeline.tsx 组装 prompt/mode/model
|
||
→ POST /api/projects/{id}/script-agent-stream/
|
||
→ projects/views.py::script_agent_stream
|
||
→ ai/script_agent.py::stream_script_agent
|
||
→ 固定 system + user messages
|
||
→ Provider 单次流式文本调用
|
||
→ normalize_draft
|
||
→ ScriptVersion + ScriptSegment
|
||
→ SSE 返回草稿
|
||
→ 用户调用 adopt-script
|
||
```
|
||
|
||
当前名称包含 `script_agent`,但核心仍是单次模型调用;没有独立运行状态、工具循环、校验决策、运行预算和恢复机制。
|
||
|
||
### 2.2 必须直接复用
|
||
|
||
| 能力 | 当前代码 | 新 Agent 用法 |
|
||
| --- | --- | --- |
|
||
| 商品、项目与阶段 | `apps/products`、`apps/projects` | 通过只读工具访问,不让 Agent 直接 ORM |
|
||
| 脚本模型调用 | `core/backend/apps/ai/script_agent.py` | 拆出纯生成服务,保留旧入口作回退 |
|
||
| 电商脚本 Skill | `script_agent.py` 当前 Skill 加载 | 作为可版本化领域提示模板 |
|
||
| 结构归一化 | `normalize_draft()` | 继续作为兼容层,不承担全部业务校验 |
|
||
| 脚本产物 | `ScriptVersion`、`ScriptSegment` | Agent 草稿仍落现有领域表 |
|
||
| 单次 AI 任务 | `AITask` | 每次生成/评审/修订各一条,不表示整个 Agent 运行 |
|
||
| 模型配置 | `ModelConfig`、Provider | 由模型路由器或用户明确选择 |
|
||
| 积分 | reserve/charge/release | 每个付费步骤继续走现有闭环 |
|
||
| 人工采用 | `adopt-script` | 首期保持,Agent 不自动推进阶段 |
|
||
| 前端流式展示 | `pipeline.tsx`、SSE | 改成 Agent 事件的展示层,不作为真实状态源 |
|
||
|
||
### 2.3 本次不做
|
||
|
||
- 不让脚本 Agent 自动生成图片、故事板或视频;
|
||
- 不自动采用脚本;
|
||
- 不让模型直接访问数据库或任意 HTTP;
|
||
- 不保存或展示模型完整思维过程;
|
||
- 不重写 Provider、计费、脚本版本和项目阶段;
|
||
- 不做多个自由对话 Agent 的互调网络;
|
||
- 不允许无限评审、无限修订或静默换模型。
|
||
|
||
## 3. 五项架构原则如何落到代码
|
||
|
||
| 原则 | 落地方式 | 禁止做法 |
|
||
| --- | --- | --- |
|
||
| 松耦合 | Agent 只依赖工具协议和领域契约;Provider、ORM、计费藏在工具实现后 | 协调器直接查表、直接请求火山接口 |
|
||
| 高内聚 | 脚本规划、脚本校验、脚本交接全部放在 script 领域目录 | 把脚本规则继续堆进通用 `services.py` |
|
||
| 可复用 | Run/Step、预算、权限、事件、模型路由、工具注册为公共基础设施 | 为脚本单独复制任务、计费、SSE 框架 |
|
||
| 精简化 | 固定状态机;首期 1 次生成、可选 1 次评审、最多 1 次修订 | 首期引入通用图式编排器或自由循环 |
|
||
| 可扩展 | 契约带 `schema_version`,工具带版本,策略由 policy 配置 | 依赖自然语言隐式约定字段 |
|
||
|
||
## 4. 推荐代码结构
|
||
|
||
建议新增独立 Django app `core/backend/apps/agents/`,公共运行能力与 AI Provider 分离:
|
||
|
||
```text
|
||
core/backend/apps/agents/
|
||
├─ apps.py
|
||
├─ models.py # AgentRun / AgentStep / AgentArtifact
|
||
├─ enums.py # agent_type、状态、step 类型
|
||
├─ registry.py # Agent 与工具注册表
|
||
├─ runtime.py # 状态机驱动、恢复、取消、步骤上限
|
||
├─ policies.py # 预算、重试、审批策略
|
||
├─ permissions.py # 工具权限和团队边界
|
||
├─ events.py # 运行事件投影,不保存模型思维过程
|
||
├─ routing.py # 能力需求 → ModelConfig
|
||
├─ schemas/
|
||
│ ├─ common.py
|
||
│ └─ script.py # ScriptAgentRequest/Brief/Report/Handoff
|
||
├─ tools/
|
||
│ ├─ base.py # ToolSpec、JSON Schema、执行结果
|
||
│ ├─ project.py # 项目只读工具
|
||
│ ├─ product.py # 商品上下文工具
|
||
│ ├─ models.py # 模型能力与报价工具
|
||
│ └─ script.py # 生成、保存、采用前检查
|
||
├─ script/
|
||
│ ├─ coordinator.py # 脚本 Agent 状态机
|
||
│ ├─ context.py # 输入快照和缺失项
|
||
│ ├─ brief.py # 确定性 Brief 构建
|
||
│ ├─ generator.py # 调用现有 script_agent 纯生成能力
|
||
│ ├─ validators.py # 确定性规则校验
|
||
│ ├─ reviewer.py # 可选语义评审
|
||
│ ├─ reviser.py # 定向修订,最多一次
|
||
│ ├─ handoff.py # 下游结构化交接包
|
||
│ └─ prompt_versions.py # 提示模板版本和兼容策略
|
||
├─ tasks.py # Celery 恢复/继续 AgentRun
|
||
├─ serializers.py
|
||
├─ views.py
|
||
├─ urls.py
|
||
└─ tests/
|
||
├─ test_runtime.py
|
||
├─ test_script_contracts.py
|
||
├─ test_script_agent.py
|
||
└─ test_script_tools.py
|
||
```
|
||
|
||
前端建议:
|
||
|
||
```text
|
||
core/frontend/src/
|
||
├─ api.ts # AgentRun API
|
||
├─ types.ts # 运行与契约类型
|
||
├─ routes/pipeline.tsx # 保留业务页面,替换提交适配器
|
||
└─ components/agent-run/
|
||
├─ run-progress.tsx # 计划和步骤状态
|
||
├─ validation-report.tsx # 错误/警告/通过项
|
||
├─ approval-card.tsx # 报价、采用、继续修订
|
||
└─ input-question-card.tsx # 澄清问题
|
||
```
|
||
|
||
脚本业务规则不放进 `components/agent-run`;公共组件只渲染通用状态。
|
||
|
||
## 5. 公共 Agent 运行数据
|
||
|
||
### 5.1 AgentRun
|
||
|
||
一个 `AgentRun` 表示一次完整脚本协作,不等于一次模型调用。
|
||
|
||
```text
|
||
id
|
||
team_id
|
||
created_by_id
|
||
agent_type script
|
||
scope_type project
|
||
scope_id project_id
|
||
goal 用户目标摘要
|
||
status created/collecting/waiting_user/planning/
|
||
waiting_approval/running/waiting_task/
|
||
validating/needs_review/succeeded/failed/
|
||
cancelled/budget_exhausted/stale
|
||
schema_version script-agent-request/v1
|
||
input_snapshot 冻结后的输入
|
||
policy_snapshot 本次预算和重试规则
|
||
plan 简短结构化计划
|
||
current_step
|
||
estimated_cost
|
||
actual_cost
|
||
stop_reason_code
|
||
stop_reason_message
|
||
lock_version 乐观锁,防并发继续
|
||
started_at/completed_at
|
||
```
|
||
|
||
### 5.2 AgentStep
|
||
|
||
```text
|
||
id
|
||
run_id
|
||
sequence
|
||
step_type collect/plan/tool/model/validate/review/
|
||
revise/persist/approval/handoff
|
||
name
|
||
tool_name/tool_version
|
||
input_summary 脱敏、可审计输入
|
||
output_summary 结构化摘要
|
||
status
|
||
idempotency_key 同一运行内唯一
|
||
ai_task_id 模型步骤关联现有 AITask
|
||
estimated_cost/actual_cost
|
||
attempt
|
||
error_code/error_message
|
||
started_at/completed_at
|
||
```
|
||
|
||
### 5.3 AgentArtifact
|
||
|
||
Agent 不复制完整脚本,只引用现有产物:
|
||
|
||
```text
|
||
run_id
|
||
step_id
|
||
artifact_type script_version / script_handoff /
|
||
validation_report / brief
|
||
object_type
|
||
object_id
|
||
version
|
||
summary
|
||
metadata
|
||
```
|
||
|
||
`ScriptVersion` 仍是脚本真相源;AgentArtifact 只是说明“哪个运行生成或检查了哪个版本”。
|
||
|
||
## 6. 输入契约
|
||
|
||
### 6.1 前端请求 `ScriptAgentRequest/v1`
|
||
|
||
```json
|
||
{
|
||
"schema_version": "script-agent-request/v1",
|
||
"project_id": "uuid",
|
||
"mode": "auto | theme | manual | revise | revise_segment",
|
||
"instruction": "用户补充主题或修改意见",
|
||
"source_script_version_id": null,
|
||
"target_segment_id": null,
|
||
"selected_selling_point_ids": ["uuid"],
|
||
"preferences": {
|
||
"style": "真实测评",
|
||
"character": "都市白领女性",
|
||
"duration_seconds": 30,
|
||
"aspect_ratio": "9:16"
|
||
},
|
||
"model_policy": {
|
||
"mode": "explicit | auto",
|
||
"model_config_id": "可选",
|
||
"quality": "standard",
|
||
"cost_ceiling_points": 30
|
||
},
|
||
"idempotency_key": "前端生成的 UUID"
|
||
}
|
||
```
|
||
|
||
关键修正:卖点必须传真实 ID,不再把标题装进 `selling_point_ids`;后端读取 ID 后保存卖点标题和内容快照,保证后续商品修改不改变本次运行事实。
|
||
|
||
### 6.2 冻结输入 `ScriptContextSnapshot/v1`
|
||
|
||
```json
|
||
{
|
||
"project": {
|
||
"id": "...",
|
||
"updated_at": "...",
|
||
"current_stage": "script",
|
||
"product_id": "..."
|
||
},
|
||
"product": {
|
||
"id": "...",
|
||
"updated_at": "...",
|
||
"title": "...",
|
||
"brand": "...",
|
||
"category": "...",
|
||
"description": "...",
|
||
"target_audience": "...",
|
||
"specs": {},
|
||
"selected_selling_points": [
|
||
{"id": "...", "title": "...", "content": "..."}
|
||
]
|
||
},
|
||
"creative": {
|
||
"mode": "theme",
|
||
"instruction": "早八通勤场景",
|
||
"style": "真实测评",
|
||
"character": "都市白领女性",
|
||
"duration_seconds": 30,
|
||
"aspect_ratio": "9:16",
|
||
"shot_policy": {"shot_count": 2, "shot_duration_seconds": 15}
|
||
},
|
||
"source_script": null
|
||
}
|
||
```
|
||
|
||
运行期间只使用 snapshot;保存前再比较 project/product `updated_at`。发生关键变更则运行转 `stale`,禁止直接采用旧结果。
|
||
|
||
## 7. 协作角色与职责边界
|
||
|
||
| 协作节点 | 类型 | 输入 | 输出 | 是否调用模型 |
|
||
| --- | --- | --- | --- | --- |
|
||
| ScriptCoordinator | 状态机 | AgentRun | 下一合法步骤 | 否 |
|
||
| ContextCollector | 工具组合 | project_id、request | ContextSnapshot、缺失项 | 否 |
|
||
| BriefBuilder | 领域规则 | ContextSnapshot | ScriptBrief | 首期否 |
|
||
| ScriptGenerator | 生成器 | Brief、输出契约 | ScriptDraft | 是,最多 1 次 |
|
||
| ContractNormalizer | 兼容器 | 模型原始文本 | 规范化草稿 | 否 |
|
||
| ScriptValidator | 规则引擎 | Draft、Snapshot | ValidationReport | 否 |
|
||
| SemanticReviewer | 独立评审 | Draft、rubric | ReviewReport | 可选,最多 1 次 |
|
||
| ScriptReviser | 修订器 | Draft、可修复问题 | 新 Draft | 是,最多 1 次 |
|
||
| DraftPersister | 领域服务 | Draft、reports | ScriptVersion | 否 |
|
||
| HandoffBuilder | 领域服务 | ScriptVersion、reports | ScriptHandoff | 否 |
|
||
|
||
这里的“协同”通过结构化产物完成,不传递长篇聊天历史,也不让节点自由决定调用任意下一节点。
|
||
|
||
## 8. Agent 状态机
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> Collecting
|
||
Collecting --> WaitingUser: 必填事实缺失或口径冲突
|
||
WaitingUser --> Collecting: 用户补充
|
||
Collecting --> Planning: 上下文完整
|
||
Planning --> WaitingApproval: 超过自动预算或用户要求确认
|
||
Planning --> Generating: 预算内
|
||
WaitingApproval --> Generating: 用户批准
|
||
Generating --> WaitingTask: AITask 在执行
|
||
WaitingTask --> Validating: 生成完成
|
||
Validating --> Persisting: 无错误且无需语义评审
|
||
Validating --> Reviewing: 仅有语义风险
|
||
Validating --> Revising: 存在可自动修复问题且未修订
|
||
Reviewing --> Persisting: 通过或只有警告
|
||
Reviewing --> Revising: 可修复且未修订
|
||
Revising --> WaitingTask: 修订任务已提交
|
||
Validating --> NeedsReview: 不可修复或已达上限
|
||
Reviewing --> NeedsReview: 高风险或已达上限
|
||
Persisting --> HumanReview
|
||
NeedsReview --> HumanReview
|
||
HumanReview --> Succeeded: 用户采用
|
||
HumanReview --> Planning: 用户给出新修改意见
|
||
HumanReview --> Cancelled: 用户放弃
|
||
Succeeded --> [*]
|
||
```
|
||
|
||
每次恢复只根据数据库状态和最后成功步骤继续;SSE 断开不会取消后端运行。用户主动取消时,尚未提交的步骤停止;已提交 AITask 按现有任务能力取消或等待完成,但不得重复提交。
|
||
|
||
## 9. 工具接口设计
|
||
|
||
### 9.1 工具统一协议
|
||
|
||
```python
|
||
class AgentTool:
|
||
name: str
|
||
version: str
|
||
permission: str
|
||
input_schema: dict
|
||
output_schema: dict
|
||
|
||
def execute(self, context, arguments) -> ToolResult:
|
||
...
|
||
```
|
||
|
||
统一 `ToolResult`:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"data": {},
|
||
"warnings": [],
|
||
"error": null,
|
||
"audit": {"source_versions": {}, "duration_ms": 12}
|
||
}
|
||
```
|
||
|
||
### 9.2 脚本 Agent 工具
|
||
|
||
| 工具 | 权限 | 复用代码 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `get_project_script_context.v1` | 只读 | Project、metadata、stage | 返回项目配置和真实状态 |
|
||
| `get_product_context.v1` | 只读 | Product、SellingPoint | 返回事实和版本快照 |
|
||
| `get_source_script.v1` | 只读 | ScriptVersion/Segment | revise 时读取源版本 |
|
||
| `quote_text_generation.v1` | 只读 | 现有 pricing | 生成/评审/修订前报价 |
|
||
| `generate_script_draft.v1` | 付费 | `stream_script_agent` 拆出的生成内核 | 只负责一次结构化生成 |
|
||
| `review_script_semantics.v1` | 付费可选 | 文本 Provider | 只返回评审 JSON,不改稿 |
|
||
| `revise_script_draft.v1` | 付费 | 文本 Provider | 只修指定 issue_code |
|
||
| `save_script_version.v1` | 低风险写 | `persist_script_draft()` | 保存未采用版本 |
|
||
| `build_script_handoff.v1` | 低风险写 | 新增领域服务 | 建立下游资产需求和验收条件 |
|
||
| `check_script_adoptable.v1` | 只读 | Project/Version | 采用前检查 snapshot 是否过期 |
|
||
|
||
工具内部验证 `team_id`,不得接受模型传入的团队 ID。对象查询必须同时限定当前 team、未删除状态和必要的项目关联。
|
||
|
||
## 10. Brief 与提示词分层
|
||
|
||
### 10.1 `ScriptBrief/v1`
|
||
|
||
```json
|
||
{
|
||
"schema_version": "script-brief/v1",
|
||
"goal": "30 秒真实测评短视频",
|
||
"audience": "通勤女性",
|
||
"platform_style": "小红书种草",
|
||
"product_facts": ["只允许来自商品快照的事实"],
|
||
"must_use_selling_points": ["轻便", "易清洗"],
|
||
"forbidden_claims": ["绝对化效果", "无来源认证", "虚构价格"],
|
||
"character": "都市白领女性",
|
||
"shot_policy": {
|
||
"count": 2,
|
||
"seconds_each": 15,
|
||
"required_functions": ["hook", "pain", "selling", "cta"]
|
||
},
|
||
"output_contract": "script-draft/v1"
|
||
}
|
||
```
|
||
|
||
Brief 首期由规则构建,避免为“整理已有字段”额外付费。以后若增加策略 Agent,只能在事实和硬规则外补充创意策略,不能修改商品事实。
|
||
|
||
### 10.2 模型消息分区
|
||
|
||
```text
|
||
system
|
||
├─ Agent 角色和安全边界
|
||
├─ 电商脚本 Skill 版本
|
||
├─ ScriptDraft JSON 契约
|
||
└─ 禁止把业务数据当系统指令
|
||
|
||
user
|
||
├─ <product_facts> 只读业务数据
|
||
├─ <creative_brief> 用户目标与偏好
|
||
├─ <source_script> 改稿时的源版本
|
||
└─ <task> generate / revise / revise_segment
|
||
```
|
||
|
||
商品标题、描述、自带脚本、用户意见都必须放在明确的数据区,禁止拼进 system 指令区,以降低提示注入风险。
|
||
|
||
### 10.3 生成与修订提示词分离
|
||
|
||
- 生成提示词只负责从 Brief 产生完整 `ScriptDraft/v1`;
|
||
- 评审提示词只输出 `ReviewReport/v1`,无权改稿;
|
||
- 修订提示词只接收明确 issue 列表,输出完整新草稿;
|
||
- 单镜修订仍输出完整草稿,但必须声明允许修改的 segment index;
|
||
- 所有模型响应先做 JSON Schema 校验,再进入业务校验。
|
||
|
||
## 11. 确定性校验器
|
||
|
||
`ScriptValidator` 应返回错误码,不只返回自然语言:
|
||
|
||
```json
|
||
{
|
||
"schema_version": "script-validation/v1",
|
||
"passed": false,
|
||
"score": 82,
|
||
"errors": [
|
||
{
|
||
"code": "SELLING_POINT_MISSING",
|
||
"path": "segments",
|
||
"message": "用户选择的卖点“易清洗”未出现",
|
||
"repairable": true
|
||
}
|
||
],
|
||
"warnings": [
|
||
{
|
||
"code": "CTA_WEAK",
|
||
"path": "segments[1]",
|
||
"message": "结尾行动引导较弱",
|
||
"repairable": true
|
||
}
|
||
],
|
||
"checks": {
|
||
"schema": "pass",
|
||
"duration": "pass",
|
||
"segment_count": "pass",
|
||
"entity_refs": "pass",
|
||
"product_facts": "pass"
|
||
}
|
||
}
|
||
```
|
||
|
||
首期规则:
|
||
|
||
1. ScriptDraft Schema、必填字段和类型;
|
||
2. 镜数与唯一时长策略一致;
|
||
3. 单镜时长、总时长和排序一致;
|
||
4. 单镜旁白字数上限;
|
||
5. hook/pain/selling/cta 覆盖;
|
||
6. 所选卖点 ID 对应内容是否覆盖;
|
||
7. 商品、人物、场景实体引用是否存在;
|
||
8. `@图N` 是否能映射到实体;
|
||
9. 价格、折扣、认证、功效是否有事实来源;
|
||
10. 绝对化、违禁和风险表达;
|
||
11. 下游所需人物、场景、商品资产是否可形成清单;
|
||
12. revise_segment 是否误改其他镜头。
|
||
|
||
只有表达自然度、镜头连贯性、钩子吸引力、转化节奏等难以确定性判断的内容进入语义评审。
|
||
|
||
## 12. 语义评审与定向修订
|
||
|
||
### 12.1 何时评审
|
||
|
||
- 规则全部通过但策略配置要求高质量评审;
|
||
- 存在 `semantic_review_required` 类型警告;
|
||
- 用户选择 production 质量档;
|
||
- 不对所有普通运行强制增加一次模型费用。
|
||
|
||
### 12.2 `ScriptReviewReport/v1`
|
||
|
||
```json
|
||
{
|
||
"passed": true,
|
||
"dimensions": {
|
||
"hook": 4,
|
||
"continuity": 4,
|
||
"clarity": 5,
|
||
"conversion": 4,
|
||
"fact_safety": 5
|
||
},
|
||
"issues": [
|
||
{
|
||
"code": "HOOK_TOO_GENERIC",
|
||
"segment_index": 0,
|
||
"severity": "warning",
|
||
"repair_instruction": "保留商品事实,只改写前两句为通勤冲突"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
评审器不能直接采用脚本,也不能自行调用修订。Coordinator 根据 policy、预算、问题是否可修复和剩余次数决定下一步。
|
||
|
||
### 12.3 修订边界
|
||
|
||
- 最多 1 次自动修订;
|
||
- 只传结构化 issue 和原草稿,不传冗长聊天记录;
|
||
- 修订后必须重新跑全部确定性规则;
|
||
- 不再递归进行第二次自动修订;
|
||
- 仍未通过则保存带报告的候选或进入 `needs_review`,交给用户。
|
||
|
||
## 13. 模型路由
|
||
|
||
Agent 声明能力,不直接写供应商名称:
|
||
|
||
```json
|
||
{
|
||
"capability": "text",
|
||
"requires": {
|
||
"structured_json": true,
|
||
"streaming": true,
|
||
"context_tokens_min": 16000
|
||
},
|
||
"preferences": {
|
||
"quality": "standard",
|
||
"cost_ceiling_points": 30
|
||
}
|
||
}
|
||
```
|
||
|
||
首期兼容策略:
|
||
|
||
- 用户明确选择豆包/Gemini:尊重选择,校验模型可用性;
|
||
- 用户选择“自动”:路由器按 capability、健康度、成本和历史契约通过率排序;
|
||
- 生成失败不自动跨模型重复扣费,除非错误明确属于可安全回退的 provider 暂时故障且 policy 允许;
|
||
- 连续结构失败最多改用一次严格 JSON 提示,不无限切换;
|
||
- 路由结果写入 AgentStep 和 AITask,页面展示实际模型。
|
||
|
||
## 14. 产物与下游交接
|
||
|
||
### 14.1 ScriptVersion
|
||
|
||
通过或带可接受警告的草稿使用现有 `persist_script_draft()` 保存:
|
||
|
||
- `ScriptVersion.is_adopted = false`;
|
||
- `ScriptSegment` 保存逐镜字段;
|
||
- metadata 保存 hook、tone、entities;
|
||
- 增加 `agent_run_id`、contract_version、validation_summary、source_snapshot_hash;
|
||
- 不自动改变项目阶段。
|
||
|
||
### 14.2 `ScriptHandoff/v1`
|
||
|
||
```json
|
||
{
|
||
"schema_version": "script-handoff/v1",
|
||
"project_id": "...",
|
||
"script_version_id": "...",
|
||
"goal": "30 秒真实测评",
|
||
"product_fact_snapshot_hash": "...",
|
||
"segments": [
|
||
{
|
||
"index": 0,
|
||
"purpose": "hook+pain",
|
||
"duration_seconds": 15,
|
||
"entities": ["product_1", "person_1", "scene_1"],
|
||
"required_assets": [
|
||
{"entity_id": "product_1", "kind": "product", "view": "front"},
|
||
{"entity_id": "person_1", "kind": "person", "view": "portrait"}
|
||
],
|
||
"acceptance": ["商品前 3 秒内露出", "人物形象跨镜一致"]
|
||
}
|
||
],
|
||
"validation_report_id": "...",
|
||
"open_questions": [],
|
||
"user_approved": false
|
||
}
|
||
```
|
||
|
||
未来视觉资产 Agent、故事板 Agent 只读取这个交接包和已采用 ScriptVersion,不读取脚本 Agent 的聊天记录。
|
||
|
||
## 15. API 设计
|
||
|
||
建议新增:
|
||
|
||
```http
|
||
POST /api/projects/{project_id}/script-agent-runs/
|
||
GET /api/agent-runs/{run_id}/
|
||
GET /api/agent-runs/{run_id}/steps/
|
||
GET /api/agent-runs/{run_id}/events/?after={sequence}
|
||
POST /api/agent-runs/{run_id}/actions/
|
||
```
|
||
|
||
`actions`:
|
||
|
||
```json
|
||
{"action": "provide_input", "payload": {...}}
|
||
{"action": "approve_budget"}
|
||
{"action": "request_revision", "instruction": "..."}
|
||
{"action": "adopt_artifact", "artifact_id": "..."}
|
||
{"action": "cancel"}
|
||
```
|
||
|
||
SSE 可保留为:
|
||
|
||
```http
|
||
GET /api/agent-runs/{run_id}/events/stream/?after={sequence}
|
||
```
|
||
|
||
但 SSE 只投影数据库状态;断线重连使用 `after` 续传。首期若不增加持久事件表,可用 AgentStep + Run 状态轮询实现,先保证恢复正确,再优化实时动画。
|
||
|
||
现有 `script-agent-stream` 保留为 feature flag 下的 legacy fallback,灰度稳定后再逐步下线。
|
||
|
||
## 16. 前端交互
|
||
|
||
保留当前脚本页面,不把整个页面改成聊天框。新增四类可验证卡片:
|
||
|
||
1. **输入摘要**:商品、卖点、时长、风格、人物、主题;
|
||
2. **执行计划**:收集 → 生成 → 校验 → 可选修订 → 保存;
|
||
3. **校验报告**:错误、警告、通过项、实际模型和费用;
|
||
4. **候选脚本**:版本差异、请求修改、采用。
|
||
|
||
当前页面“思考、自检完成”等文字必须改成真实状态:只有对应 AgentStep 成功才显示完成;不能再用前端硬编码步骤制造已校验的假象。
|
||
|
||
## 17. 幂等、并发、恢复和取消
|
||
|
||
- 创建运行使用 `(team_id, idempotency_key)` 唯一约束;
|
||
- 每个步骤使用 `(run_id, step_name, attempt)` 唯一幂等键;
|
||
- Coordinator 更新使用 `select_for_update` 或 lock_version;
|
||
- 同一项目同一 agent_type 默认只允许一个活动运行;
|
||
- 付费步骤先创建 AgentStep,再创建/关联 AITask;
|
||
- `waiting_task` 恢复时查询原 AITask,不新建任务;
|
||
- Worker 崩溃后由恢复任务扫描活动 Run;
|
||
- 用户取消只阻止后续步骤,已完成产物仍保留审计;
|
||
- 用户修改商品/项目后,旧运行输入 hash 不一致则标记 stale;
|
||
- adopt 前再次执行 `check_script_adoptable`。
|
||
|
||
## 18. 预算和权限
|
||
|
||
默认 policy:
|
||
|
||
```json
|
||
{
|
||
"max_steps": 8,
|
||
"max_generation_calls": 1,
|
||
"max_review_calls": 1,
|
||
"max_revision_calls": 1,
|
||
"max_total_points": 60,
|
||
"auto_spend_points": 30,
|
||
"allow_model_fallback": false,
|
||
"require_human_adoption": true
|
||
}
|
||
```
|
||
|
||
权限分级:
|
||
|
||
- 自动允许:读项目/商品、构建 Brief、规则校验、保存检查报告;
|
||
- 预算内允许:生成、可选评审、一次修订;
|
||
- 必须确认:超自动预算、采用脚本、改变项目阶段;
|
||
- 禁止:外部发布、删除用户版本、绕过团队权限。
|
||
|
||
## 19. 错误分类与降级
|
||
|
||
| 错误 | 处理 |
|
||
| --- | --- |
|
||
| `CONTEXT_MISSING` | waiting_user,列出缺失字段 |
|
||
| `INPUT_STALE` | 标记 stale,要求基于新数据重开/刷新 |
|
||
| `MODEL_UNAVAILABLE` | 若用户明确模型则停止;自动模式可重新报价候选 |
|
||
| `CONTRACT_INVALID` | 使用 normalize 兼容一次;仍失败则停止 |
|
||
| `VALIDATION_FAILED` | 可修复且有预算则修订一次,否则 needs_review |
|
||
| `BUDGET_EXCEEDED` | waiting_approval/budget_exhausted |
|
||
| `CLIENT_DISCONNECTED` | 后端继续,前端可恢复 |
|
||
| `PROVIDER_ERROR` | AITask 现有退款;Run 记录错误,不重复扣费 |
|
||
|
||
旧生成入口始终可作为人工选择的回退,不由系统无提示自动切换。
|
||
|
||
## 20. 测试方案
|
||
|
||
### 20.1 单元测试
|
||
|
||
- Request/Snapshot/Brief/Draft/Handoff Schema;
|
||
- 卖点 ID 与快照;
|
||
- 时长、镜数、字数、实体、CTA、风险词校验;
|
||
- revise_segment 不得修改其他镜;
|
||
- 工具 team 权限;
|
||
- 路由和预算策略;
|
||
- 状态机所有合法/非法迁移;
|
||
- 幂等键和重复 Celery 投递。
|
||
|
||
### 20.2 集成测试
|
||
|
||
- auto/theme/manual/revise/revise_segment 五种模式;
|
||
- 生成 → 校验通过 → 保存未采用版本;
|
||
- 生成 → 校验失败 → 修订一次 → 通过;
|
||
- 修订后仍失败 → needs_review;
|
||
- SSE 断开后恢复;
|
||
- provider 失败退款;
|
||
- 项目中途修改导致 stale;
|
||
- 用户采用后现有 `adopt-script` 同步镜头数量;
|
||
- legacy 与 Agent 灰度并存。
|
||
|
||
### 20.3 验收指标
|
||
|
||
- ScriptDraft 一次契约通过率;
|
||
- 商品事实错误率;
|
||
- 所选卖点覆盖率;
|
||
- 规则一次通过率;
|
||
- 自动修订成功率;
|
||
- 用户直接采用率;
|
||
- 采用前修改次数;
|
||
- 单次运行平均调用数、积分、耗时;
|
||
- 下游缺失实体/资产比例;
|
||
- 用户拒绝原因分布。
|
||
|
||
## 21. 分阶段实施
|
||
|
||
### 阶段 A:公共最小运行时
|
||
|
||
- AgentRun、AgentStep、AgentArtifact;
|
||
- 固定状态机、幂等、恢复、取消;
|
||
- 工具注册、Schema、权限;
|
||
- 预算策略和 AITask 关联;
|
||
- 查询 API 和最小前端状态展示。
|
||
|
||
### 阶段 B:拆出现有脚本生成内核
|
||
|
||
- 把 `stream_script_agent()` 中上下文、提示词、模型调用、归一化、持久化拆成可独立测试服务;
|
||
- 旧 API 继续调用这些服务;
|
||
- 不改变现有业务结果。
|
||
|
||
### 阶段 C:脚本 Agent MVP
|
||
|
||
- ContextSnapshot、Brief;
|
||
- 生成一次;
|
||
- 确定性校验;
|
||
- 保存候选和 Handoff;
|
||
- 人工采用;
|
||
- 不接语义评审和自动修订。
|
||
|
||
### 阶段 D:有限协同
|
||
|
||
- 可选语义评审;
|
||
- 最多一次定向修订;
|
||
- 报价和预算确认;
|
||
- 输入过期检查;
|
||
- 真实步骤 UI。
|
||
|
||
### 阶段 E:灰度与优化
|
||
|
||
- 团队 feature flag;
|
||
- 对照旧链路采用率、费用和失败率;
|
||
- 根据 issue 数据优化规则,不靠盲目加提示词;
|
||
- 稳定后供项目导演 Agent 通过 Handoff 调用。
|
||
|
||
## 22. 一人串行开发工作量参考
|
||
|
||
以下为现有代码可复用、使用编码工具辅助、需求口径已确认后的研发量,不包含大规模 UI 重做和生产数据迁移异常处理:
|
||
|
||
| 工作 | 参考工期 |
|
||
| --- | ---: |
|
||
| 公共最小 AgentRun/Step/Artifact、状态机、工具协议 | 3–4 天 |
|
||
| 拆分现有脚本生成服务并保持旧接口兼容 | 1.5–2 天 |
|
||
| Snapshot、Brief、校验器、Handoff | 2–3 天 |
|
||
| Agent API、Celery 恢复、预算与幂等 | 2–3 天 |
|
||
| 前端真实步骤、报告、确认与恢复 | 2–3 天 |
|
||
| 语义评审和一次修订 | 1.5–2 天 |
|
||
| 单元/集成测试、灰度开关和修正 | 2–3 天 |
|
||
|
||
合计约 **14–20 人天**。如果公共 Agent 基础设施已由平台套图或其他 Agent 建好,脚本领域自身约 **8–12 人天**。MVP 先不做语义评审与自动修订,可压缩到约 **9–13 人天(含公共最小运行时)**。
|
||
|
||
## 23. 最终落地形态
|
||
|
||
```text
|
||
用户配置脚本目标
|
||
→ Script Agent 冻结项目和商品事实
|
||
→ 规则构建 Brief
|
||
→ 报价和模型路由
|
||
→ 生成完整 ScriptDraft
|
||
→ 确定性校验
|
||
→ 可选独立语义评审
|
||
→ 最多一次定向修订并重新校验
|
||
→ 保存未采用 ScriptVersion
|
||
→ 生成 ScriptHandoff
|
||
→ 用户确认采用
|
||
→ 下游视觉/故事板读取结构化交接包
|
||
```
|
||
|
||
这不是把现有“脚本助手”换一个名称,而是补齐运行状态、工具边界、观察校验、有限决策、预算、恢复和交接能力。实现后,脚本节点才具备受控 Agent 的实质,同时仍保持现有 AirShelf 项目流水线的稳定边界。
|