技术探索不迷路:从Function Calling到RAG的实战入门
大家好,我是VibeCoding的后端讲师,工作五年来带过不少零基础学员。今天写这篇教程,是因为最近很多初学者问我:“大模型很火,但我该怎么用它做点实际的东西?”——这让我想起自己刚接触AI编程时也是一头雾水。
别担心!这篇文章会带你亲手做出一个能查资料、会调函数的小助手,全程不用懂数学公式,只要会写简单代码就行。我们会重点搞懂两个关键词:Function Calling 和 RAG。它们就像AI的“手脚”和“外挂大脑”,让你的程序真正“聪明”起来。
一、这两个词到底在干啥?
先别被术语吓到,我用生活例子解释:
Function Calling = 给AI装“手”
想象你雇了个聪明但不能动的助理(大模型)。你说:“帮我查下天气。”
他只能回答:“我不知道。”
但如果你给他配个手机App(函数),他就能主动调用这个App去查天气,再告诉你结果。
这就是Function Calling:让AI在需要时自动调用你写的函数,获取实时数据或执行操作。
RAG = 给AI配“外挂笔记本”
假设你问AI:“我们公司上周的项目进展如何?”
普通AI会瞎猜(因为训练数据里没有你们公司的内部信息)。
但如果你提前把项目文档喂给它,它就能精准引用文档内容作答。
这就是RAG(Retrieval-Augmented Generation):先从你的资料库中检索相关信息,再让AI基于这些信息生成回答。
💡 我当初学的时候,以为必须精通机器学习才能玩这些。后来发现:只要会调API+写函数,就能搭出实用系统!
二、动手前的环境准备
我们用Python(最友好的入门语言)+ 开源工具链,全程免费!
需要安装什么?
| 工具 | 作用 | 安装命令 |
|---|---|---|
| Python 3.8+ | 编程语言基础 | 官网下载 |
| pip | Python包管理器 | 自带无需单独装 |
| openai | 调用大模型API | pip install openai |
| langchain | 快速实现RAG | pip install langchain |
| faiss-cpu | 向量数据库(存资料) | pip install faiss-cpu |
获取API密钥(关键步骤!)
- 访问 OpenAI平台
- 注册账号(支持国内手机号)
- 进入 API Keys 页面 → Create new secret key
- 复制密钥,保存到本地文件
.env(内容:OPENAI_API_KEY=你的密钥)
⚠️ 注意:密钥不要提交到GitHub!后续代码会自动读取
.env文件
三、核心概念拆解:用代码说话
1. Function Calling 实战
先写个能查天气的函数:
# weather_tool.py
import requests
def get_weather(city: str) -> str:
"""查询城市天气的函数"""
url = f"http://wttr.in/{city}?format=3"
response = requests.get(url)
return response.text.strip()
现在让AI学会调用它:
# function_calling_demo.py
from openai import OpenAI
import json
client = OpenAI()
# 告诉AI有哪些函数可用
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如'北京'"}
},
"required": ["city"]
}
}
}
]
# 用户提问
messages = [{"role": "user", "content": "上海今天天气怎么样?"}]
# 请求AI(要求它考虑是否调用函数)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
tools=tools,
tool_choice="auto" # 让AI自动决定是否调用
)
# 检查AI是否要调用函数
tool_call = response.choices[0].message.tool_calls
if tool_call:
# 执行函数
city = json.loads(tool_call[0].function.arguments)["city"]
weather_result = get_weather(city)
# 把结果告诉AI,让它生成最终回答
messages.append(response.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": tool_call[0].id,
"content": weather_result
})
final_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
print(final_response.choices[0].message.content)
运行效果:
上海目前多云,气温22°C。
🔑 关键逻辑:
- AI先返回“我要调用get_weather函数”
- 程序执行函数拿到真实数据
- 把数据塞回对话,AI据此生成自然语言回答
2. RAG 实战:打造你的知识库
假设你有份《公司产品手册.txt》,想让AI基于它回答问题。
步骤1:把文档切成小段
from langchain.text_splitter import CharacterTextSplitter
with open("产品手册.txt", encoding="utf-8") as f:
text = f.read()
text_splitter = CharacterTextSplitter(
chunk_size=300, # 每段300字符
chunk_overlap=50 # 相邻段重叠50字符防断句
)
chunks = text_splitter.split_text(text)
步骤2:把文本转成向量存进数据库
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# 用OpenAI的embedding模型转换文本
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_texts(chunks, embeddings)
步骤3:提问时自动检索+生成答案
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever()
)
answer = qa_chain.run("我们的旗舰产品有什么特点?")
print(answer)
背后发生了什么?
文字描述流程图:
用户提问 → 在向量库中找最相关的3段文档 → 把文档+问题一起发给AI → AI基于文档生成答案
💡 为什么需要切分文档?
大模型有输入长度限制(比如最多4096字),长文档必须切块处理
四、综合实战:做个智能客服机器人
现在把Function Calling和RAG结合起来!目标:
✅ 能回答公司产品问题(用RAG)
✅ 能查询订单状态(用Function Calling)
1. 准备材料
产品手册.txt(公司产品介绍)- 模拟订单查询函数
# order_tool.py
def get_order_status(order_id: str) -> str:
"""模拟查询订单状态"""
# 实际项目这里会调数据库或API
fake_db = {
"ORD123": "已发货",
"ORD456": "处理中"
}
return fake_db.get(order_id, "订单不存在")
2. 主程序整合
# smart_agent.py
import os
from dotenv import load_dotenv
from openai import OpenAI
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
load_dotenv() # 读取.env中的API密钥
client = OpenAI()
# 初始化RAG组件
with open("产品手册.txt", encoding="utf-8") as f:
text = f.read()
text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=50)
chunks = text_splitter.split_text(text)
vectorstore = FAISS.from_texts(chunks, OpenAIEmbeddings())
# 定义可用工具
tools = [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "查询订单状态",
"parameters": {"type": "object", "properties": {
"order_id": {"type": "string"}
}, "required": ["order_id"]}
}
}
]
def handle_query(user_input: str):
# 第一步:用RAG检索相关产品知识
relevant_docs = vectorstore.similarity_search(user_input, k=2)
context = "\n".join([doc.page_content for doc in relevant_docs])
# 第二步:构造包含上下文的对话
messages = [
{"role": "system", "content": f"你是个客服,参考以下资料回答:{context}"},
{"role": "user", "content": user_input}
]
# 第三步:请求AI(允许调用工具)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
tools=tools,
tool_choice="auto"
)
# 第四步:处理函数调用(如有)
tool_call = response.choices[0].message.tool_calls
if tool_call:
func_name = tool_call[0].function.name
args = eval(tool_call[0].function.arguments) # 实际项目用json.loads更安全
if func_name == "get_order_status":
result = get_order_status(args["order_id"])
# 返回最终答案
messages.append(response.choices[0].message)
messages.append({"role": "tool", "content": result, "tool_call_id": tool_call[0].id})
final_resp = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages
)
return final_resp.choices[0].message.content
return response.choices[0].message.content
# 测试
print(handle_query("旗舰产品支持5G吗?")) # 触发RAG
print(handle_query("订单ORD123到哪了?")) # 触发Function Calling
运行效果:
是的,旗舰产品X1支持5G网络,最高下载速度可达2Gbps。
您的订单ORD123已发货,预计明天送达。
五、新手常见问题急救包
❓ 问题1:API调用总报错"Invalid API Key"
- 原因:密钥没正确加载
- 解决:
- 确认
.env文件和代码在同一目录 - 文件内容格式:
OPENAI_API_KEY=sk-xxxxxx(等号两边无空格) - 代码开头加
from dotenv import load_dotenv; load_dotenv()
- 确认
❓ 问题2:RAG返回的答案和文档无关
- 原因:文档切分太碎或向量检索不准
- 解决:
- 调大
chunk_size(比如500) - 检查文档编码(用
encoding="utf-8"打开) - 在提问时加提示词:“请严格根据提供的资料回答”
- 调大
❓ 问题3:Function Calling不触发
- 原因:函数描述不够清晰
- 解决:
- 在
description里明确使用场景,例如:“当用户询问订单、物流、配送时调用此函数” - 参数说明要具体:“订单ID格式为ORD+三位数字”
- 在
❓ 问题4:运行速度慢
- 优化方案:
- 用
gpt-3.5-turbo代替gpt-4(便宜10倍+快3倍) - 向量数据库首次创建后保存到磁盘:
vectorstore.save_local("faiss_index"),下次直接加载
- 用
六、下一步学习路线图
你已经掌握了AI应用开发的核心模式!接下来可以:
🔹 深化方向
| 方向 | 推荐资源 | 关键技能 |
|---|---|---|
| 更复杂的Agent | LangChain官方文档 | 记忆管理、多工具协作 |
| 私有化部署 | LlamaIndex + 本地模型 | 无需联网的AI应用 |
| 生产级优化 | FastAPI + 异步调用 | 高并发接口设计 |
🔹 避坑指南(血泪经验!)
- 别一上来就搞大模型微调:90%的场景用Function Calling+RAG就够了
- 测试时打印中间结果:比如AI选择的函数参数、检索到的文档片段
- 成本控制:在代码里加token计数器,避免意外高额账单
最后送大家一句话:技术探索不是比谁懂的理论多,而是看谁能快速做出可运行的原型。你现在手里的代码,已经是很多创业公司的MVP(最小可行产品)了!
动手试试吧!遇到问题欢迎在评论区留言,我会一一解答。下期我们聊聊《如何用30行代码搭建AI搜索框》,记得关注~

评论 0