从 Function Calling 到 RAG:AI 应用开发的三把钥匙

0 阅读4分钟

你是否好奇 ChatGPT 是怎么联网搜索的?AI 助手怎么能调用外部工具?知识库问答系统背后是什么原理?这篇文章带你搞懂 Tools、Function Calling、RAG 这三个核心概念。

一、为什么 LLM 需要"外挂"?

大语言模型(LLM)本质上是一个文本预测机器,它的知识来自训练数据,有两个天然缺陷:

  • 知识截止日期:不知道最新发生的事
  • 无法执行操作:不能查数据库、不能发邮件、不能调 API

为了突破这两个限制,业界发展出了三种核心技术:Tools(工具调用)Function CallingRAG(检索增强生成)


二、Function Calling:让 AI 学会"打电话"

是什么?

Function Calling 是 OpenAI 在 GPT-3.5/4 中引入的能力,允许你预先定义一批函数,让模型在合适的时机决定调用哪个函数、传什么参数。

工作流程

用户提问 → LLM 判断需要调用函数 → 返回函数名+参数(JSON)
→ 你的代码执行函数 → 把结果返回给 LLMLLM 生成最终回答

注意:LLM 本身不执行函数,它只是告诉你"我需要调用这个函数,参数是这些",真正执行是你的代码。

代码示例

const tools = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "获取指定城市的天气",
      parameters: {
        type: "object",
        properties: {
          city: {
            type: "string",
            description: "城市名称,如:北京"
          }
        },
        required: ["city"]
      }
    }
  }
];

// 第一次请求:让模型决定是否调用函数
const response = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [{ role: "user", content: "北京今天天气怎么样?" }],
  tools: tools,
  tool_choice: "auto"
});

// 模型返回:需要调用 get_weather,参数 city="北京"
const toolCall = response.choices[0].message.tool_calls[0];
const args = JSON.parse(toolCall.function.arguments);

// 你的代码执行真实的天气查询
const weatherResult = await getWeather(args.city);

// 第二次请求:把结果告诉模型,让它生成回答
const finalResponse = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [
    { role: "user", content: "北京今天天气怎么样?" },
    response.choices[0].message,
    {
      role: "tool",
      tool_call_id: toolCall.id,
      content: JSON.stringify(weatherResult)
    }
  ]
});

三、Tools:Function Calling 的进化版

区别在哪?

对比项Function CallingTools
出现时间较早较新(统一标准)
支持类型仅函数函数 + 代码解释器 + 文件检索等
并发调用单个支持同时调用多个
适用场景简单工具调用复杂 Agent 场景

简单说:Tools 是 Function Calling 的超集,现在 OpenAI 官方推荐统一用 tools 参数。

多工具并发示例

// 模型可以同时决定调用多个工具
// 比如用户问:"帮我查北京天气,顺便查一下明天的日历安排"
// 模型会同时返回两个 tool_call,你并发执行后一起返回结果

四、RAG:给 AI 装上"私人图书馆"

是什么?

RAG(Retrieval-Augmented Generation,检索增强生成)解决的是另一个问题:如何让 AI 回答基于你私有数据的问题

比如:

  • 公司内部文档问答
  • 产品手册智能客服
  • 个人知识库助手

核心流程

离线阶段(建库):
文档 → 切片 → Embedding(向量化)→ 存入向量数据库

在线阶段(查询):
用户提问 → 问题向量化 → 向量数据库相似度检索
→ 取出相关文档片段 → 拼入 Prompt → LLM 生成回答

关键概念解释

Embedding(向量化)

把文字转换成一串数字(向量),语义相近的文字,向量距离也近。

// 用 OpenAI Embedding API 把文本转成向量
const embedding = await openai.embeddings.create({
  model: "text-embedding-3-small",
  input: "如何申请年假?"
});
// 返回一个 1536 维的数字数组

向量数据库

专门存储和检索向量的数据库,常见的有:

  • Chroma(本地,适合开发)
  • Pinecone(云端,生产推荐)
  • Milvus(开源,高性能)
  • pgvector(PostgreSQL 插件)

简单 RAG 实现思路

// 1. 建库:把文档切片并存入向量库
async function buildIndex(documents) {
  for (const doc of documents) {
    const chunks = splitText(doc, 500); // 每500字切一片
    for (const chunk of chunks) {
      const vector = await getEmbedding(chunk);
      await vectorDB.insert({ text: chunk, vector });
    }
  }
}

// 2. 查询:检索相关片段 + 让 LLM 回答
async function ragQuery(question) {
  const questionVector = await getEmbedding(question);
  const relevantChunks = await vectorDB.search(questionVector, topK=3);
  
  const context = relevantChunks.map(c => c.text).join("\\n\\n");
  const prompt = `
    根据以下资料回答问题,如果资料中没有相关信息,请说"我不知道"。
    
    资料:
    ${context}
    
    问题:${question}
  `;
  
  return await llm.chat(prompt);
}

五、三者的关系与组合使用

用户
 │
 ▼
Agent(智能体)
 ├── Tools/Function Calling → 调用外部 API、执行代码、操作数据库
 └── RAG → 检索私有知识库、历史对话记忆

实际项目中的典型组合:

  • 智能客服 = RAG(产品文档)+ Function Calling(查订单、退款)
  • AI 编程助手 = RAG(代码库)+ Tools(执行代码、搜索文档)
  • 个人助理 = RAG(个人笔记)+ Tools(查日历、发邮件)

六、学习路径建议

初学者路线:

  1. 先跑通一个 Function Calling 的 Hello World
  2. 用 LangChain 或 LlamaIndex 快速搭一个 RAG Demo
  3. 理解向量和 Embedding 的概念

进阶路线:

  1. 手写 RAG 流程,不依赖框架
  2. 研究 Rerank(重排序)提升 RAG 准确率
  3. 探索 Agent 框架(LangGraph、AutoGen)

总结

技术解决的问题核心机制
Function CallingAI 无法执行操作模型输出结构化调用指令
Tools复杂多工具场景Function Calling 的超集
RAGAI 不知道私有数据检索 + 生成

这三个技术是构建实用 AI 应用的基础,掌握了它们,你就能从"玩 ChatGPT"升级到"构建 AI 应用"。