我的AI学习 function Calling2

今天继续增加function Calling的例子.其实原理都是一样的,
例1: 通过 Function Calling 查询数据库

#  描述数据库表结构
database_schema_string = """
CREATE TABLE orders (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_id INT NOT NULL, -- 客户ID,不允许为空
    product_id STR NOT NULL, -- 产品ID,不允许为空
    price DECIMAL(10,2) NOT NULL, -- 价格,不允许为空
    status INT NOT NULL, -- 订单状态,整数类型,不允许为空。0代表待支付,1代表已支付,2代表已退款
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间,默认为当前时间
    pay_time TIMESTAMP -- 支付时间,可以为空
);
"""

这是一个数据库创建语句

def get_sql_completion(messages, model="gpt-4o-mini"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
        tools=[{  # 摘自 OpenAI 官方示例 https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb
            "type": "function",
            "function": {
                "name": "ask_database",
                "description": "Use this function to answer user questions about business. \
                            Output should be a fully formed SQL query.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": f"""
                            SQL query extracting info to answer the user's question.
                            SQL should be written using this database schema:
                            {database_schema_string}
                            The query should be returned in plain text, not in JSON.
                            The query should only contain grammars supported by SQLite.
                            """,
                        }
                    },
                    "required": ["query"],
                }
            }
        }],
    )
    return response.choices[0].message
    
def ask_database(query):
    cursor.execute(query)
    records = cursor.fetchall()
    return records

这是大模型的调用,并在tools参数中声明函数的名称,类型描述,入参,入参中参数的类型描述等.像这固定格式的描述写长了也就记住了.

import sqlite3

# 创建数据库连接
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

# 创建orders表
cursor.execute(database_schema_string)

# 插入5条明确的模拟记录
mock_data = [
    (1, 1001, 'TSHIRT_1', 50.00, 0, '2023-09-12 10:00:00', None),
    (2, 1001, 'TSHIRT_2', 75.50, 1, '2023-09-16 11:00:00', '2023-08-16 12:00:00'),
    (3, 1002, 'SHOES_X2', 25.25, 2, '2023-10-17 12:30:00', '2023-08-17 13:00:00'),
    (4, 1003, 'SHOES_X2', 25.25, 1, '2023-10-17 12:30:00', '2023-08-17 13:00:00'),
    (5, 1003, 'HAT_Z112', 60.75, 1, '2023-10-20 14:00:00', '2023-08-20 15:00:00'),
    (6, 1002, 'WATCH_X001', 90.00, 0, '2023-10-28 16:00:00', None)
]

for record in mock_data:
    cursor.execute('''
    INSERT INTO orders (id, customer_id, product_id, price, status, create_time, pay_time)
    VALUES (?, ?, ?, ?, ?, ?, ?)
    ''', record)

# 提交事务
conn.commit()

这里是创建数据库表,并且向数据库插入几条数据

prompt = "10月的销售额"
# prompt = "统计每月每件商品的销售额"
# prompt = "哪个用户消费最高?消费多少?"

messages = [
    {"role": "system", "content": "你是一个数据分析师,基于数据库的数据回答问题"},
    {"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
if response.content is None:
    response.content = ""
messages.append(response)
print("====Function Calling====")
print_json(response)

if response.tool_calls is not None:
    tool_call = response.tool_calls[0]
    if tool_call.function.name == "ask_database":
        arguments = tool_call.function.arguments
        args = json.loads(arguments)
        print("====SQL====")
        print(args["query"])
        result = ask_database(args["query"])
        print("====DB Records====")
        print(result)

        messages.append({
            "tool_call_id": tool_call.id,
            "role": "tool",
            "name": "ask_database",
            "content": str(result)
        })
        response = get_sql_completion(messages)
        messages.append(response)
        print("====最终回复====")
        print(response.content)

print("=====对话历史=====")
print_json(messages)

这个还是前面讲的固定格式,根据tool_call是否和定义的方法名一样,一样则执行定义的方法,然后再塞给大模型.大模型返回最终的结果. 大模型在这里会自动形成下列sql语句,
SELECT SUM(price) AS total_sales FROM orders WHERE strftime(‘%Y-%m’, create_time) = ‘2023-10’ AND status = 1;

例2:用 Function Calling 实现多表查询

#  描述数据库表结构
database_schema_string = """
CREATE TABLE customers (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_name VARCHAR(255) NOT NULL, -- 客户名,不允许为空
    email VARCHAR(255) UNIQUE, -- 邮箱,唯一
    register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 注册时间,默认为当前时间
);
CREATE TABLE products (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    product_name VARCHAR(255) NOT NULL, -- 产品名称,不允许为空
    price DECIMAL(10,2) NOT NULL -- 价格,不允许为空
);
CREATE TABLE orders (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_id INT NOT NULL, -- 客户ID,不允许为空
    product_id INT NOT NULL, -- 产品ID,不允许为空
    price DECIMAL(10,2) NOT NULL, -- 价格,不允许为空
    status INT NOT NULL, -- 订单状态,整数类型,不允许为空。0代表待支付,1代表已支付,2代表已退款
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间,默认为当前时间
    pay_time TIMESTAMP -- 支付时间,可以为空
);
"""

prompt = "统计每月每件商品的销售额"
prompt = "这星期消费最高的用户是谁?他买了哪些商品? 每件商品买了几件?花费多少?"
messages = [
    {"role": "system", "content": "你是一个数据分析师,基于数据库中的表回答用户问题"},
    {"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
sql = json.loads(response.tool_calls[0].function.arguments)["query"]
print(sql)

上述代码是测试输出的多表级联查询.

### 函数调用的概念及其在编程中的实现 #### 什么是函数调用? 函数调用是指程序运行过程中,通过指定名称激活某个预先定义好的功能模块的过程。这种机制允许开发者将复杂的任务分解成多个可重用的小单元,从而提高代码的清晰度和维护性[^1]。 #### Function Calling 的作用 Function Calling 不仅限于简单的内部方法调用,在现代开发环境中,它还被用来扩展模型的功能边界。例如,当涉及到与外部系统的交互时,可以通过嵌入 API 来增强模型的能力[^2]。具体来说,这通常涉及以下几个方面: - **数据获取**:从第三方服务中提取实时信息。 - **计算处理**:利用专门设计的服务完成复杂运算。 - **存储管理**:访问云端数据库或其他形式的数据仓库。 以下是基于 Python 实现的一个简单例子展示如何设置并执行带有 JSON Schema 描述参数结构以及目标 URL 地址指向所需 Web Service 的 function call: ```python import requests def get_current_weather(location): url = f"https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q={location}" response = requests.get(url) data = response.json() weather_description = data['current']['condition']['text'] temperature_celsius = data['current']['temp_c'] return {"description": weather_description, "temperature": temperature_celsius} # Example usage of the defined function with a hypothetical location. weather_info = get_current_weather("London") print(weather_info) ``` 此脚本片段展示了如何构建一个用于查询特定地点当前天气状况的应用场景下的 function calling 流程[^3]。 #### 如何解决问题? 如果遇到关于 function calling 方面的具体技术难题,则需考虑以下几点建议: 1. 明确需求——确认是要调用本地库还是远程 RESTful APIs; 2. 查阅官方文档——确保遵循所选框架/平台给出的最佳实践指南; 3. 错误调试——仔细分析返回错误消息以便快速定位问题根源所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值