微信扫码
与创始人交个朋友
我要投稿
# 导入必要的库
import openai
import os
from math import *
from icecream import ic
import json
from math import *
import requests
import logging
import sqlite3
# 设置日志记录配置
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 加载 .env 文件
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
# 从环境变量中获得你的 OpenAI Key
openai.api_key = os.getenv('OPENAI_API_KEY')
openai.api_base = os.getenv('OPENAI_API_URL')
model = os.getenv('MODEL')
amap_key = os.getenv('GAODE_MAP_API_KEY')
# 定义数据库表结构的字符串
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 -- 支付时间,可以为空
);
"""
def get_sql_completion(messages, model=model):
"""
使用 OpenAI 的 Chat API 来生成完成的 SQL 查询语句。
参数:
- messages: 一个包含用户消息和系统消息的列表,用于上下文对话。
- model: 使用的 OpenAI 模型的名称,默认为环境变量中定义的模型。
返回:
- 生成的 SQL 查询语句。
"""
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0,# 模型输出的随机性,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.",#使用此功能可以回答用户有关业务的问题\输出应该是完全格式的SQL查询。
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
#SQL查询提取信息以回答用户的问题。SQL应该使用以下数据库架构编写:\
#查询应以纯文本形式返回,而不是以JSON形式返回。查询应该只包含SQLite支持的语法。
"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
# 创建内存中的SQLite数据库连接
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
# 执行数据库表创建语句
for statement in database_schema_string.split(';'):
cursor.execute(statement)
# 插入模拟数据
mock_data = [
(1, 1001, 'TSHIRT_1', 50.00, 0, '2023-10-12 10:00:00', None),
(2, 1001, 'TSHIRT_2', 75.50, 1, '2023-10-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, 'HAT_Z112', 60.75, 1, '2023-10-20 14:00:00', '2023-08-20 15:00:00'),
(5, 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()
def ask_database(query):
"""
执行 SQL 查询并返回结果。
参数:
- query: 要执行的 SQL 查询语句。
返回:
- 查询结果。
"""
cursor.execute(query)
records = cursor.fetchall()
return records
def test_promopt():
"""
测试通过自然语言询问来生成并执行 SQL 查询的功能。
"""
prompt = "统计每月每件商品的销售额"
# prompt = "这星期消费最高的用户是谁?他买了哪些商品? 每件商品买了几件?花费多少?"
messages = [
{"role": "system", "content": "基于 order 表回答用户问题"},
{"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
print(response)
conn.close()
def test_promopt_result():
"""
测试自然语言询问的更复杂场景,包括对数据库操作的调用和日志记录。
"""
prompt = "统计每月每件商品的销售额"
# prompt = "这星期消费最高的用户是谁?他买了哪些商品? 每件商品买了几件?花费多少?"
messages = [
{"role": "system", "content": "基于 order 表回答用户问题"},
{"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
if response.content is None:
response.content = "null"
messages.append(response)
logging.info("====Function Calling====")
logging.info(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)
logging.info("====SQL====")
logging.info(args["query"])
result = ask_database(args["query"])
logging.info("====DB Records====")
logging.info(result)
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": "ask_database",
"content": str(result)
})
response = get_sql_completion(messages)
logging.info("====最终回复====")
logging.info(response.content)
conn.close()
if __name__ == '__main__':
test_promopt_result()
2024-05-31 23:12:38,331 - INFO - ====Function Calling====
2024-05-31 23:12:38,332 - INFO - {
"role": "assistant",
"content": "null",
"tool_calls": [
{
"id": "call_zhket5tQwLB9jGukvB2GpfMX",
"type": "function",
"function": {
"name": "ask_database",
"arguments": "{\"query\":\"SELECT strftime('%Y-%m', create_time) AS month, product_id, SUM(price) AS total_sales FROM orders WHERE status = 1 GROUP BY month, product_id;\"}"
}
}
]
}
2024-05-31 23:12:38,334 - INFO - ====SQL====
2024-05-31 23:12:38,334 - INFO - SELECT strftime('%Y-%m', create_time) AS month, product_id, SUM(price) AS total_sales FROM orders WHERE status = 1 GROUP BY month, product_id;
2024-05-31 23:12:38,335 - INFO - ====DB Records====
2024-05-31 23:12:38,335 - INFO - [('2023-10', 'HAT_Z112', 60.75), ('2023-10', 'TSHIRT_2', 75.5)]
2024-05-31 23:12:41,284 - INFO - ====最终回复====
2024-05-31 23:12:41,285 - INFO - 每月每件商品的销售额统计如下:
- 2023年10月:
- 商品ID:HAT_Z112,销售额:60.75
- 商品ID:TSHIRT_2,销售额:75.5
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-12-14
百度关于大模型在研发领域落地的深度思考
2024-12-14
NotebookLM这个更新为新的GPT范式补上了重要的一环
2024-12-14
国产全AI游戏来了?!大模型直出开放世界游戏,有声可交互
2024-12-14
OpenAI直播发布第7天:ChatGPT推出Projects,本周最强功能!
2024-12-14
OpenAI 新货详解:Project
2024-12-13
Meta MobileLLM:深度架构与优化技术打造的移动设备超强语言模型
2024-12-13
漫画 Transform: 手把手用数学公式推导
2024-12-13
谷歌从来就没有落后,这一波gemini 2.0可太牛了,贾维斯来了!
2024-05-28
2024-04-26
2024-08-13
2024-08-21
2024-07-09
2024-04-11
2024-07-18
2024-08-04
2024-07-01
2024-06-13
2024-12-06
2024-12-03
2024-12-01
2024-11-29
2024-11-26
2024-11-25
2024-11-21
2024-11-18