一、前言
在 AI 快速发展的当下,大语言模型(LLM)已广泛应用于智能客服、代码辅助等领域,但 “幻觉” 问题严重制约其价值发挥。当用户询问技术细节或数据分析需求时,LLM 常输出模糊、错误的回答。究其原因,基于 Transformer 架构的 LLM 本质是概率生成模型,擅长语言模式模仿,却缺乏真实问题解决能力。
而 FunctionCall 机制的出现带来转机。它就像给 LLM 的 “外挂工具箱”,让模型能根据需求调用数学计算、API 获取等工具函数,实现 “指令 - 调用 - 输出” 闭环,助力 LLM 从 “空谈” 走向 “实干”。后续我们将探究其技术逻辑与应用,一同见证这场 AI 理性革命。
二、AI对话设计(无 FunctionCall)
使用 OpenAI 客户端库调用 DeepSeek 模型回答足球相关问题的 AI 对话设计。主要内容包括:通过环境变量配置 DeepSeek API 密钥,设置基础 URL;创建客户端实例并调用deepseek-reasoner模型;设置系统提示指定 AI 为足球专家角色,用户询问 C 罗国籍,AI 回答其为葡萄牙运动员;最后打印模型的思考过程和最终答案,展示了完整的调用流程和输出结构。
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': 'c罗是哪个国家的足球运动员?'},
{'role': 'assistant', 'content': 'c罗是葡萄牙足球运动员。'}
]
)
print('思考过程:')
print(completion.choices[0].message.reasoning_content)
print('最终答案:')
print(completion.choices[0].message.content)
2.1 密钥的安全性
相关代码解释:
- import os 提供访问和操作环境变量的基础功能,可以让文件读取到其它文件的内容
- from dotenv import load_dotenv 将
.env文件中的变量注入到环境变量中,增强安全性和开发便利性。
将密钥存储在.env.local文件中,不直接暴露在代码里,可避免因代码上传至公开仓库(如 GitHub)而导致密钥泄露。在涉及 FunctionCall 调用外部 API 的 AI 项目中,若密钥不慎公开,可能导致 API 滥用或数据泄露,而.env.local可有效规避这类风险。
2.2 AI对话的建立
completion = client.chat.completions.create(
model='deepseek-reasoner',
messages=[
{'role': 'system', 'content': '你是一个足球领域的专家,请尽量帮我回答与足球相关的问题。'},
{'role': 'user', 'content': 'c罗是哪个国家的足球运动员?'},
{'role': 'assistant', 'content': 'c罗是葡萄牙足球运动员。'}
]
)
核心功能:创建 AI 对话
代码使用 OpenAI Python 库的client.chat.completions.create()方法向 DeepSeek 模型发送对话请求,并获取回复。这是实现聊天机器人、智能助手等功能的基础。
参数详解
(1)model='deepseek-reasoner'
- 指定使用的 AI 模型为
deepseek-reasoner
(2)messages参数
-
对话由多个消息组成,每个消息是一个字典,包含
role(角色)和content(内容):-
{'role': 'system', 'content': ...}- 人为添加,给AI一个足球领域的专家的身份,让它就足球专家的角度去思考
-
{'role': 'user', 'content': ...}- 用户消息,即用户提出的问题。示例中用户询问 “C 罗是哪个国家的足球运动员?”
-
{'role': 'assistant', 'content': ...}- 助手(AI)的回复。实际使用时,这部分内容由模型生成,示例中是预先写好的正确答案(实际代码运行时会被 API 返回的内容覆盖)。
-
注意: 如果需要多轮对话,可以通过在messages列表中添加更多消息,比如:
messages=[
{'role': 'system', 'content': '你是足球专家'},
{'role': 'user', 'content': 'C罗效力过哪些俱乐部?'},
{'role': 'assistant', 'content': '他效力过曼联、皇家马德里等俱乐部。'},
{'role': 'user', 'content': '他在皇马进了多少球?'}
# 追加新问题,形成对话 ]
三、 AI对话设计(有 ·FunctionCall)
from email import message
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",
)
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):
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
})
print("回复:")
print(response.choices[0].message.content)
3.1 AI对话的建立
给 AI 装上 “超能力外挂”!手把手教你打造 send_message 神方法
client.chat.completions.create()是调用 DeepSeek 模型 API 的核心方法,用于创建一个对话完成请求。model='deepseek-reasoner'指定了使用的模型为deepseek-reasoner,这是一个支持推理和工具调用的模型。messages=messages将函数传入的对话消息列表传递给模型,模型会基于这些消息进行回复。tools=tools引入了 FunctionCall 机制,tools是一个预定义的列表,其中包含了可供模型调用的工具函数的描述。模型会根据对话内容判断是否需要调用这些工具函数来获取信息。tool_choice='auto'表示让模型自动决定是否调用工具函数以及调用哪些函数。模型会根据对话内容和工具函数的描述,智能判断是否需要通过调用外部函数来更好地回答问题。
震惊!看似无所不能的 AI,竟偷偷向人类索要这份 “通关秘籍”!
# 打造一个函数调用的工具
tools = [
{
"type": "function",
"function": {
"name": "get_closing_price",
"description": "获取指定股票的收盘价",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "股票名称",
},
},
"required": ["name"],
}
}
}
]
tools ---"通关秘籍"
tools = [ ... ]这段代码创建了一个列表,用于定义可被大语言模型(LLM)调用的工具函数信息,是 FunctionCall 机制的关键组成部分。它就像是给模型的 “使用说明书”,让模型知道有哪些功能可供调用。下面为你详细拆解:
-
整体结构:
tools是一个列表,其中每个元素描述一个工具函数。当前列表只包含一个工具函数的描述,实际应用中可根据需求扩展多个。 -
工具类型定义:
"type": "function"明确告知模型,这个工具是一个函数类型。在 FunctionCall 机制中,除了函数类型,未来可能还会有其他类型(如 API 调用等),通过此字段进行区分。提醒:我们的演示数据都是固定的,后面主要是利用API调用去获取数据
-
函数详细信息:
-
函数名称:
"name": "get_closing_price"定义函数的名称,后续模型若判断需要调用该函数,会使用此名称指定操作。
-
-
函数描述:
"description": "获取指定股票的收盘价"用自然语言向模型解释函数的功能,帮助模型理解在什么场景下应该调用该函数。例如当用户询问 “贵州茅台今天收盘价是多少” 时,模型通过分析问题和该描述,判断是否调用
get_closing_price函数。 -
参数定义:
"parameters": { "type": "object", "properties": { "name": { "type": "string", "description": "股票名称", }, }, "required": ["name"] }type: "object":表示函数的参数整体是一个对象(JSON 格式的数据结构)。properties:定义对象中包含的属性。这里只有一个属性name,类型为字符串,描述为 “股票名称” ,即调用函数时需要传入股票名称。required:指定必须传入的参数,这里表明name参数是调用函数时必不可少的。
四、两者区别
4.1 核心功能差异
第一段代码(无 FunctionCall)
- 功能定位:简单的问答对话,AI 直接生成文本回答。
- 交互模式:用户提问 → AI 基于知识库直接回答。
- 应用场景:适用于一般性问答,如知识查询、闲聊等。
第二段代码(集成 FunctionCall)
- 功能定位:智能工具调用,AI 可根据需求调用外部函数获取数据。
- 交互模式:用户提问 → AI 判断是否需要调用工具 → 执行函数 → 返回结果。
- 应用场景:适用于需要动态数据或外部服务的场景,如股票查询、天气获取等。
4.2 代码结构差异
核心组件
- 第一段:直接通过
completion = client.chat.completions.create()发送消息。 - 第二段:封装为
send_message()函数,并引入tools和tool_choice参数。
FunctionCall 配置
-
第一段:无 FunctionCall 相关代码,AI 仅依赖自身知识生成回答。
-
第二段:
- 定义
tools列表,包含函数描述(如get_closing_price)。 - 设置
tool_choice='auto'让 AI 自动决定是否调用函数。
- 定义
函数实现
- 第一段:无自定义函数,所有逻辑由 AI 完成。
- 第二段:实现
get_closing_price()函数,用于查询股票收盘价,AI 可调用此函数获取数据。
4.3. 对话流程差异
第一段代码的执行流程
- 用户提问:“C 罗是哪个国家的足球运动员?”
- AI 直接回答:“C 罗是葡萄牙足球运动员。”
第二段代码的执行流程
- 用户提问:“青岛啤酒的收盘价是多少?”
- AI 分析问题,判断需要调用
get_closing_price函数。 - 执行函数,获取实际数据(如 “67.92”)。
- AI 结合函数结果生成最终回答。
4.4总结对比表
| 特性 | 第一段代码(无 FunctionCall) | 第二段代码(FunctionCall) |
|---|---|---|
| 核心功能 | 文本对话生成 | 智能工具调用 |
| 交互模式 | 单轮问答 | 多轮(问题→函数调用→结果整合) |
| 代码结构 | 简单直接,无函数定义 | 复杂,需定义工具描述和函数实现 |
| 数据来源 | AI 知识库 | 外部函数 / API |
| 应用场景 | 一般性问答、闲聊 | 需要实时数据或特定工具的场景(如查询、计算) |
| 扩展性 | 弱(依赖模型更新) | 强(可自定义工具) |
五、总结
FunctionCall 机制通过为 AI 配备标准化工具函数,构建起 "动态工具调用 - 数据验证 - 结果整合" 的闭环体系:不仅能实时获取股票行情、天气数据等动态信息,从源头规避 AI 因知识滞后产生的 "幻觉",更可通过多轮函数递归调用实现复杂逻辑处理。例如在订餐场景中,AI 可依次调用get_restaurant_list、check_availability、place_order等工具,自动补全用户未明确的就餐时间、人数等信息,直至完成订单提交,真正实现从 "被动回答" 到 "主动执行" 的能力跃迁。这种工具赋能模式,既保持了 AI 自然语言交互的灵活性,又通过工程化手段确保任务执行的准确性,为构建可落地的智能应用提供了关键技术支撑。