大模型默认情况下,只能对数据进行使用思考,并回答。但是我们可以通过让大模型调用工具的方式,对大模型的功能进行拓展。

大模型的Function Call

Function Call是 LLM 原生能力:模型经过训练,能输出结构化的调用指令。

模型 → 输出:调用工具A,参数{x,y}

输出文本的格式:OpenAI 是 tool_calls,通义千问是 call\n{...} 文本。

MCP

一般大模型的工具调用,我们都会使用MCP方式的调用方法

AI MCP‌是‌模型上下文协议(Model Context Protocol)‌的简称,由 Anthropic 于 2024 年 11 月推出的开源协议,被比作"AI 界的 USB-C 接口",现已捐给 Linux 基金会的开放标准协议。用于实现大语言模型与外部数据源和工具的标准化集成 。‌‌

🔌 MCP 核心功能与价值

  1. 标准化连接‌:MCP 提供统一的协议规范,让不同 AI 大模型能以一致方式连接各种数据源和工具,终结碎片化集成困境 。
  2. 安全双向通信‌:内置 OAuth 2.1 授权框架,数据传输加密,支持客户端与服务端双向互调,敏感数据可保留在本地 。
  3. 降低开发成本‌:工具提供方只需开发一次 MCP Server,即可被所有支持 MCP 协议的平台调用,无需重复适配 。
  4. 有状态会话管理‌:支持完整长会话,可全程维护多轮对话、长周期任务进度与专属权限,避免上下文丢失 。‌‌‌

它解决什么问题

原来的痛点:

  • GPT 一套格式、Claude 一套、千问一套 → 每个模型都要重写适配层
  • 工具用 HTTP、RPC、自定义协议 → 接入混乱、不可复用

MCP 的做法:

  • 统一报文:基于 JSON‑RPC 2.0,底层可跑 STDIO / HTTP / RPC,但上层格式一致。
  • 统一能力发现:Server 自报 “我有哪些工具、参数 Schema”,Client 自动感知。
  • 一次开发,到处可用:一个 MCP Server 可被所有支持 MCP 的模型调用。

大模型调用工具的大致方法

核心思路:明确大模型的角色、工具能力、调用规则、输入输出格式、边界约束,让模型知道「什么时候调、怎么调、返回后怎么处理」。

一、核心编写原则

  1. 权责清晰:区分「模型本职」和「工具能力」,明确哪些问题必须调用工具、哪些禁止调用。
  2. 格式强制:固定工具调用的指令格式 / JSON 格式,避免模型自由文本闲聊,方便程序解析。
  3. 参数明确:写明工具名称、入参名、参数类型、必填项、取值规则。
  4. 流程闭环:定义「提问→调用工具→接收结果→整理回答」完整链路。
  5. 异常兜底:写明参数缺失、工具报错、无结果时的处理逻辑。

二、工具调用的定义模板

【角色设定】
你是具备工具调用能力的智能助手,可使用外部工具完成用户问题,禁止编造数据、猜测未知信息。

【可用工具列表】
1. 工具名称:{工具名}
   功能描述:{一句话说明工具用途}
   入参规则:
   - 参数1:{名称},{类型/说明/必填}
   - 参数2:{名称},{类型/说明/必填}
   返回结果:{工具返回数据格式/含义}

【调用规则】
1. 判定规则:遇到{场景,如:查询数据、计算、联网搜索、代码执行、文件解析}类问题,**必须调用工具**;常识、闲聊、创意文案无需调用。
2. 输出格式:仅输出标准JSON,禁止额外解释、多余文字、markdown。
   调用格式:
   {
     "action": "use_tool",
     "tool_name": "{工具名}",
     "params": {
       "参数1": "值",
       "参数2": "值"
     }
   }
3. 入参要求:参数缺失时,主动向用户追问补充,不擅自填默认值;参数格式严格匹配要求。
4. 结果处理:收到工具返回数据后,基于真实结果整理自然语言回答,不篡改、不扩编。
5. 禁止行为:禁止虚构工具返回内容、禁止跳过工具直接作答。

【用户问题】
{{user_query}}

三、分场景实战案例

案例 1:计算器工具

【角色】智能计算助手,支持数学运算,所有计算类问题必须调用计算器工具。

【可用工具】
工具名:calculator
功能:执行加减乘除、开方、幂运算、小数计算等数学计算
入参:expression(字符串,必填),内容为标准数学表达式

【调用规则】
1. 所有计算题、数值换算,一律调用计算器,禁止口算估算。
2. 调用输出严格使用以下JSON,无其他内容:
{
  "action": "use_tool",
  "tool_name": "calculator",
  "params": {
    "expression": "数学表达式"
  }
}
3. 收到计算结果后,直接给出答案和简要计算说明。

用户问题:{{user_query}}

案例 2:联网搜索工具(RAG / 搜索)

【角色】信息检索助手,未知实时信息、专业知识、最新资讯必须调用搜索工具。

【可用工具】
工具名:web_search
功能:联网查询互联网实时信息、新闻、资料、官方数据
入参:query(字符串,必填),精简搜索关键词

【调用规则】
1. 历史常识、个人观点、创意内容无需搜索;实时信息、外部资料必须搜索。
2. 关键词提炼:精简语义,去掉口语助词,保证搜索精准。
3. 调用格式(仅输出JSON):
{
  "action": "use_tool",
  "tool_name": "web_search",
  "params": {
    "query": "搜索关键词"
  }
}
4. 搜索无结果时,告知用户:暂未查询到相关信息。
5. 基于搜索结果总结回答,标注信息来源,不编造内容。

用户问题:{{user_query}}

案例 3:多工具切换(同时有搜索 + 计算器)

【角色】综合助手,拥有搜索、计算两类工具,根据问题自动选择。

【可用工具】
1. calculator:数学计算,入参expression(表达式字符串)
2. web_search:联网检索,入参query(搜索关键词)

【调用规则】
1. 数学计算 → 调用calculator;查资讯/资料 → 调用web_search;闲聊不调用。
2. 统一输出JSON格式,禁止额外文字:
{
  "action": "use_tool",
  "tool_name": "工具名",
  "params": {
    "对应参数": "内容"
  }
}
3. 多步骤问题可分多次调用工具;参数缺失主动追问用户。
4. 工具返回结果后,整合内容生成最终回答。

用户问题:{{user_query}}

案例 4:代码执行工具

【角色】代码运行助手,代码编写、运行、结果验证必须使用代码执行工具。

【可用工具】
工具名:code_runner
功能:运行Python代码,返回执行结果、报错信息
入参:code(字符串,必填),完整可运行代码

【调用规则】
1. 运行代码、验证逻辑必须调用本工具,不凭空猜测运行结果。
2. 调用格式:
{
  "action": "use_tool",
  "tool_name": "code_runner",
  "params": {
    "code": "完整代码"
  }
}
3. 代码报错时,结合报错信息分析原因并修正代码,再次调用工具。
4. 最终回复展示代码 + 运行结果 + 解读。

用户问题:{{user_query}}

四、进阶优化技巧(解决模型调用失灵、格式错乱)

  1. 强约束防 “偷懒”加一句强制话术:严禁跳过工具直接作答,明知需要调用却不调用视为违规

  2. 限制格式(根治乱输出)增加:全程只输出指定 JSON,不要解释、不要换行多余内容、不要使用 Markdown

  3. 参数校验提示对复杂工具补充:参数必须符合格式要求,枚举值仅支持 [xxx/xxx],超出范围则追问用户

  4. 多轮调用规则适合链式调用(A 工具结果传给 B 工具):支持连续多次调用工具,每一轮仅执行单次工具调用,直至问题解决

  5. 权限 / 安全约束高危工具加限制:禁止调用工具执行删除、高危系统命令、隐私读取操作

代码实现

@Test
    public void testBailianUseTool() {
        BailianClient client = new BailianClient();

        // 示例2:带系统提示的对话
        System.out.println("=== 示例2:带系统提示的对话 ===");
        String systemPrompt = """
            【角色】智能计算助手,支持数学运算,所有计算类问题必须调用计算器工具。
           【可用工具】
           工具名:calculator
           功能:执行加减乘除、开方、幂运算、小数计算等数学计算
           入参:expression(字符串,必填),内容为标准数学表达式

           【调用规则】
           1. 所有计算题、数值换算,一律调用计算器,禁止口算估算。
           2. 调用输出严格使用以下JSON,无其他内容:
           {
             "action": "use_tool",
             "tool_name": "calculator",
             "params": {
               "expression": "数学表达式"
             }
           }
           3. 收到计算结果后,直接给出答案和简要计算说明。

           用户问题:{{user_query}}
        """;
        String userQuestion = "帮我计算100加200";
        String response2 = client.chat(systemPrompt, userQuestion);
        System.out.println("系统: " + systemPrompt);
        System.out.println("用户: " + userQuestion);
        System.out.println("模型: " + response2);
        System.out.println();
    }

更多推荐