支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


AI 框架:FastGPT Agent 源码解析 ReAct

发布日期:2025-08-02 08:03:20 浏览次数: 1516
作者:向量仙人

微信搜一搜,关注“向量仙人”

推荐语

深入解析FastGPT Agent的ReAct实现,揭秘大模型推理的三种高效工具调用模式。

核心内容:
1. ReAct与Plan-and-Execute两种推理模式的性能对比与应用场景
2. FastGPT工具调用的三种实现方式及代码架构解析
3. 新旧版本函数调用机制(tool_calls vs function_call)的技术演进

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

本文介绍了 ReAct 、Plan-and-Execute 两种大模型推理模式,以及 FastGPT 对 ReAct 的三种实现方式。


01 ReAct 和 Plan


ReAct(Reasoning and Acting),让大模型通过「观察-思考-行动」三个步骤,循环往复,能够自主决定使用一些工具去解决问题。从代码层面来讲,本质是递归(or 循环),而递归结束的条件往往是超过次数限制、问题已经得到解决等条件。


Plan-and-Execute,相较于 ReAct,会先让大模型制定计划、步骤(子任务),然后按照计划依次执行。中间可能会调整计划,如有必要。


从一些测评集来看,ReAct响应速度更快,消耗 token 量少,但处理复杂任务的表现不及 Plan-and-Execute。这似乎也是意料之中。


笔者认为,在智能客服、需要即时响应等情况下,ReAct是最优解。且大部分实际生产环境中,计划可以由基于 Cot(Chain-of-Thought) 设计模式的 Prompt 来完成。


FastGPT中「工具调用」可以看做是 ReAct 的思路。


02 FastGPT 代码


代码所在目录:



1. 入口与主流程


工具调用的主入口是 dispatchRunTools(见 runTool/index.ts),它负责根据当前节点、上下文、历史消息等,决定是否需要调用工具,并组织好调用工具所需的参数和上下文。


2. 工具调用的三种模式


根据所用大模型的能力,分为三种调用方式:


  • ToolChoice(如 OpenAI 的 tool_calls):runToolWithToolChoice

  • FunctionCall(如 OpenAI 的 function_call):runToolWithFunctionCall

  • PromptCall(通过 prompt 让大模型决定是否调用工具):runToolWithPromptCall


dispatchRunTools 会根据模型的能力选择合适的调用方式。


科普一下 tool_calls 和 function_call 的区别:


function_call(旧版本)

  • 每次只能调用一个函数

  • 已被标记为 deprecated(废弃)


tool_calls(新版本)

  • 支持并行调用多个函数

  • 当前推荐的标准做法


最新的模型,目前主要使用 tool_calls,提供给大模型 tool schema,没有显式的使用Prompt干预整个过程。也可以看一下古老的PromptCall是如何处理的。附源码中的Prompt。


import { replaceVariable } from '@fastgpt/global/common/string/tools';export const Prompt_Tool_Call = `<Instruction>你是一个智能机器人,除了可以回答用户问题外,你还掌握工具的使用能力。有时候,你可以依赖工具的运行结果,来更准确的回答用户。工具使用了 JSON Schema 的格式声明,其中 toolId 是工具的唯一标识, description 是工具的描述,parameters 是工具的参数及参数表述,required 是必填参数的列表。请你根据工具描述,决定回答问题或是使用工具。在完成任务过程中,USER代表用户的输入,TOOL_RESPONSE代表工具运行结果,ANSWER 代表你的输出。你的每次输出都必须以0,1开头,代表是否需要调用工具:0: 不使用工具,直接回答内容。1: 使用工具,返回工具调用的参数。例如:USER: 你好呀ANSWER: 0: 你好,有什么可以帮助你的么?USER: 现在几点了?ANSWER:  1: {"toolId":"searchToolId1"}TOOL_RESPONSE: """2022/5/5 12:00 Thursday"""ANSWER: 0: 现在是202255日,星期四,中午12点。USER: 今天杭州的天气如何?ANSWER: 1: {"toolId":"searchToolId2","arguments":{"city""杭州"}}TOOL_RESPONSE: """晴天......"""ANSWER: 0: 今天杭州是晴天。USER: 今天杭州的天气适合去哪里玩?ANSWER: 1: {"toolId":"searchToolId3","arguments":{"query""杭州 天气 去哪里玩"}}TOOL_RESPONSE: """晴天. 西湖、灵隐寺、千岛湖……"""ANSWER: 0: 今天杭州是晴天,适合去西湖、灵隐寺、千岛湖等地玩。</Instruction>------现在,我们开始吧!下面是你本次可以使用的工具:"""{{toolsPrompt}}"""下面是正式的对话内容:USER: {{question}}ANSWER: `;export const getMultiplePrompt = (obj: {  fileCount: number;  imgCount: number;  question: string;}) => {  const prompt = `Number of session file inputs:Document:{{fileCount}}Image:{{imgCount}}------{{question}}`;  return replaceVariable(prompt, obj);};


3. 工具调用的详细流程


以 runToolWithToolChoice 为例,流程如下(见 runTool/toolChoice.ts):

  1. 准备工具描述:将所有可用工具(toolNodes)转为 OpenAI tool schema,传递给大模型。


  2. 构造对话历史:包括系统 prompt、历史消息、用户输入等。


  3. 请求大模型:带上 tools schema,请求大模型,模型会决定是否需要调用工具,并返回 tool_calls。


  4. 执行工具:根据大模型返回的 tool_calls,找到对应的工具节点,解析参数,实际执行工具(本质是调度 workflow 的子流程)。


  5. 结果回传:将工具执行结果通过 SSE 或直接返回给前端,并递归判断是否需要继续调用工具或结束。


  6. 工具节点的定义与参数

  • 工具节点(toolNodes)包含了工具的唯一标识(nodeId)、描述、参数 schema(JSON Schema 格式)等。

  • 工具参数的定义和校验也在节点 schema 中完成,最终会被序列化为 JSON 传递给大模型。


4. 递归结束条件


1. 工具有交互节点,并被选择


2. 没有工具需要调用

大模型返回的结果中没有需要调用的工具(如 toolCalls/functionCalls/toolJson 为空),说明流程已结束。


3. 递归次数达到上限

有一个保护参数 maxRunToolTimes(如 ToolChoice 默认 30),防止死循环,超过则强制终止。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询