跳转至

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_runs
  • fusion_run_inputs
  • fusion_run_outputs
  • 当前主控制面 API:
  • PATCH /agents/{agent_id} 保存 live Fusion draft
  • GET /agents/{agent_id}/versions
  • POST /agents/{agent_id}/publish
  • 当前运行时 API:
  • POST /agents/{agent_id}/fusion-runs
  • GET /agents/{agent_id}/fusion-runs
  • GET /agents/{agent_id}/fusion-runs/{run_id}
  • POST /agents/{agent_id}/fusion-runs 同时接受 JSON input_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_node
  • validate_definition_contract_node
  • validate_run_inputs_node
  • persist_validated_inputs_node
  • resolve_capability_bindings_node
  • prepare_file_artifacts_node
  • retrieve_context_node
  • build_prompt_node
  • plan_tool_usage_node
  • invoke_tools_node
  • invoke_model_node
  • normalize_outputs_node
  • validate_outputs_node
  • persist_outputs_node
  • finalize_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_countlease_tokenlast_attempt_started_atworker_heartbeat_at,用于表达 claim / lease / heartbeat 真相。
  • 执行中的 run 会周期性刷新 worker_heartbeat_at;如果服务中断导致心跳停止,超出 [fusion].worker_stale_seconds 后,stale queued / pending / running run 会被 supervisor 收敛为 failed
  • 输入合约会在模型调用前做严格校验。
  • 输出合约会在持久化前做严格校验。
  • Phase 1 里 MCP、RAG、存储、图像能力都通过 adapter 接入。
  • 现有老 Agent API 与运行时保持不变。
  • 当版本的 prompting_config.enable_json_object_response_format=true 且存在 structured_json 输出槽时,运行时会优先尝试 provider-native response_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_idcapability_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_countlease_tokenlast_attempt_started_atworker_heartbeat_at
  • 新创建的 Fusion Run 会持久化一份 run 级别的 governance_context 快照,避免后续 Agent mounts 变化污染历史审计结果。
  • 对缺少快照的 legacy run,API 只返回基于 definition version 的保守治理视图,不会在读取时按当前 Agent mounts 反推或补写历史快照。
  • governance_context 现在还会记录:
  • response_format_requested
  • response_format_applied
  • response_format_fallback_reason
  • resolved_model_provider
  • resolved_model_name
  • prompt_messages
  • model_raw_response
  • normalized_outputs
  • validation_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_detailnormalized_outputs 一起暴露给 Run API 和治理快照
  • 观测字段:Run API 与治理快照会暴露请求、是否真正应用、fallback reason、实际 provider/model_name、发送给模型的 prompt_messagesmodel_raw_responsenormalized_outputs 和可选的 validation_error_detail,便于确认 output contract 是否真的进入 prompt,以及具体是哪个字段校验失败

Structured JSON Schema Resolution

Fusion 没有新增独立 output kind。所有 richer schema 能力都收敛在现有 structured_json 槽上,并由以下 contract 字段驱动:

  • structured_output_schema: authoritative nested schema
  • output_instruction_fragment: slot 级显式输出提示片段
  • structured_output_profile: 可选附加语义 profile;当前第一版支持 document_field_set

运行时的解析顺序:

  1. 优先使用显式 structured_output_schema
  2. 对 legacy persisted payload,在后端单点把 schema_fields 归一化为 structured_output_schema
  3. 对 legacy document_field_set persisted 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 / tables canonical 形状时做附加结构检查,但不再把该形状作为默认 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。当前实现主要覆盖三件事:

  1. authoring 阶段把 preset schema 与 visible instruction fragment 实体化到 slot contract
  2. model binding 在可用时直接读取这份显式 nested schema
  3. 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
  • fieldstables 如果存在,必须是数组
  • fields[]cells[] 的 canonical 输出需要包含 field_namefield_typevaluepage_numbergeometry
  • tables[] 必须包含 table_namerows
  • rows[] 必须包含 row_indexcells
  • confidence 必须在 0..1
  • page_number 必须为正整数
  • geometry.type 允许 bboxpolygon
  • geometry.type == "bbox" 时,bbox 必须是 4 个数字

当前边界也需要明确:

  • 这是 Fusion structured_json 的 profile 扩展,不是新的运行时
  • 这不等于现有 document_extraction Agent 的完整审核产物
  • 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_set profile 已经在后端 schema / runtime 中生效,也已经在 Studio 表单中暴露
  • Run API 继续以 output_item_list[].json_value 作为 canonical output 真相源
  • 内部 hidden definition 兼容层仍可存在,但它属于 Fusion domain 内部状态,不是 application / Studio 需要理解的产品实体