Fusion Runtime
Fusion 现在有了 agent-owned 运行时基础设施,用于承载新的 langgraph/state graph 执行路径,而不影响现有老 Agent 的运行方式。
一图看懂
flowchart LR
Agent[Agent]
Draft[Live Fusion Draft on Agent]
Version[Published Agent Version]
Run[Fusion Run]
RAG[RAG Binding]
MCP[MCP Binding]
Model[Model Binding]
Outputs[Persisted Outputs]
Agent --> Draft
Draft --> Version
Version --> Run
Run --> RAG
Run --> MCP
Run --> Model
RAG --> Outputs
MCP --> Outputs
Model --> Outputs
已落地范围
- 新增
Fusion运行时与 agent-owned snapshot 模型: agents中的 live Fusion draft 字段agent_versions中的 immutable Fusion snapshot 字段fusion_runsfusion_run_inputsfusion_run_outputs- 当前主控制面 API:
PATCH /agents/{agent_id}保存 live Fusion draftGET /agents/{agent_id}/versionsPOST /agents/{agent_id}/publish- 当前运行时 API:
POST /agents/{agent_id}/fusion-runsGET /agents/{agent_id}/fusion-runsGET /agents/{agent_id}/fusion-runs/{run_id}POST /agents/{agent_id}/fusion-runs同时接受 JSONinput_item_list和 multipart form-data 文件上传;multipart 文件字段名必须等于 input slot key- 新增
AgentTypeRegistry插件族: fusion- 新增 Fusion worker lifecycle:
ai_service/fusion/infrastructure/workers/fusion_run_worker.py- 新增 LangGraph 运行骨架节点:
load_definition_nodevalidate_definition_contract_nodevalidate_run_inputs_nodepersist_validated_inputs_noderesolve_capability_bindings_nodeprepare_file_artifacts_noderetrieve_context_nodebuild_prompt_nodeplan_tool_usage_nodeinvoke_tools_nodeinvoke_model_nodenormalize_outputs_nodevalidate_outputs_nodepersist_outputs_nodefinalize_run_node
运行约束
- 每次运行都绑定到一个不可变的
agent_version_id。 - 每次运行在创建时都会分配一个持久化
trace_id,用于把 API 返回的 run 记录与 Langfuse trace 对齐。 POST /agents/{agent_id}/fusion-runs现在只负责校验、持久化输入并 enqueue;实际执行由 Fusion worker 从持久化 ledger claim。- run ledger 会记录
attempt_count、lease_token、last_attempt_started_at、worker_heartbeat_at,用于表达 claim / lease / heartbeat 真相。 - 执行中的 run 会周期性刷新
worker_heartbeat_at;如果服务中断导致心跳停止,超出[fusion].worker_stale_seconds后,stalequeued/pending/runningrun 会被 supervisor 收敛为failed。 - 输入合约会在模型调用前做严格校验。
- 输出合约会在持久化前做严格校验。
- Phase 1 里 MCP、RAG、存储、图像能力都通过 adapter 接入。
- 现有老 Agent API 与运行时保持不变。
- 当版本的
prompting_config.enable_json_object_response_format=true且存在structured_json输出槽时,运行时会优先尝试 provider-nativeresponse_format={"type":"json_object"} - 当版本的
prompting_config.enable_pdf_file_image_conversion=true时,运行时会把application/pdf文件输入渲染为逐页 PNG 图片并作为 multimodal image blocks 注入模型 - PDF 渲染 DPI 由
prompting_config.pdf_file_image_conversion_dpi控制,默认150,允许范围72-300 - 当某个
structured_json输出槽声明structured_output_schema时,runtime 会优先使用这份显式 nested schema 生成 provider-facing structured output schema,并在输出阶段执行递归校验 - 如果 provider/model 不支持该模式,或 native 调用失败,运行时会自动回退到原有 prompt-only 路径,并记录 warning 与治理快照字段
- 当
structured_json输出槽声明output_instruction_fragment时,prompt builder 只会拼接这份显式可见的 slot instruction;不会再基于 profile 水下追加隐藏 prompt 文本 - 当
structured_json输出槽声明structured_output_profile="document_field_set"时,validator 仍会追加 document-style 结构校验,但 schema / prompt 都来自持久化后的显式 contract
执行时序
sequenceDiagram
participant Studio as Studio or API Client
participant LabAPI as /lab API
participant RunService as Run Service
participant Worker as Fusion Worker
participant Runtime as Fusion Runtime
participant Agent as Owning Agent
participant RAG as RAG Adapter
participant MCP as MCP Adapter
participant Model as Model Binding
participant DB as Persistence
Studio->>LabAPI: POST /agents/{agent_id}/fusion-runs
LabAPI->>RunService: validate inputs and enqueue run
RunService->>DB: persist queued run and inputs
LabAPI-->>Studio: return queued run detail
Worker->>DB: claim queued run with lease_token
Worker->>Runtime: execute run by run_id
Runtime->>DB: load agent version snapshot and persisted inputs
Runtime->>Agent: resolve owning agent context
Runtime->>RAG: resolve rag binding with inherited agent_id
Runtime->>MCP: resolve mcp binding with inherited agent_id
Runtime->>Model: build prompt and invoke model
Runtime->>Model: best-effort native json_object response_format when enabled
Runtime->>DB: persist outputs and finalize status
Worker->>DB: complete or fail run
Agent 继承
- Fusion runtime 直接把 route path 上的
agent_id作为默认继承上下文注入 runtime state。 capability_bindings.rag.agent_id未显式指定时,会默认继承 owning Agent,并直接复用该 Agent 已挂载的 knowledge sources。capability_bindings.mcp.agent_id未显式指定时,也会默认继承 owning Agent,并按该 Agent 的 MCP mounts 解析可用工具清单。capability_bindings.model在未显式指定provider/model_name时,仍会复用 agent fallback 或全局config.chat_model的 provider/name;但temperature只认 binding 自身或 fallback config,缺省时固定回退到0.0,不会继承config.chat_model.temperature。- 显式写入
capability_bindings.rag.agent_id或capability_bindings.mcp.agent_id时,优先使用 version 自己的配置。
数据关系
erDiagram
AGENTS ||--o{ AGENT_VERSIONS : snapshots
AGENTS ||--o{ AGENT_LAB_RUNS : executes
AGENT_LAB_RUNS ||--o{ AGENT_LAB_RUN_INPUTS : stores
AGENT_LAB_RUNS ||--o{ AGENT_LAB_RUN_OUTPUTS : stores
AGENTS {
string id PK
string agent_type
}
AGENT_VERSIONS {
string id PK
string agent_id FK
int version_number
}
AGENT_LAB_RUNS {
string id PK
string agent_id FK
string agent_version_id FK
string status
}
这张图表达的是当前实现里的核心落点:
Agent持有 live Fusion draft。AgentVersion持有不可变 Fusion runtime snapshot。Fusion Run是执行记录,直接指向Agent和不可变AgentVersion。Fusion Run同时也是 worker-led run ledger,会持久化attempt_count、lease_token、last_attempt_started_at、worker_heartbeat_at。- 新创建的
Fusion Run会持久化一份 run 级别的governance_context快照,避免后续 Agent mounts 变化污染历史审计结果。 - 对缺少快照的 legacy run,API 只返回基于 definition version 的保守治理视图,不会在读取时按当前 Agent mounts 反推或补写历史快照。
governance_context现在还会记录:response_format_requestedresponse_format_appliedresponse_format_fallback_reasonresolved_model_providerresolved_model_nameprompt_messagesmodel_raw_responsenormalized_outputsvalidation_error_detail
JSON Object Response Format
当版本配置开启 enable_json_object_response_format 时,Fusion 运行时会保持原有 output_contract prompt 注入,同时额外尝试 native JSON object 模式。
当版本配置开启 enable_pdf_file_image_conversion 时,Fusion 运行时会在 prompt 构建阶段识别 application/pdf 文件输入,并把每页按 pdf_file_image_conversion_dpi 渲染成图片 block。这个流程主要面向 vision-capable 模型;如果开关关闭,PDF 只会按普通 file 输入处理。
- 开启前提:版本必须声明至少一个
structured_json输出槽;控制面会在保存时校验 - native 成功:
model_raw_response会包含稳定的json_output,输出映射仍走现有structured_json归一化和校验链路 - native 失败或不支持:自动回退到 prompt-only 路径,Run 继续执行;如果模型返回的是合法 JSON object 文本,运行时会继续 best-effort 解析并映射到
structured_json输出槽 - 如果 fallback 文本不是合法 JSON object,运行时会保留 warning,并在校验失败时把
validation_error_detail与normalized_outputs一起暴露给 Run API 和治理快照 - 观测字段:Run API 与治理快照会暴露请求、是否真正应用、fallback reason、实际
provider/model_name、发送给模型的prompt_messages、model_raw_response、normalized_outputs和可选的validation_error_detail,便于确认 output contract 是否真的进入 prompt,以及具体是哪个字段校验失败
Structured JSON Schema Resolution
Fusion 没有新增独立 output kind。所有 richer schema 能力都收敛在现有 structured_json 槽上,并由以下 contract 字段驱动:
structured_output_schema: authoritative nested schemaoutput_instruction_fragment: slot 级显式输出提示片段structured_output_profile: 可选附加语义 profile;当前第一版支持document_field_set
运行时的解析顺序:
- 优先使用显式
structured_output_schema - 对 legacy persisted payload,在后端单点把
schema_fields归一化为structured_output_schema - 对 legacy
document_field_setpersisted payload,后端也会补齐对应的 preset schema 与 instruction fragment,再进入 prompt / model binding / validator 链路
这意味着 prompt builder、model binding、validator 消费的是同一份解析后的显式 contract,而不是各自再做 profile-specific 隐式补丁。
Document-Style Structured Output
document_field_set 现在的定位是 profile / preset / 附加 validator,而不是 nested schema 的唯一入口。
这条路径的运行时行为:
- Studio 或后端兼容层会把 document preset 实体化到
structured_output_schema - prompt builder 只拼接持久化后的
output_instruction_fragment - validator 先执行 generic nested-schema 校验,再追加 document-style 基础结构检查
- Run API 不新增字段,仍通过
output_item_list[].json_value返回结果
当前默认 preset 来自 ai_service/fusion/domain/output_profile_schemas/booking_confirmation_schema.json,基础规则改为:
- 顶层值必须是 object,字段集合与 required 列表由 schema 文件决定
- 默认叶子节点统一使用
{ value, page_number, bbox } bbox约定为归一化相对页坐标[x, y, width, height]- 数组与嵌套 object 必须保持 schema 中声明的结构
- profile-aware validator 仍会在 payload 选择
fields/tablescanonical 形状时做附加结构检查,但不再把该形状作为默认 preset
Document-Style Structured Output
Fusion 现在允许某个 structured_json 输出槽声明:
{
"structured_output_schema": {
"type": "object",
"properties": {
"booking_number": { "type": "object" },
"routing": { "type": "array" }
},
"additional_properties": false
},
"structured_output_profile": "document_field_set",
"output_instruction_fragment": "Document-style output profile requirements: ..."
}
该 profile 的用途是让一个普通 structured_json 槽表达单证识别风格的 canonical JSON,而不引入新的 output kind。当前实现主要覆盖三件事:
- authoring 阶段把 preset schema 与 visible instruction fragment 实体化到 slot contract
- model binding 在可用时直接读取这份显式 nested schema
- runtime 依据这份显式 contract 生成输出约束
推荐 canonical 形状:
{
"fields": [
{
"field_name": "invoice_code",
"field_type": "string",
"value": "123456789012",
"confidence": 0.98,
"page_number": 1,
"geometry": {
"type": "bbox",
"bbox": [0.12, 0.08, 0.28, 0.03]
}
}
],
"tables": [
{
"table_name": "line_items",
"page_number": 1,
"rows": [
{
"row_index": 0,
"cells": [
{
"field_name": "amount",
"field_type": "number",
"value": "10000.00"
}
]
}
]
}
]
}
第一版校验规则:
- slot 值必须是 object
fields、tables如果存在,必须是数组fields[]和cells[]的 canonical 输出需要包含field_name、field_type、value、page_number、geometrytables[]必须包含table_name、rowsrows[]必须包含row_index、cellsconfidence必须在0..1page_number必须为正整数geometry.type允许bbox或polygon- 当
geometry.type == "bbox"时,bbox必须是 4 个数字
当前边界也需要明确:
- 这是 Fusion
structured_json的 profile 扩展,不是新的运行时 - 这不等于现有
document_extractionAgent 的完整审核产物 - Run API 仍然通过原有
output_item_list[].json_value返回结果,不新增专用响应模型
当前 Studio 能力
Studio 现在以 Agent Detail Fusion workspace 作为唯一正式控制面入口,当前提供:
- live Agent draft 的输入/输出 contract 编辑
structured_json输出槽上的structured_output_profile选择器document_field_set的一等 authoring 与 JSON round-trip- Draft / published snapshot JSON 导入导出
- published snapshot 列表
- Recent runs 与 run detail 查看
补充说明:
document_field_setprofile 已经在后端 schema / runtime 中生效,也已经在 Studio 表单中暴露- Run API 继续以
output_item_list[].json_value作为 canonical output 真相源 - 内部 hidden definition 兼容层仍可存在,但它属于 Fusion domain 内部状态,不是 application / Studio 需要理解的产品实体