Function Call 往返:tool_calls→invoke→tool 消息回喂

Function Call 往返:tool_calls→invoke→tool 消息回喂 由 Archify 生成的时序图。 ① chatCompletion(messages, tools=getAllTools) ② POST /chat/completions(含 tools 声明) ③ finish_reason=tool_calls:name + arguments JSON ④ ChatCompletionResponse.choices[0].toolCalls ⑤ ToolUtil.invoke(functionName, argument) ⑥ 分发:内置→executor · MCP→callTool · 函数→反射 invoke ⑦ String result(业务输出) ⑧ 结果字符串 ⑨ 追加 role=tool 消息后再次 chatCompletion ⑩ 第二轮(含 tool 结果)→ 最终文本回答 宿主调用方 · 驱动两轮调用 · 时序参与者 宿主调用方 驱动两轮调用 ChatService · chatCompletion · 时序参与者 ChatService chatCompletion Provider 模型 · tool_calls 裁决 · 时序参与者 Provider 模型 tool_calls 裁决 ToolUtil · invoke 分发 · 时序参与者 ToolUtil invoke 分发 工具实现 · 函数/MCP/内置 · 时序参与者 工具实现 函数/MCP/内置 图例 默认消息

注解扫描成工具面

  • • @FunctionCall(name, description, strict) + @FunctionParameter 标注 POJO 方法;ToolUtil 用 Reflections 扫描进 toolEntityMap/toolClassMap
  • • getAllTools(functions, mcpIds) 只生成显式声明的 tools 数组——不传不暴露

invoke 三路分发

  • • 内置工具 → BuiltInToolExecutor.invoke(BuiltInToolContext 栈式上下文 push/pop)
  • • MCP 工具 → invokeMcpTool 反射接 mcpGateway.callTool;普通函数 → newInstance + method.invoke 注入解析参数

回喂语义

  • • tool_calls 出现时本轮无最终文本:宿主必须把每条 call 的结果以 role=tool + tool_call_id 追加进 messages
  • • 第二轮模型基于完整对话(含 tool 输出)产出自然语言回答;多 call 可并行执行后逐条回填