在人工智能领域,大型语言模型(LLM)的"幻觉"问题一直备受关注。当被问及股票价格、天气情况等具体信息时,模型有时会像一位自信满满的"学霸",给出看似合理实则错误的答案,这就是所谓的"幻觉"现象。究其原因,在于模型虽然精通语言艺术,却缺乏接入现实世界的"触角"。
为了破解这一难题,函数调用(Function Call)机制应运而生。它就像为模型配备了一部"智能手机",让模型在需要时能够"上网搜索"、"调用APP",从而获取准确可靠的实时信息。
函数调用实战:股票查询系统
让我们以一个股票查询系统为例,看看函数调用机制是如何大显身手的:
markdown
import json
from openai import OpenAI
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv('.env.local')
# 创建DeepSeek客户端
client = OpenAI(
api_key=os.getenv('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com/v1",
)
# 消息发送函数
def send_message(messages):
response = client.chat.completions.create(
model='deepseek-reasoner',
messages=messages,
tools=tools,
tool_choice='auto'
)
return response
# 定义函数调用工具
tools = [
{
"type": "function",
"function": {
"name": "get_closing_price",
"description": "获取指定股票的收盘价",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "股票名称",
},
},
"required": ["name"],
}
}
}
]
# 实际股票查询函数
def get_closing_price(name):
# 这里可以替换为真实的股票API调用
if name == '青岛啤酒':
return '67.92'
elif name == '贵州茅台':
return '1488.21'
else:
return '未找到该股票'
# 主程序
if __name__ == '__main__':
# 用户查询
messages = [{"role": "user", "content": "青岛啤酒的收盘价是多少?"}]
# 第一轮:模型判断是否需要调用函数
response = send_message(messages)
message = response.choices[0].message
messages.append({
"role": message.role,
"content": message.content,
"tool_calls": message.tool_calls
})
# 如果模型决定调用函数
if response.choices[0].message.tool_calls != None:
tool_call = response.choices[0].message.tool_calls[0]
# 执行股票查询函数
if tool_call.function.name == "get_closing_price":
arguments_dict = json.loads(tool_call.function.arguments)
price = get_closing_price(arguments_dict['name'])
# 将结果加入对话上下文
messages.append({
"role": "tool",
"content": price,
"tool_call_id": tool_call.id
})
# 第二轮:模型解释结果
response = send_message(messages)
print("最终回复:")
print(response.choices[0].message.content)
系统工作流程
- 用户提问:用户询问股票价格,例如:"青岛啤酒的收盘价是多少?"
- 模型判断:DeepSeek 模型识别出需要调用外部工具来获取准确信息。
- 函数执行 :调用
get_closing_price
函数,该函数可以接入真实的股票数据源(示例中为模拟数据)。 - 结果整合:模型将获取到的股票价格信息整合成自然语言回答,返回给用户。
优势分析
- 避免幻觉:模型不再"闭门造车",而是通过调用可靠的数据源获取准确信息,有效避免了"幻觉"问题。
- 动态更新:股票价格等实时信息可以随时更新,确保模型始终提供最新最准确的信息。
- 领域扩展:可以轻松添加更多工具函数,例如天气查询、餐厅推荐等,不断扩展系统的能力边界。
角色定义的重要性
除了函数调用,角色定义也是控制模型行为的重要手段。例如,在情感问答场景中,可以通过系统角色设定来定义模型的回答风格:
ini
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv('.env.local')
client = OpenAI(api_key=os.getenv('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com/v1")
completion = client.chat.completions.create(
model='deepseek-reasoner',
messages=[
{"role": "system", "content": "你是一个爱情聊天高手,请尽量帮我回答情侣之间相关的问题"},
{"role": "user", "content": "请问你的女友问你,她和你妈掉水里,先救谁,请给出具体答案"}
]
)
print('思考过程:')
print(completion.choices[0].message.reasoning_content)
print('最终答案:')
print(completion.choices[0].message.content)
结果图:
三层角色体系
- 系统角色:定义 AI 的人设和回答边界,例如"你是一个爱情聊天高手"。
- 用户角色:提供具体问题和上下文,例如情感类难题。
- AI 角色:模型返回符合人设的回答,例如输出符合"爱情高手"定位的巧妙回答。
函数调用的高级应用
多工具集成系统
可以将多个工具函数集成到一个系统中,例如:
ini
tools = [
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "获取股票实时价格",
# 参数定义...
}
},
{
"type": "function",
"function": {
"name": "search_restaurants",
"description": "搜索附近餐厅",
# 参数定义...
}
},
{
"type": "function",
"function": {
"name": "check_weather",
"description": "查询天气预报",
# 参数定义...
}
}
]
动态参数处理
可以在函数调用中添加智能默认值,提高函数的灵活性和易用性:
ini
python
# 在函数调用中添加智能默认值
def get_closing_price(name, date="today"):
if date == "today":
# 获取今日数据
elif date == "yesterday":
# 获取昨日数据
else:
# 指定日期数据
结果图:

结论:突破幻觉的边界
函数调用机制赋予了大语言模型"耳听六路,眼观八方"的能力,使其不再局限于"语言游戏",而是能够真正接入现实世界,成为连接人类需求与现实世界的"智能中枢"。
- 知识实时性:可以接入股票行情、地图服务等动态数据源,提供实时信息。
- 回答可靠性:避免模型编造看似合理实则错误的信息,确保回答准确可靠。
- 能力可扩展:通过添加新函数,可以不断扩展系统的能力边界,满足更多场景的需求。
- 角色可控性:通过系统角色设定,可以精确控制模型的回答风格,使其更符合特定场景的需求。
函数调用机制不仅解决了大模型的"幻觉"问题,更开启了大模型作为"智能中枢"的新时代。
如有错误欢迎指正,欢迎各位友友评论点赞!