你是否好奇 ChatGPT 是怎么联网搜索的?AI 助手怎么能调用外部工具?知识库问答系统背后是什么原理?这篇文章带你搞懂 Tools、Function Calling、RAG 这三个核心概念。
一、为什么 LLM 需要"外挂"?
大语言模型(LLM)本质上是一个文本预测机器,它的知识来自训练数据,有两个天然缺陷:
- 知识截止日期:不知道最新发生的事
- 无法执行操作:不能查数据库、不能发邮件、不能调 API
为了突破这两个限制,业界发展出了三种核心技术:Tools(工具调用)、Function Calling、RAG(检索增强生成)。
二、Function Calling:让 AI 学会"打电话"
是什么?
Function Calling 是 OpenAI 在 GPT-3.5/4 中引入的能力,允许你预先定义一批函数,让模型在合适的时机决定调用哪个函数、传什么参数。
工作流程
用户提问 → LLM 判断需要调用函数 → 返回函数名+参数(JSON)
→ 你的代码执行函数 → 把结果返回给 LLM → LLM 生成最终回答
注意: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 Calling | Tools |
|---|---|---|
| 出现时间 | 较早 | 较新(统一标准) |
| 支持类型 | 仅函数 | 函数 + 代码解释器 + 文件检索等 |
| 并发调用 | 单个 | 支持同时调用多个 |
| 适用场景 | 简单工具调用 | 复杂 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(查日历、发邮件)
六、学习路径建议
初学者路线:
- 先跑通一个 Function Calling 的 Hello World
- 用 LangChain 或 LlamaIndex 快速搭一个 RAG Demo
- 理解向量和 Embedding 的概念
进阶路线:
- 手写 RAG 流程,不依赖框架
- 研究 Rerank(重排序)提升 RAG 准确率
- 探索 Agent 框架(LangGraph、AutoGen)
总结
| 技术 | 解决的问题 | 核心机制 |
|---|---|---|
| Function Calling | AI 无法执行操作 | 模型输出结构化调用指令 |
| Tools | 复杂多工具场景 | Function Calling 的超集 |
| RAG | AI 不知道私有数据 | 检索 + 生成 |
这三个技术是构建实用 AI 应用的基础,掌握了它们,你就能从"玩 ChatGPT"升级到"构建 AI 应用"。