编排器
ChameleonOrchestrator 是当前默认聊天运行时的顶层 LangGraph 编排器。它根据 SessionStatus 在 ai_node 与 human_node 间切换,并通过共享运行时基础设施串联 RAG 检索、长期记忆读取、Skill 执行、MCP 调用、LLM 生成、长期记忆写入与 Langfuse 观测。
当前控制面采用三层选择模型:
agent_type负责粗粒度能力边界,例如chat、etl、document_extractionorchestrator_key仅在chat下选择具体聊天运行时;当前默认键是chameleon_chat_v1model_routing_config仅在chat下可选启用,用于为工具阶段与最终生成阶段选择不同模型角色mcp_runtime_config仅在chat下可选启用,用于覆盖 MCP 最近用户历史窗口与 Chameleon MCP helper prompt guidanceresponse_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。当该配置启用时,最终回复阶段会优先尝试结构化输出,把结果分类为:
answerask_for_clarificationdecline
然后由服务端根据 mode、allow_general_knowledge、low_confidence_behavior 与 structured_output_failure_behavior 做一次保守后处理,降低“看起来很流畅但没有可靠依据”的最终回答概率。
/stream 与 evaluation runner 都通过同一个聊天编排器注册表构造运行时,因此控制面中的 orchestrator_key 会同时影响在线对话与离线测评。model_routing_config、mcp_runtime_config 与 response_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_context、skill_context、mcp_context等观测数据并返回响应。 - 汇总
model_routing.stage_decisions[]、最终回复模型角色与最终模型配置,并写入 turn 观测负载。
human_node
- 仅处理
incoming_role="agent"的请求。 - 将人工消息原样回传为最终响应,不触发 RAG、Skill、MCP 或 LLM 生成。
ai_node 内部阶段
需要注意,下面这些是 ai_node 内部串联的运行阶段,不是顶层 LangGraph 节点:
rag-retrievalmemory-readskill-loopskill-callmcp-loopmcp-tool-selection-decisionmcp-pre-generation-gatemcp-argument-generationmcp-argument-verificationmcp-callllm-generationmemory-write
这也是为什么编译图本身只有 router / ai_node / human_node 三个业务节点,而不是将每个内部阶段都展开成单独节点。
补充说明:
- 第 6 到 10 阶段的模型选择会优先尝试
tool_call_model - 第 11 阶段会在
general_model、complex_task_model、reasoning_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,判断优先级如下:
- 当前消息含唯一可识别的追踪标识 → 放行
- 当前消息含追踪标识但有歧义(多个候选值)→ 阻断,返回歧义澄清提示
- 历史中含唯一追踪标识,且当前消息是省略式续问(如"查一下"、"继续"、"那个呢")→ 放行
- 历史中含追踪标识但有歧义 → 阻断,返回歧义澄清提示
- 追踪意图但当前消息与历史均无标识 → 阻断,返回结构化补参提示
- 非追踪内容 → 阻断,静默跳过(不返回补参提示)
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_payloadjson_subset:只保留selected_fields[]命中的字段text:按prefix_text + selected_fields + suffix_text渲染文本wrap_json_code_block=true时,raw_json、json_subset,以及格式化失败后的raw_jsonfallback 都会包成 Markdown```jsonfenced 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 直返会额外包成```jsonfenced 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_role、response_content、observability_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仍然保留最小顶层 LangGraphlanggraph_react_agent_v1不再是空壳,而是复用同样的检索、记忆、观测和 checkpoint 契约- 运行时升级可以在不改变控制面契约的情况下推进
Checkpoint 与长期记忆
Runtime Checkpoint
- 新增持久化表:
runtime_checkpoints - 当前主要用于 MCP 审批边界
- 仅当
runtime_checkpoint.approval_required_tool_names显式命中某个工具时,运行时才会: - 持久化
awaiting_approvalcheckpoint - 返回
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_sourcellm_generated:默认总结路径mcp_raw:命中 MCP 原始 JSON 直返mcp_direct_response:命中 Agent direct-response formattermcp_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_moderaw_json、json_subset、textmcp_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”策略:
- 从
tools/list读取工具定义,优先使用input_schema。 - 若某个挂载声明了自定义
tool_capability,且 Agent 为该 capability 启用了intent_gate_rules[],编排器会先用当前用户消息做一次挂载级门禁;未命中时直接跳过该挂载,不进入discover_tools()。 - 如果一个 MCP Server 暴露多个工具,编排器不会盲选返回列表中的第一个工具。
- 运行时会先过滤空名称工具,再应用 Agent 挂载 allowlist。
- 运行时将
query_tracking与query_tracking9视为同一个 tracking capability;能力级元数据由 capability registry 持有,capability 到 runtime 的映射由 runtime strategy registry 持有,tracking 运行时解析/门控逻辑由 dedicated runtime strategy 持有,并统一由MCPToolAdapterService消费。 - 对自定义 capability 挂载,运行时不会套用 tracking 的确定性选工具、缺参澄清或历史续问策略,而是直接进入常规 AI tool selection 路径。
- 若消息表现为追踪意图、已含追踪标识,或属于可复用历史的省略式续问,则优先选择 tracking tool。
- 若当前轮本身只是纯标识回复,但最近可信
user历史已建立 tracking 上下文(例如上一轮是Track Shipment),运行时也会把该回复视为安全补参并优先选择 tracking tool。 - 若只有一个 eligible tracking tool 且当前消息没有任何追踪信号,则会确定性静默跳过,不再为“是否调用唯一 tracking 工具”额外跑一次 LLM 选择。
- 若确定性规则不足以选中工具,才运行一次 bounded
mcp-tool-selection;该阶段允许返回no_tool,而不是因为“只剩一个工具”就强行进入工具路径。 mcp-tool-selection现在优先走 structured output,并一次返回selected_tool_name + should_call_now + missing_required_arguments + reason;仅在模型/网关不支持时回退到旧的 JSON 提取路径。- 在
mcp-argument-generation之前先执行预门控: - 若工具来自 AI selector,运行时会直接复用该结构化执行决策;
mcp-pre-generation-gate主要负责审计、trace 和用户引导,不再重新猜一次“现在能不能调”。 - 对 tracking tool(
query_tracking/query_tracking9),若“当前消息 + 最近 3 条可信 user 历史”可解析到HBL No. / FBA No. / CTN No. / PO No.之一,则允许继续;运行时会把这些业务标识统一映射到底层 transport 字段selectNo。其中纯selectNo回复也可以在最近历史已明确 tracking 上下文时被接受。 - 若需要补参或澄清,编排器会调用 adapter 的 registry/strategy-backed capability helper 生成结构化 guidance payload,而不是自己硬编码 tracking 分支;这些 payload 统一使用
missing_identifiers与candidate_identifier_arguments这类 capability-generic key。 - 若
user_chat命中追踪意图但缺少标识,则直接返回结构化补参提示,不生成 MCP 参数。常见追踪意图表达包括Track Shipment、where is my package、请帮我查一下进度、查询包裹到哪里了、我想查询货物、eta for my cargo。 - 若是
你好、闲聊、普通问答等非追踪聊天,则静默跳过 MCP,不生成 MCP 参数。 - 对
message_type=rule/form/other,无显式标识时默认静默跳过工具。 - 若当前消息是省略式续问,且最近可信
user历史中只有一个可复用标识,则允许继续;若存在多个竞争标识,则阻断并要求用户澄清。 - 最近历史里的旧单号不会被用于普通闲聊或无关问答;只有当前轮仍表现为追踪意图或省略式续问时,才会复用历史标识。
- 混合字母数字单号(例如
555E898665 帮查一下)现在会在本地规则层优先解析,而不是退回 LLM 选工具。 - 仅在预门控放行后,使用模型根据
current user message + recent trusted user history + tool schema生成tool_argumentsJSON。 mcp-argument-generation与工具选择一样优先走 structured output;若上游模型不支持,再回退到 JSON 文本解析。build_tool_arguments(...)会优先保留可从“当前消息 + 最近可信 user 历史”回溯命中的追踪字段,不可追溯字段会先被剔除。mcp-argument-verification统一负责:- 校验剩余参数是否仍满足
input_schema.required - 校验关键标识字段是否仍可追溯到 trusted user text
- 若失败则直接阻断调用,并返回结构化补参提示与
blocked审计原因 - 审计层会区分:
blocked:准备进入工具路径,但被阻断skipped:当前上下文下不应进入工具路径
API 参考
详细字段与方法说明请查看「API 参考 -> 编排器」。