跳转至

编排器

ChameleonOrchestrator 是当前默认聊天运行时的顶层 LangGraph 编排器。它根据 SessionStatusai_nodehuman_node 间切换,并通过共享运行时基础设施串联 RAG 检索、长期记忆读取、Skill 执行、MCP 调用、LLM 生成、长期记忆写入与 Langfuse 观测。

当前控制面采用三层选择模型:

  • agent_type 负责粗粒度能力边界,例如 chatetldocument_extraction
  • orchestrator_key 仅在 chat 下选择具体聊天运行时;当前默认键是 chameleon_chat_v1
  • model_routing_config 仅在 chat 下可选启用,用于为工具阶段与最终生成阶段选择不同模型角色
  • mcp_runtime_config 仅在 chat 下可选启用,用于覆盖 MCP 最近用户历史窗口与 Chameleon MCP helper prompt guidance
  • response_grounding_config 仅在 chat 下可选启用,用于约束最终回复阶段的 grounded-answer 策略

当前已实现两个聊天运行时:

  • chameleon_chat_v1
  • 默认运行时
  • 顶层 LangGraph 仍然负责会话状态路由
  • 具体能力阶段通过共享 RuntimeKernel + CapabilityPipeline 组织
  • langgraph_react_agent_v1
  • 非默认实验运行时
  • 同样复用共享 RuntimeKernel + CapabilityPipeline
  • 使用显式 react_tools.py 工具桥接暴露已挂载的 Skill / MCP 能力

两者都保留同一个 OrchestratorInput / OrchestratorResult 契约,并输出统一的观测负载版本 observability_schema_version = "v2"

当前角色化模型路由约定如下:

  • tool_call_model
  • 用于 MCP 选择、参数生成,以及 ReAct 工具循环
  • general_model
  • 默认最终回复模型
  • complex_task_model
  • 在复杂度门控命中时用于最终回复
  • reasoning_model
  • 在推理门控命中时用于最终回复
  • 若请求级或评测级显式传入 model_*,本次执行会折叠成单模型路径,不再按角色分流

ChameleonOrchestrator 当前默认支持 Agent 级 response_grounding_config。当该配置启用时,最终回复阶段会优先尝试结构化输出,把结果分类为:

  • answer
  • ask_for_clarification
  • decline

然后由服务端根据 modeallow_general_knowledgelow_confidence_behaviorstructured_output_failure_behavior 做一次保守后处理,降低“看起来很流畅但没有可靠依据”的最终回答概率。

/stream 与 evaluation runner 都通过同一个聊天编排器注册表构造运行时,因此控制面中的 orchestrator_key 会同时影响在线对话与离线测评。model_routing_configmcp_runtime_configresponse_grounding_config 也会沿同一路径进入聊天运行时。

LangGraph 编译图

当前项目可以直接从已编译的 LangGraph 导出 Mermaid 图。刷新本页中的图,请运行:

UV_CACHE_DIR=/tmp/uv-cache uv run python scripts/export_orchestrator_graph.py

图的来源是 ChameleonOrchestrator.graph.get_graph().draw_mermaid(),因此它反映的是当前代码中的真实顶层节点,而不是手工维护的概念图。

---
config:
  flowchart:
    curve: linear
---
graph TD;
    __start__[start]:::first
    router(router)
    ai_node(ai_node)
    human_node(human_node)
    __end__[end]:::last
    __start__ --> router;
    router -.-> ai_node;
    router -.-> human_node;
    ai_node --> __end__;
    human_node --> __end__;
    classDef default fill:#f2f0ff,line-height:1.2
    classDef first fill-opacity:0
    classDef last fill:#bfb6fc

上图回答的是“LangGraph 实际编译出来的顶层节点是什么”。如果要理解业务运行过程,还需要看下面的展开图,因为 RAG、Skill、MCP、LLM 生成都发生在 ai_node 内部,而不是顶层 LangGraph 节点上。

另一个与编排器并列的确定性快路径发生在 POST /stream API 层:

  • message_type_response_config 固定响应短路
  • mcp_response_config.quick_match_rules[] 前缀短路

相对地,response_grounding_config 不会在 API 层短路;它发生在编排器内部的最终生成阶段。

这两条路径都会在进入聊天编排器前直接返回 SSE token / done,因此不属于顶层 LangGraph 节点的一部分。

运行阶段展开图

下图是文档层面的运行阶段展开图,用来解释 run() 调用后在 ai_node 内部发生了什么。它不是第二份编译图,而是对真实运行阶段的细化说明。

flowchart TD
    RunInput[run 输入]
    ApplyEvent[应用事件并解析 SessionStatus]
    BuildState[构造 OrchestratorState]
    RootTrace[开启 chat-turn 根追踪]
    InvokeGraph[调用编译后的 LangGraph]

    RunInput --> ApplyEvent --> BuildState --> RootTrace --> InvokeGraph

    subgraph TopLevelGraph[顶层 LangGraph]
        Start[start]
        Router[router]
        AINode[ai_node]
        HumanNode[human_node]
        EndNode[end]

        Start --> Router
        Router -->|AI_ACTIVE| AINode
        Router -->|HUMAN_ACTIVE| HumanNode
        HumanNode --> HumanReturn[直接回传 agent 消息]
        HumanReturn --> EndNode

        AINode --> RoleGuard{incoming_role 是 user}
        RoleGuard -->|否| EmptyResponse[返回空响应]
        EmptyResponse --> EndNode
        RoleGuard -->|是| TraceMeta[初始化 trace 元数据]
        TraceMeta --> HasAgent{是否存在 agent_id}
        HasAgent -->|否| GenerateReply[生成最终回复或 fallback]
        HasAgent -->|是| RAGPhase[RAG 检索与上下文拼装]
        RAGPhase --> MemoryRead[长期记忆读取]
        MemoryRead --> SkillGate{skill.enabled}
        SkillGate -->|是| SkillLoop[Skill loop 与 skill-call]
        SkillGate -->|否| MCPGate
        SkillLoop --> MCPGate{mcp.enabled}
        MCPGate -->|是| MCPLoop[MCP loop 预门控 产参 调用 校验]
        MCPGate -->|否| GenerateReply
        MCPLoop -->|单次真实调用且命中 Agent direct-response rule| DirectReturn[按 Agent 规则直接返回 MCP 输出]
        MCPLoop -->|单次真实调用且仅命中 legacy raw_passthrough_tool_keys| RawReturn[兼容返回 MCP 原始 JSON]
        MCPLoop -->|其余情况| GenerateReply
        DirectReturn --> Observability
        RawReturn --> Observability
        GenerateReply --> MemoryWrite[长期记忆写入]
        MemoryWrite --> Observability[组装 observability payload]
        Observability --> AIResponse[返回 ai 响应]
        AIResponse --> EndNode
    end

    InvokeGraph --> Start

顶层节点职责

router

  • 读取当前 OrchestratorState,但不直接修改状态。
  • 根据 active_status 决定下一跳:
  • SessionStatus.HUMAN_ACTIVE -> human_node
  • 其他状态 -> ai_node

ai_node

  • 仅处理 incoming_role="user" 的请求。
  • 初始化当前轮次的 Langfuse 追踪元数据。
  • 在有 agent_id 时按顺序执行:
  • RAG 检索
  • Skill 调用回路
  • MCP 调用回路
  • 按角色路由选择最终 LLM 回复模型并生成答案
  • MCP 阶段支持一条受控旁路:
  • 若当前轮次真实进入 invoke_tool(...) 的次数恰好为 1
  • 优先匹配当前 Agent 的 enabled direct_response_rules[]
  • 若未命中 Agent 规则,再兼容检查全局 mcp.raw_passthrough_tool_keys
  • 命中后直接返回 MCP 输出,不再进入最终 LLM 总结
  • 汇总 rag_contextskill_contextmcp_context 等观测数据并返回响应。
  • 汇总 model_routing.stage_decisions[]、最终回复模型角色与最终模型配置,并写入 turn 观测负载。

human_node

  • 仅处理 incoming_role="agent" 的请求。
  • 将人工消息原样回传为最终响应,不触发 RAG、Skill、MCP 或 LLM 生成。

ai_node 内部阶段

需要注意,下面这些是 ai_node 内部串联的运行阶段,不是顶层 LangGraph 节点:

  1. rag-retrieval
  2. memory-read
  3. skill-loop
  4. skill-call
  5. mcp-loop
  6. mcp-tool-selection-decision
  7. mcp-pre-generation-gate
  8. mcp-argument-generation
  9. mcp-argument-verification
  10. mcp-call
  11. llm-generation
  12. memory-write

这也是为什么编译图本身只有 router / ai_node / human_node 三个业务节点,而不是将每个内部阶段都展开成单独节点。

补充说明:

  • 第 6 到 10 阶段的模型选择会优先尝试 tool_call_model
  • 第 11 阶段会在 general_modelcomplex_task_modelreasoning_model 与主模型回退之间做确定性选择

MCP 内部阶段详解(第 6–10 阶段)

第 6 到 10 阶段在 mcp-loop 内部依次执行,任意一步返回阻断信号(should_attempt=false 或必填字段缺失)都会 break 本轮循环,不再发起后续调用。

阶段 6:mcp-tool-selection-decision

职责:决定本轮选哪个工具(或不选)。

  • 先按 eligible_tool_definitions 过滤当前挂载中的可用工具(空名称工具和不在 allowlist 内的工具会被排除)。
  • 对具备 runtime strategy 的工具(如 tracking),先走确定性选择:从当前消息与最近 user 历史中提取追踪标识,有标识则直接选;没有标识但有追踪意图,也选但继续走后续门控。
  • 无确定性工具时,调用 tool_call_model 的 AI 选择器,返回 selected_tool_name + should_call_now + missing_required_arguments
  • 若 AI 选择器返回 no_tool,或工具名为空,或无 eligible 工具,本轮 break(记录 skipped)。
  • AI 选择器的执行决策结果会直接传递给下一阶段,避免重复判断。

阻断条件:无 eligible 工具 / 工具名空 / AI 返回 no_tool

阶段 7:mcp-pre-generation-gate

职责:在进入 AI 参数生成之前,先做确定性判断,避免无谓的 LLM 调用。

对 tracking tool,判断优先级如下:

  1. 当前消息含唯一可识别的追踪标识 → 放行
  2. 当前消息含追踪标识但有歧义(多个候选值)→ 阻断,返回歧义澄清提示
  3. 历史中含唯一追踪标识,且当前消息是省略式续问(如"查一下"、"继续"、"那个呢")→ 放行
  4. 历史中含追踪标识但有歧义 → 阻断,返回歧义澄清提示
  5. 追踪意图但当前消息与历史均无标识 → 阻断,返回结构化补参提示
  6. 非追踪内容 → 阻断,静默跳过(不返回补参提示)
  7. message_type != user_chat 且无显式标识 → 阻断

此阶段"历史标识"仅用于判断是否值得触发参数生成,不会直接注入工具参数。

阻断条件should_attempt=false

阶段 8:mcp-argument-generation

职责:调用 tool_call_model 为选定工具生成参数。

  • 输入:当前用户消息、工具 Schema(含 input_schema)、最近 N 条 user 历史消息(N 由 history_user_message_window 控制,默认 3)。
  • 优先使用 structured output(MCPToolArgumentsStructuredOutput),不支持时回退到 JSON 文本解析。
  • AI 的输出是权威信号:AI 输出了哪些字段,就代表它在当前上下文中识别到了哪些信息。若 AI 未输出某个 required 字段,说明当前上下文不足以提供该参数。
  • 解析失败时,返回 None,后续阶段按空参数处理,通常会在 required-argument-check 被拦截。

阻断条件:此阶段本身不阻断,但解析失败会导致参数为空,在后续阶段阻断。

build_tool_arguments(阶段 8 与 9 之间,非独立 span)

职责:将 AI 生成的原始参数与当前消息的确定性提取结果合并,得到最终 payload。

两个来源,优先级明确:

来源 A — AI 生成参数(主要来源)

  • AI 输出先经过别名归一化(canonicalize)。
  • 对追踪标识字段做可追溯性校验:能从当前消息(或允许历史复用时从最近 user 历史)确定性回溯到的值保留,无法追溯的视为幻觉丢弃。
  • 通过校验的字段写入 payload。

来源 B — 当前消息确定性提取(兜底来源)

  • 仅对当前消息resolution_source=current_user_message)做规则提取。
  • 典型场景:用户在上一轮被询问后,当前轮直接回复了单号(如 S55ES0000134),当前消息本身就是单号,规则直接提取补入。
  • 不从历史消息自动填充:历史中的旧单号不会在此阶段注入 payload。这是故意的设计——若 AI 已经看到历史却没有生成该字段,说明它判断当前上下文不足以支持调用,规则层不应覆盖这一判断。

固定字段:query(原始用户消息)、round(当前执行轮次)始终写入。

阶段 9:mcp-argument-verification

职责:对已组装的 payload 做统一后置验证。

  • 若 payload 中的追踪标识字段可从用户消息确定性回溯 → 放行
  • 若 AI 产参包含不可追溯的标识字段 → 阻断,返回补参提示
  • 若工具 Schema 的 required 字段不完整 → 阻断,返回结构化缺参提示

此阶段把原先分散的“调用前门控 + required 字段校验”收敛成一处,专门处理参数完整性与参数来源可信度,不再重复做 readiness 阶段已经完成的上下文判断。

阻断条件should_attempt=false 或 required 字段缺失。

阶段 11:mcp-call

职责:发起真实工具调用,解析响应语义。

  • 调用 invoke_tool(transport_type, connection_config, tool_name, tool_arguments)
  • 响应经 resolve_response_semantic() 解析,映射为四种语义状态:
  • success:传输成功且无业务错误
  • timeout:调用超时
  • blocked:响应体中明确指出缺少必填参数(如外部服务的参数校验错误)
  • error:其他业务错误或传输错误
  • blocked 时记录审计并 break;error / timeout 按重试策略决定是否继续循环。

Agent 级 MCP 直接返回

当前 MCP 阶段保留“默认总结、Agent 显式旁路”的策略,但当前产品主控制面已经切到 Agent 级结构化配置。

  • 默认路径:
  • 成功的 MCP 工具结果会先进入 effective_user_message
  • 若本轮 MCP 被跳过、阻塞、超时或报错,编排器会追加 MCP Tool Outcomes 上下文,明确说明没有可靠的外部工具结果,避免最终回复把“没查到 / 没执行”误判成“已经查询成功”
  • 缺少标识符或标识符歧义时,会优先追加 MCP Argument Issues 或 capability guidance,驱动最终回复要求补充信息而不是继续猜
  • 最终由 LLM 组织成用户可见回复
  • Agent 直返路径:
  • 仅当本轮真实 MCP 调用次数为 1
  • 且命中当前 Agent 的 enabled direct_response_rules[]
  • raw_json:优先返回 response_payload.response 内的业务 JSON;若无 response 字段,则回退为序列化整个 response_payload
  • json_subset:只保留 selected_fields[] 命中的字段
  • text:按 prefix_text + selected_fields + suffix_text 渲染文本
  • wrap_json_code_block=true 时,raw_jsonjson_subset,以及格式化失败后的 raw_json fallback 都会包成 Markdown ```json fenced block
  • 兼容兜底路径:
  • 仅当未命中 Agent direct_response_rules[]
  • <server_name>/<tool_name> 仍命中全局 mcp.raw_passthrough_tool_keys
  • 该路径只保留为兼容旧配置,不再是推荐的控制方式
  • 若同时开启 mcp.raw_passthrough_wrap_json_code_block=true,则这条 legacy raw JSON 直返会额外包成 ```json fenced block
  • 多调用路径:
  • 只要本轮真实 MCP 调用次数大于 1
  • 即使某个工具配置了 direct-response rule 或 legacy raw allowlist,也会退回默认“聚合后总结”路径

字段格式化失败时会自动回退到 raw_json,并把 mcp_format_fallback_used=true 写入观测负载。

另外,POST /stream 在进入编排器前还支持 mcp_response_config.quick_match_rules[]

  • 仅对 message_type=user_chat 生效
  • 这是 API 层快路径:命中后直接返回 SSE,不进入 orchestrator / 最终 LLM 总结
  • 在 API 层按前缀直接解析参数,并在真正调用前继续执行 MCP 挂载/allowlist 校验、预门控、argument verification 与审批 checkpoint;任一步阻断都不会发起 invoke_tool(...)
  • 若命中 quick-match 但 suffix_parameter_name 后缀为空,或工具 schema 仍缺少 required 字段,则直接返回确定性的 usage guidance,而不是回退到普通聊天;例如:Quick-match '#get_tracking' requires one cargo number after the prefix. Use HBL No., FBA No., CTN No., or PO No.
  • 若配置了 response_rule_key,则复用同一个 direct-response formatter
  • response_rule_key 未配置、留空或为空字符串,则 quick-match 不会自动套用同工具的 direct-response rule,而是直接返回 raw_json
  • 若复用到开启了 wrap_json_code_block 的 direct-response rule,则 quick-match 返回的 JSON 也会带同样的 fenced block

与此同时,tracking/query 的查询前门禁也走 Agent 级 mcp_response_config.intent_gate_rules[]

  • 关键词匹配主入口是 Agent settings,而不是全局 ai_service/utils/settings.py
  • tool_capability 允许管理员填写任意 capability 标签
  • 当前只有 tracking 具备内建 runtime strategy;其它 capability 仅参与挂载级门禁过滤
  • regex 使用 Python 语法,并在保存阶段由后端校验
  • match_source_mode 支持 default/append/replace
  • 对自定义 capability,运行时只使用该 rule 自身的 keywords[] / regex_patterns[] 匹配当前用户消息
  • 某个挂载声明了自定义 capability 但未配置 enabled rule 时,运行时不会额外拦截该挂载,保持旧行为
  • allow_contextual_follow_up 与内置默认 matcher 目前仍主要服务 tracking

与门禁规则并列的 Agent 级运行时覆盖则走 mcp_runtime_config

  • history_user_message_window
  • 覆盖全局 [mcp].history_user_message_window
  • 同时影响 Chameleon 与 ReAct runtime 的最近用户消息窗口
  • tool_selection_prompt_guidance
  • 仅追加到 Chameleon runtime 的 MCP 工具选择提示词
  • tool_argument_prompt_guidance
  • 仅追加到 Chameleon runtime 的 MCP 参数生成提示词

“真实 MCP 调用次数”只统计真正进入 invoke_tool(...) 的次数,不统计以下分支:

  • no_tool
  • 工具选择跳过
  • 预门控/后门控跳过
  • 缺少必填参数导致未发起调用
  • 审批前暂停导致未发起调用

若单次直返工具调用失败但存在 response_payload,仍按相同规则优先返回 response 内业务 JSON,否则返回整个 payload;若 payload 缺失,则返回最小错误 JSON:

{
  "server_name": "tracking-server",
  "tool_name": "query_tracking9",
  "status": "error",
  "error_message": "upstream failed"
}

运行入口

run() 会先根据传入事件计算新的 SessionStatus,然后构造 OrchestratorState 并调用编译后的 LangGraph:

updated_state = self.graph.invoke(orchestrator_state.model_dump())

执行完成后,编排器会将 response_roleresponse_contentobservability_payload 封装为 OrchestratorResult 返回。

共享运行时基础设施

当前聊天运行时已经提炼出以下共享组件:

  • ai_service/orchestrator/runtime_kernel.py
  • 统一处理事件应用、根追踪、运行时状态收口与 OrchestratorResult 封装
  • ai_service/orchestrator/capability_pipeline.py
  • 统一串联检索、记忆、工具、生成与观测装配
  • ai_service/orchestrator/model_routing.py
  • 统一定义角色化模型配置、解析/序列化与阶段路由决策
  • ai_service/orchestrator/runtime_types.py
  • 定义共享阶段输入/输出类型
  • ai_service/orchestrator/checkpoint_state.py
  • 定义审批型 checkpoint 负载
  • ai_service/orchestrator/react_tools.py
  • 为实验运行时暴露显式 Skill / MCP 工具桥接

这意味着:

  • chameleon_chat_v1 仍然保留最小顶层 LangGraph
  • langgraph_react_agent_v1 不再是空壳,而是复用同样的检索、记忆、观测和 checkpoint 契约
  • 运行时升级可以在不改变控制面契约的情况下推进

Checkpoint 与长期记忆

Runtime Checkpoint

  • 新增持久化表:runtime_checkpoints
  • 当前主要用于 MCP 审批边界
  • 仅当 runtime_checkpoint.approval_required_tool_names 显式命中某个工具时,运行时才会:
  • 持久化 awaiting_approval checkpoint
  • 返回 next_status_override = HUMAN_ACTIVE
  • 在收到 agent_release 后从 checkpoint 恢复并继续执行

Agent Memory

  • 新增持久化表:agent_memory_records
  • 能力上支持长期记忆读取与写入,但默认是配置关闭的加法能力
  • 开启后会:
  • 在推理前读取有界记忆摘要并注入提示
  • 在成功对话后写入 turn 摘要与有限数量的工具结果记忆
  • 若存储层不可用,记忆层会 fail-open,不影响主对话运行

运行时发布策略

  • chameleon_chat_v1 继续作为默认运行时
  • langgraph_react_agent_v1 继续保持非默认实验状态
  • 运行时切换仍通过 orchestrator_key 完成,不新增新的产品层类型字段
  • 推荐将运行时晋升门禁建立在评测运行的 runtime slice 汇总之上,而不是直接通过主观观察切换默认值

可观测性

编排器当前的链路观测主要通过 Langfuse Span 完成:

Span 名称 位置 说明
chat-turn run() 根 Span 覆盖整轮对话
rag-retrieval ai_node 检索与上下文拼装
skill-loop ai_node Skill 总回路
skill-call _run_skill_tool_loop() 单次 Skill 调用
mcp-loop ai_node MCP 总回路
mcp-tool-selection-decision _run_mcp_tool_loop() MCP 工具选择总决策(覆盖确定性/AI 两条路径)
mcp-tool-selection _select_mcp_tool_definition_with_ai() MCP 工具选择
mcp-pre-generation-gate _run_mcp_tool_loop() MCP 参数生成前门控
mcp-argument-generation _generate_mcp_tool_arguments_with_ai() MCP 参数生成
mcp-argument-verification _run_mcp_tool_loop() MCP 参数后置验证(完整性 + 可追溯性)
mcp-call _run_mcp_tool_loop() 单次 MCP 调用
llm-generation _generate_ai_reply() 最终模型生成

共享 observability_payload 还会额外记录 MCP 直返判定字段:

  • response_source
  • llm_generated:默认总结路径
  • mcp_raw:命中 MCP 原始 JSON 直返
  • mcp_direct_response:命中 Agent direct-response formatter
  • mcp_quick_match:命中 API 层 quick-match 快路径
  • mcp_raw_passthrough
  • 布尔值,标记当前响应是否来自 legacy raw_passthrough_tool_keys 原始 JSON 直返
  • mcp_direct_response
  • 布尔值,标记当前响应是否命中 Agent direct-response 或 quick-match 直返
  • mcp_invocation_count
  • 当前轮次真实进入 invoke_tool(...) 的次数
  • mcp_raw_tool_key
  • 命中 legacy 原始直返时记录 <server_name>/<tool_name>,否则为 null
  • mcp_output_mode
  • raw_jsonjson_subsettext
  • mcp_response_rule_key
  • 命中的 direct-response rule key;若 quick-match 未绑定 formatter,则为 null
  • mcp_quick_match_prefix
  • 命中的 quick-match 前缀;普通 MCP 调用为 null
  • mcp_format_fallback_used
  • 字段格式化失败后是否回退到 raw_json

错误处理与降级

场景 当前行为
模型不可用 返回 fallback 文案
RAG 检索失败 记录告警,继续后续阶段
Skill 回路失败 记录告警,回退到下一阶段
MCP 回路失败 记录告警,回退到最终生成
LangGraph 运行异常 记录根 Span 错误并向上抛出

MCP 参数生成

在 MCP 调用回路中,编排器采用“readiness + AI 产参 + argument verification”策略:

  1. tools/list 读取工具定义,优先使用 input_schema
  2. 若某个挂载声明了自定义 tool_capability,且 Agent 为该 capability 启用了 intent_gate_rules[],编排器会先用当前用户消息做一次挂载级门禁;未命中时直接跳过该挂载,不进入 discover_tools()
  3. 如果一个 MCP Server 暴露多个工具,编排器不会盲选返回列表中的第一个工具。
  4. 运行时会先过滤空名称工具,再应用 Agent 挂载 allowlist。
  5. 运行时将 query_trackingquery_tracking9 视为同一个 tracking capability;能力级元数据由 capability registry 持有,capability 到 runtime 的映射由 runtime strategy registry 持有,tracking 运行时解析/门控逻辑由 dedicated runtime strategy 持有,并统一由 MCPToolAdapterService 消费。
  6. 对自定义 capability 挂载,运行时不会套用 tracking 的确定性选工具、缺参澄清或历史续问策略,而是直接进入常规 AI tool selection 路径。
  7. 若消息表现为追踪意图、已含追踪标识,或属于可复用历史的省略式续问,则优先选择 tracking tool。
  8. 若当前轮本身只是纯标识回复,但最近可信 user 历史已建立 tracking 上下文(例如上一轮是 Track Shipment),运行时也会把该回复视为安全补参并优先选择 tracking tool。
  9. 若只有一个 eligible tracking tool 且当前消息没有任何追踪信号,则会确定性静默跳过,不再为“是否调用唯一 tracking 工具”额外跑一次 LLM 选择。
  10. 若确定性规则不足以选中工具,才运行一次 bounded mcp-tool-selection;该阶段允许返回 no_tool,而不是因为“只剩一个工具”就强行进入工具路径。
  11. mcp-tool-selection 现在优先走 structured output,并一次返回 selected_tool_name + should_call_now + missing_required_arguments + reason;仅在模型/网关不支持时回退到旧的 JSON 提取路径。
  12. mcp-argument-generation 之前先执行预门控:
  13. 若工具来自 AI selector,运行时会直接复用该结构化执行决策;mcp-pre-generation-gate 主要负责审计、trace 和用户引导,不再重新猜一次“现在能不能调”。
  14. 对 tracking tool(query_tracking / query_tracking9),若“当前消息 + 最近 3 条可信 user 历史”可解析到 HBL No. / FBA No. / CTN No. / PO No. 之一,则允许继续;运行时会把这些业务标识统一映射到底层 transport 字段 selectNo。其中纯 selectNo 回复也可以在最近历史已明确 tracking 上下文时被接受。
  15. 若需要补参或澄清,编排器会调用 adapter 的 registry/strategy-backed capability helper 生成结构化 guidance payload,而不是自己硬编码 tracking 分支;这些 payload 统一使用 missing_identifierscandidate_identifier_arguments 这类 capability-generic key。
  16. user_chat 命中追踪意图但缺少标识,则直接返回结构化补参提示,不生成 MCP 参数。常见追踪意图表达包括 Track Shipmentwhere is my package请帮我查一下进度查询包裹到哪里了我想查询货物eta for my cargo
  17. 若是 你好、闲聊、普通问答等非追踪聊天,则静默跳过 MCP,不生成 MCP 参数。
  18. message_type=rule/form/other,无显式标识时默认静默跳过工具。
  19. 若当前消息是省略式续问,且最近可信 user 历史中只有一个可复用标识,则允许继续;若存在多个竞争标识,则阻断并要求用户澄清。
  20. 最近历史里的旧单号不会被用于普通闲聊或无关问答;只有当前轮仍表现为追踪意图或省略式续问时,才会复用历史标识。
  21. 混合字母数字单号(例如 555E898665 帮查一下)现在会在本地规则层优先解析,而不是退回 LLM 选工具。
  22. 仅在预门控放行后,使用模型根据 current user message + recent trusted user history + tool schema 生成 tool_arguments JSON。
  23. mcp-argument-generation 与工具选择一样优先走 structured output;若上游模型不支持,再回退到 JSON 文本解析。
  24. build_tool_arguments(...) 会优先保留可从“当前消息 + 最近可信 user 历史”回溯命中的追踪字段,不可追溯字段会先被剔除。
  25. mcp-argument-verification 统一负责:
  26. 校验剩余参数是否仍满足 input_schema.required
  27. 校验关键标识字段是否仍可追溯到 trusted user text
  28. 若失败则直接阻断调用,并返回结构化补参提示与 blocked 审计原因
  29. 审计层会区分:
  30. blocked:准备进入工具路径,但被阻断
  31. skipped:当前上下文下不应进入工具路径

API 参考

详细字段与方法说明请查看「API 参考 -> 编排器」。

相关文档