阅读视图

发现新文章,点击刷新页面。

前端AI应用开发深入理解 FunctionCall:让 LLM 拥有"超能力"的完整指南

想象一下,如果你的 AI 助手不仅能聊天,还能帮你查询实时天气、调用 API、执行数据库查询,那会是什么体验?FunctionCall 技术正是实现这一目标的关键!

🌟 什么是 FunctionCall?

FunctionCall(函数调用)是一种让大语言模型(LLM)能够调用外部工具函数的技术。它打破了传统 LLM 只能基于训练数据回答问题的限制,让 AI 能够:

  • 🔍 查询实时数据(如天气、股票价格)
  • 📊 访问数据库获取最新信息
  • 🔗 调用第三方 API 服务
  • ⚙️ 执行特定的业务逻辑

简单来说,FunctionCall 就像是给 LLM 装上了"手脚",让它不仅能"思考",还能"行动"!

🚀 为什么需要 FunctionCall?

传统的 LLM 有一个明显的局限:它只能基于训练时的数据回答问题。这意味着:

❌ 无法获取实时信息(比如今天的天气) ❌ 无法访问你的私有数据 ❌ 无法执行具体的操作(如发送邮件、创建订单)

而 FunctionCall 完美解决了这些问题!它让 LLM 成为了一个智能的"调度器",能够:

  • 理解用户的自然语言需求
  • 判断需要调用哪些工具
  • 自动提取函数参数
  • 将执行结果转化为自然语言回答

FunctionCall 完整工作流程

让我们通过一个实际例子来理解整个流程。假设用户问:"北京今天天气怎么样?"

🔧 步骤 1:定义工具描述

首先,我们需要告诉 LLM 有哪些工具可以使用。这就像给 LLM 提供一份"工具说明书":

const tools = [
  {
    type: "function",
    function: {
      name: "get_current_weather",
      description: "获取指定城市当前的实时天气",
      parameters: {
        type: "object",
        properties: {
          city: {
            type: "string",
            description: "城市名称",
          },
          unit: {
            type: "string",
            enum: ["摄氏度", "华氏度"],
            description: "温度单位",
          },
        },
        required: ["city"],
      },
    },
  },
];

这里的描述非常重要!LLM 会根据 description 来判断何时需要调用这个函数,根据 parameters 来提取用户输入中的参数值。

⚙️ 步骤 2:实现实际函数

定义好工具描述后,我们需要实现真正的函数逻辑:

function get_current_weather(city, unit = "摄氏度") {
  // 这里可以调用外部 API 来获取真实天气数据
  console.log(`正在获取 ${city} 的天气...`);
  const weather = {
    city: city,
    temperature: "25",
    unit: unit,
    forecast: "晴朗",
  };
  return JSON.stringify(weather);
}

这个函数可以调用任何你需要的 API 或执行任何业务逻辑。

🔗 步骤 3:建立函数映射

为了方便调用,我们创建一个映射对象:

const availableFunctions = {
  get_current_weather: get_current_weather,
};

这样 LLM 返回函数名后,我们就能快速找到对应的函数并执行。

🚀 步骤 4:发起对话

现在,我们将用户的问题和可用工具一起发送给 LLM:

const response = await zhipuClient.createCompletions({
  model: llmModel,
  messages: [
    {
      role: "user",
      content: "北京今天天气怎么样?",
    },
  ],
  tools: tools, // 告诉 LLM 有哪些工具可用
});

🤔 步骤 5:LLM 智能决策

LLM 会分析用户的问题,并做出智能判断:

情况 A:需要调用工具

{
  "tool_calls": [
    {
      "id": "call_123",
      "function": {
        "name": "get_current_weather",
        "arguments": "{\"city\": \"北京\", \"unit\": \"摄氏度\"}"
      }
    }
  ]
}

情况 B:不需要调用工具

{
  "content": "我是 AI 助手,无法直接回答天气问题。"
}

这就是 FunctionCall 的神奇之处:LLM 自动判断是否需要调用工具,并从自然语言中提取参数!

💻 步骤 6:执行本地函数

当 LLM 决定调用工具时,我们解析参数并执行函数:

const toolCall = message.tool_calls[0];
const functionName = toolCall.function.name;
const functionArgs = JSON.parse(toolCall.function.arguments);

const functionResponse = availableFunctions[functionName](
  functionArgs.city,
  functionArgs.unit
);

执行结果可能是:

{
  "city": "北京",
  "temperature": "25",
  "unit": "摄氏度",
  "forecast": "晴朗"
}

🔄 步骤 7:回传结果给 LLM

将函数执行结果作为上下文再次发送给 LLM:

const secondResponse = await zhipuClient.createCompletions({
  model: llmModel,
  messages: [
    { role: "user", content: "北京今天天气怎么样?" }, // 原始问题
    message, // LLM 的工具调用请求
    {
      role: "tool", // 工具执行结果
      tool_call_id: toolCall.id,
      content: functionResponse,
    },
  ],
});

这一步非常关键!LLM 需要看到完整的对话历史,包括:

  • 用户的问题
  • 自己的工具调用决策
  • 工具的执行结果

✅ 步骤 8:生成最终回答

最后,LLM 基于函数执行结果,生成自然语言的回答:

根据查询结果,北京今天的天气是晴朗,温度为 25 摄氏度。今天是个好天气,适合外出活动!

🎯 FunctionCall 的核心优势

1. 智能决策 🧠

LLM 自动判断是否需要调用工具,无需复杂的规则判断。比如:

  • 用户问"北京天气怎么样?" → 调用天气查询函数
  • 用户问"什么是人工智能?" → 直接回答,无需调用工具

2. 参数解析 📝

LLM 能够从自然语言中精准提取参数:

  • "北京今天天气怎么样?" → city="北京"
  • "查一下上海的天气,用华氏度" → city="上海", unit="华氏度"
  • "纽约的天气如何" → city="纽约"

3. 结果整合 💬

LLM 将结构化的函数结果转化为自然的语言回答,让用户体验更加流畅。

4. 多轮对话 🔄

支持连续的工具调用和上下文延续,可以进行复杂的任务链。

� 实际应用场景

场景 1:智能客服助手

// 工具:查询订单状态
function get_order_status(orderId) { ... }

// 工具:处理退款
function process_refund(orderId, reason) { ... }

// 用户:"我的订单 #12345 怎么还没到?"
// LLM 自动调用 get_order_status("12345")
// 回答:"您的订单 #12345 已发货,预计明天送达"

场景 2:数据分析助手

// 工具:查询数据库
function query_database(sql) { ... }

// 工具:生成图表
function generate_chart(data, type) { ... }

// 用户:"帮我看看上个月的销售数据"
// LLM 自动调用 query_database 和 generate_chart

场景 3:办公自动化

// 工具:发送邮件
function send_email(to, subject, body) { ... }

// 工具:创建日程
function create_calendar_event(title, time) { ... }

// 用户:"帮我给张三发封邮件约明天开会"
// LLM 自动调用 send_email 和 create_calendar_event

🛠️ 快速开始

1. 安装依赖

npm install zhipu-sdk-js dotenv

2. 配置环境变量

创建 .env 文件:

ZHIPUAI_API_KEY=your_api_key_here

3. 编写代码

import ZhipuAI from "zhipu-sdk-js";
import "dotenv/config";

const zhipuClient = new ZhipuAI({
  apiKey: process.env.ZHIPUAI_API_KEY,
});

// 定义工具、实现函数、运行对话...

4. 运行示例

node index.js

📚 技术栈

  • Node.js: 运行环境
  • zhipu-sdk-js: 智谱 AI 官方 SDK
  • GLM-4.5-Flash: 高性能大语言模型
  • dotenv: 环境变量管理

🔮 未来展望

FunctionCall 技术正在快速发展,未来可能支持:

  • 🤖 多工具并行调用
  • 📊 复杂的工具调用链
  • 🎯 自适应工具选择
  • 🔒 更安全的权限控制

代码示例

// index.js
import ZhipuAI from "zhipu-sdk-js";

import "dotenv/config";

// 步骤 1: 定义你的工具函数
const tools = [
  {
    type: "function",
    function: {
      name: "get_current_weather",
      description: "获取指定城市当前的实时天气",
      parameters: {
        type: "object",
        properties: {
          city: {
            type: "string",
            description: "城市名称",
          },
          unit: {
            type: "string",
            enum: ["摄氏度", "华氏度"],
            description: "温度单位",
          },
        },
        required: ["city"],
      },
    },
  },
];

// 步骤 2: 创建一个假想的函数来执行工具
function get_current_weather(city, unit = "摄氏度") {
  // 这里可以调用外部 API 来获取真实天气数据
  // 为了简化,我们直接返回一个模拟值
  console.log(`正在获取 ${city} 的天气...`);
  const weather = {
    city: city,
    temperature: "25",
    unit: unit,
    forecast: "晴朗",
  };
  return JSON.stringify(weather);
}

// 定义一个映射,将函数名和实际函数绑定
const availableFunctions = {
  get_current_weather: get_current_weather,
};

const zhipuClient = new ZhipuAI({
  apiKey: process.env.ZHIPUAI_API_KEY,
});

const llmModel = "glm-4.5-flash";
async function runConversation() {
  const userMessage = "北京今天天气怎么样?";

  // 向 LLM 发送用户问题,并提供可用的工具
  const response = await zhipuClient.createCompletions({
    model: llmModel,
    messages: [
      {
        role: "user",
        content: userMessage,
      },
    ],
    tools: tools,
  });
  debugger;
  const message = response.choices[0].message;

  // 步骤 3: 检查 LLM 是否决定调用函数
  if (message.tool_calls && message.tool_calls.length > 0) {
    const toolCall = message.tool_calls[0];
    const functionName = toolCall.function.name;
    const functionArgs = JSON.parse(toolCall.function.arguments);

    // 步骤 4: 在本地执行函数
    const functionResponse = availableFunctions[functionName](
      functionArgs.city,
      functionArgs.unit,
    );

    // 再次调用 LLM,将函数执行结果作为上下文
    const secondResponse = await zhipuClient.createCompletions({
      model: llmModel,
      messages: [
        { role: "user", content: userMessage },
        message, // 将 LLM 第一次的响应也作为上下文
        {
          role: "tool",
          tool_call_id: toolCall.id,
          content: functionResponse, // 将函数执行结果作为上下文
        },
      ],
    });

    // 最终返回 LLM 基于函数结果生成的回答
    console.log(secondResponse.choices[0].message.content);
  } else {
    // 如果 LLM 没决定调用函数,直接返回 LLM 的回答
    console.log(message.content);
  }
}

runConversation();
{
  "name": "function_call_llm",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^17.2.3",
    "zhipu-sdk-js": "^1.0.0"
  }
}

📝 总结

FunctionCall 是连接 LLM 与现实世界的桥梁,它让 AI 从"聊天机器人"进化为"智能助手"。通过掌握这项技术,你可以:

  1. 构建更强大的 AI 应用
  2. 提供更智能的用户体验
  3. 实现更复杂的业务场景

现在就开始尝试吧! 让你的 AI 助手拥有真正的"超能力"!🚀


💡 小贴士:本文档配套了完整的示例代码,你可以直接运行体验 FunctionCall 的强大功能。如有问题,欢迎交流讨论!

❌