大模型接口 Function Calling:提升提示词中计算问题的准确性
大模型接口 Function Calling:提升提示词中计算问题的准确性
在与大语言模型交互时,我们常常会遇到一个问题:直接让模型执行数学计算,或者包含数学运算的复杂问题。尤其是高精度或复杂运算时,结果往往不准确。例如,直接询问模型“计算 124342314 / 4324 并保留 6 位小数”,可能会得到一个近似值,甚至是错误的答案。这是因为大语言模型更擅长语言理解和生成,而非精确的数值计算。
不过,许多现代大模型接口(如 OpenAI 的 API)提供了 Function Calling 功能,允许我们在提示词中定义工具,通过生成代码并在本地执行来解决计算问题。本文将以 OpenAI 接口为例,展示如何利用 Function Calling 设计一个生成 Python 代码的工具,计算 124342314 / 4324 并保留 6 位小数,最终返回准确结果。国内的DeepSeek也提供了这一功能,不过目前的版本不稳地,官方接口文档说下个版本修复。
有人说为啥不使用深度推理,深度推理结果会准确。是的,不过在实际的业务场景中,使用接口调用推理模型,效率有点太低,远远不如使用这一工具,即使需要调用两次接口,使用成本还是比推理模型低的。
实现思路
- 定义工具:创建一个名为 generate_python_code 的工具,描述其功能为“生成并执行 Python 代码以完成计算任务”。
- 提示模型:在提示词中明确问题,并要求模型调用工具生成代码。
- 本地执行:接收模型生成的代码,在本地运行,得到计算结果。
- 返回结果:将结果传递回模型,生成最终回答。
代码实现
以下是一个完整的 Python 示例
1. 配置 OpenAI API
首先,确保你已安装 OpenAI 的 Python 库并获取了 API Key:
pip install openai
然后导入库并配置客户端:
import openai import json from openai import OpenAI
client = OpenAI(api_key="your_openai_api_key")
2. 定义工具
我们定义一个工具 generate_python_code,用于生成 Python 代码:
tools = [
{
"type": "function",
"function": {
"name": "generate_python_code",
"description": "根据任务需求生成可执行的 Python 代码来完成计算,并返回结果。",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "可执行的 Python 代码,返回计算结果"
}
},
"required": ["code"]
}
}
}
]
3. 发送提示词并调用工具
构造一个提示词,要求模型计算 124342314 / 4324 并保留 6 位小数:
messages = [
{
"role": "user",
"content": "请计算 124342314 / 4324,结果保留 6 位小数。"
}
]
response = client.chat.completions.create(
model="gpt-4o", # 确保使用支持 Function Calling 的模型
messages=messages,
tools=tools,
tool_choice="auto"
)
4. 处理模型返回的工具调用
模型会返回一个工具调用请求,我们提取生成的代码并在本地执行:
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
if tool_calls:
for tool_call in tool_calls:
if tool_call.function.name == "generate_python_code":
# 解析生成的代码
function_args = json.loads(tool_call.function.arguments)
code = function_args["code"]
print(f"模型生成的代码:\n{code}")
# 在本地执行代码
try:
local_vars = {}
exec(code, {}, local_vars)
result = local_vars.get("result", "未定义 result 变量")
print(f"本地计算结果: {result}")
except Exception as e:
result = f"代码执行错误: {str(e)}"
模型生成以下代码(这个是不固定的,模型会自己写代码,使用的变量名以及变量数量可以在tools的参数里定义):
result = round(124342314 / 4324, 6)
本地执行后,result 将是 28756.316836
5. 将结果返回给模型
将计算结果追加到对话中,让模型生成最终回答:
messages.append({
"role": "tool",
"content": str(result),
"tool_call_id": tool_call.id
})
final_response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages
)
final_answer = final_response.choices[0].message.content
print(f"最终回答: {final_answer}")
模型会返回:
计算结果为 28756.316836
完整代码(DeepSeek使用方法基本一致,不过目前在第二次提交给接口时返回的内容是空的,官方正在修复。。。)
以下是整合后的完整代码:
import openai
import json
from openai import OpenAI
client = OpenAI(api_key="your_openai_api_key")
tools = [
{
"type": "function",
"function": {
"name": "generate_python_code",
"description": "根据任务需求生成可执行的 Python 代码来完成计算,并返回结果。",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "可执行的 Python 代码,返回计算结果"
}
},
"required": ["code"]
}
}
}
]
def calculate_with_function_calling(prompt):
messages = [{"role": "user", "content": prompt}]
# 第一次调用,生成工具调用
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages,
tools=tools,
tool_choice="auto"
)
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
if tool_calls:
for tool_call in tool_calls:
if tool_call.function.name == "generate_python_code":
function_args = json.loads(tool_call.function.arguments)
code = function_args["code"]
print(f"模型生成的代码:\n{code}")
# 本地执行代码
try:
local_vars = {}
exec(code, {}, local_vars)
result = local_vars.get("result", "未定义 result 变量")
print(f"本地计算结果: {result}")
except Exception as e:
result = f"代码执行错误: {str(e)}"
# 将结果返回给模型
messages.append({
"role": "tool",
"content": str(result),
"tool_call_id": tool_call.id
})
# 第二次调用,生成最终回答
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)
return final_response.choices[0].message.content
# 测试
prompt = "请计算 124342314 / 4324,结果保留 6 位小数。"
result = calculate_with_function_calling(prompt)
print(f"最终回答: {result}")
优势与局限性
优势
-
高精度:通过本地执行代码,避免了模型的“猜测”行为。
-
灵活性:工具可以扩展到更复杂的计算或数据处理任务。
-
可控性:开发者可以在本地验证代码安全性。
局限性
-
依赖模型生成正确代码:如果模型生成的代码有误(例如忘记 round),结果仍可能错误。
-
本地执行风险:需要确保代码安全,避免恶意代码注入。
-
性能开销:两次 API 调用和本地执行增加了延迟。
总结(欢迎访问我的博客:https://he-via.xyz/)
通过 OpenAI 的 Function Calling 功能,我们可以轻松解决大模型在计算问题上的准确性缺陷。以 124342314 / 4324 为例,利用工具生成 Python 代码并本地执行,不仅保证了结果精确到 6 位小数,还展示了 Function Calling 的强大潜力。这种方法特别适合需要精确计算或逻辑推理的场景,是提示工程与代码执行的完美结合。
未来,你可以进一步优化工具定义,加入更多参数(如精度控制),或扩展到其他领域(如数据分析)。欢迎在评论区分享你的实践经验!
更多推荐
所有评论(0)