function calling 流程和案例
目录
流程
以下是openai的代码,使用阿里云等其他模型需要调整
大模型选择
有些小模型不支持function call,如qwen2.5-7b-instruct 不支持function calling, qwen2.5-72b-instruct 支持
0 函数定义和编写工具说明(tools)
sunwukong_tool = StructuredTool.from_function(
func=get_weather,
name=get_weather.__name__ , # 保持名称一致性
description="查询天气,输入必须是英文名,中国的城市需要用对应城市的英文名称代替,例如如果需要查询北京市天气,则loc参数需要输入'Beijing';,示例输入:'Beijing'"
)
1. 第一次调用大模型
除了发送询问消息外,还要带上 自定义函数列表。 大模型判断当需要调用外部函数的时候,会根据函数的说明寻找合适的函数。
messages=[
{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
{"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
tools=tools,
tool_choice="auto", //让大模型决定是否需要调用外部自定义函数
)
first_response = response.choices[0].message
2. 解析调用返回值,判断response的 tool_calls 是否有值,如果有值说明需要调用外部函数
tool_calls = response.choices[0].message.tool_calls
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_tools[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(**function_args)
3. 追加 第一次模型返回结果消息
messages.append(first_response)
4. 追加 外部函数的调用结果
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
5. 再一次请求大模型
示例代码
以下使用阿里云大模型function calling 代码示例
import os
import numpy as np
import pandas as pd
import json
import io
from langchain_core.tools import StructuredTool
from openai import OpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.messages import AIMessage
from langchain_core.messages import SystemMessage, HumanMessage, ToolMessage
import os
def sunwukong_function(data):
"""
孙悟空算法函数,该函数定义了数据集计算过程
:param data: 必要参数,表示带入计算的数据表,用字符串进行表示
:return:sunwukong_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象
"""
data = io.StringIO(data)
df_new = pd.read_csv(data, sep='\s+', index_col=0)
res = df_new * 10
return json.dumps(res.to_string())
df = pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]})
df_str = df.to_string()
print(df_str)
result_json=sunwukong_function(df_str)
print(result_json)
# sunwukong={
# "type": "function",
# "function": {"name": "sunwukong_processor",
# "description": "用于执行孙悟空算法函数,定义了一种特殊的数据集计算过程",
# "parameters": {"type": "object",
# "properties": {"data": {"type": "string",
# "description": "执行孙悟空算法的数据集"},
# },
# "required": ["data"],
# },
# }
# }
# 注册函数
# sunwukong_tool = StructuredTool.from_function(func=sunwukong_function,name="sunwukong_processor", description=sunwukong['function']['description'])
sunwukong_tool = StructuredTool.from_function(
func=sunwukong_function,
name=sunwukong_function.__name__ , # 保持名称一致性
description="执行孙悟空算法处理表格数据,输入必须是以空格或制表符分隔的字符串,示例输入:'x1 x2\\n0 1 3\\n1 2 4'"
)
def create_llm() -> ChatOpenAI:
"""创建并返回配置好的大模型实例"""
return ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY") or "your_api_key_here",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen2.5-72b-instruct",
)
# message_history = [
# SystemMessage(content=f"数据集data:{dataset_str},数据集以字符串形式呈现"),
# HumanMessage(content="请用孙悟空算法处理这个数据集")
# ]
messages=[
{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
{"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]
def build_chain_withtool(prompt_template):
# 定义提示模板
# 创建LLM实例并绑定工具
llm = create_llm()
# 构建处理链:提示词 -> 绑定工具的模型
return prompt_template | llm.bind_tools(tools=[sunwukong_tool],tool_choice="auto")
def build_chain(prompt_template):
# 定义提示模板
# prompt_template = ChatPromptTemplate.from_messages([
# ("system", "数据集data:{dataset},数据集以字符串形式呈现"),
# ("human", "{user_query}"),
# ])
# 创建LLM实例并绑定工具
llm = create_llm()
# 构建处理链:提示词 -> 绑定工具的模型
return prompt_template | llm
def main():
prompt_template = ChatPromptTemplate.from_messages([
("system", "数据集data:{dataset},数据集以字符串形式呈现"),
("human", "{user_query}"),
])
# 示例数据集
sample_df = pd.DataFrame({'x1': [1, 2], 'x2': [3, 4]})
dataset_str = sample_df.to_string()
# 初始化消息历史
message_history = [
SystemMessage(content=f"数据集data:{dataset_str},数据集以字符串形式呈现"),
HumanMessage(content="请用孙悟空算法处理这个数据集")
]
# 构建对话链
chain = build_chain_withtool(prompt_template)
# 执行调用
first_response = chain.invoke({
"dataset": dataset_str,
"user_query": "请用孙悟空算法处理这个数据集"
})
print("完整响应对象:\n", first_response)
message_history.append(first_response) # 追加AIMessage
if isinstance(first_response, AIMessage):
raw_calls = first_response.additional_kwargs.get("tool_calls", [])
for call in raw_calls:
func_name = call["function"]["name"]
args = json.loads(call["function"]["arguments"])
if func_name == sunwukong_function.__name__ :
func_args = sunwukong_function(args["data"])
tool_result = json.loads(func_args)
print("最终结果:", tool_result) # 解析JSON输出
message_history.append(
ToolMessage(
content=tool_result,
name=func_name,
tool_call_id=call["id"]
)
)
# 第二次调用:传递完整历史
final_prompt = ChatPromptTemplate.from_messages(message_history)
final_chain = build_chain(final_prompt)
final_response = final_chain.invoke({}) # 无输入变量
print("最终回复:", final_response.content)
if __name__ == "__main__":
main()