技术定义与核心价值
Function Calling(函数调用)是MySQL数据库查询优化的核心方法论之一,指通过预定义的存储过程(Stored Procedure)或自定义函数(User-Defined Function)执行数据操作,实现业务逻辑与数据库操作的深度耦合。相较于传统SQL语句拼接,其核心价值体现在:
- 逻辑封装:将高频查询、复杂计算封装为可复用的函数模块,例如通过
CREATE PROCEDURE
定义多表联查逻辑,或使用CREATE FUNCTION
实现税率计算等业务规则; - 性能优化:预编译的存储过程减少SQL解析开销,结合参数化查询降低网络传输负载;
- 安全增强:通过权限隔离(如
GRANT EXECUTE ON PROCEDURE
)控制敏感数据访问,规避SQL注入风险。
应用场景与演进方向
在传统企业系统中,Function Calling常用于财务报表生成、数据清洗等批处理任务。随着AI技术发展,其与自然语言处理(NLP)的结合成为新趋势:通过语义解析引擎将用户提问(如“显示本月华东区销售额”)转换为函数调用指令(如CALL get_region_sales('East', CURRENT_MONTH)
),驱动智能数据分析Agent自动响应。
总结
Function Calling通过标准化、模块化的数据库操作接口,显著提升系统健壮性与开发效率。未来在低代码平台与AI代理的驱动下,其“声明式调用+自动化执行”的特性将进一步降低数据库交互门槛,成为企业数据架构升级的关键技术支点。
一、定义Mysql表结构以及查询
进行表结构的定义以及mysql数据库的连接以及查询
table_sql = """
CREATE TABLE `user_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色id',
`role` varchar(255) DEFAULT NULL COMMENT '角色简称',
`name` varchar(255) DEFAULT NULL COMMENT '姓名',
`wuqi` varchar(255) DEFAULT NULL COMMENT '武器',
`fashu` varchar(255) DEFAULT NULL COMMENT '法术',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
"""
# 数据库连接配置
config = {
'host':'localhost',
'user':'root',
'password':'123456',
'database':'sys'
}
def mysql_query(query:str):
# 获取数据库连接
try:
db = pymysql.connect(**config)
cursor = db.cursor()
cursor.execute(query)
result = cursor.fetchall()
return result
except Exception as e:
print(f"Error connecting to database: {e}")
return ""
def get_query_result(tool_name,tool_args):
if tool_name == "mysql_query":
sql = tool_args["query"]
print(sql)
result = mysql_query(sql)
print(f'执行结果是:{result}')
return str(result)
else:
return "未知的函数"
二、定义functions
functions = [{
"type": "function",
"function": {
"name": "mysql_query",
"description": "使用此功能回答用户有关业务的问题。输出应该是完整形式的SQL查询",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": f"""
SQL查询提取信息以回答用户的问题.
SQL应该使用此数据库模式编写:
{table_sql}
该查询应该以纯文本形式返回,而不是以JSON形式返回.
查询应仅包含Mysql支持的语法.
""",
}
},
"required": ["query"],
}
}
}]
三、定义OpenAI以及模型工具调用
1、进行模型定义
client = OpenAI(
api_key = os.getenv("DMX_OPENAI_API_KEY"),
base_url = os.getenv("DMX_BASE_URL")
)
def get_sql_completion(messages, model="gpt-3.5-turbo"):
try:
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0,
tools= functions,
tool_choice = "auto"
)
return response.choices[0].message
except ValueError as e:
print(f"模型处理数据异常:{str(e)}")
2、定义提示词以及message参数,并对第一次的执行结果进行封装
rompt = "孙悟空有什么武器和法术";
messages = [
{"role": "system", "content": "你是一个数据分析师,基于数据库的数据回答问题"},
{"role": "user", "content": prompt}
]
first_response = get_sql_completion(messages)
if first_response:
messages.append(first_response)
# 注意第一次的结果也要塞入
tool_calls = first_response.tool_calls
if tool_calls is not None:
for tool_call in tool_calls:
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
# 解析后的结果塞入
messages.append({
"role": "tool",
"content": get_query_result(tool_name,tool_args),
"tool_call_id": tool_call.id
})
# 第二次请求
second_response = get_sql_completion(messages)
print("*****************************************")
print(second_response.content)
四、运行结果
以上结果运行了三次,三次都是不一样的,所以还有待于进行微调,不过这里只是demo演示,了解其运行过程。
五、扩展与思考
1、上面的例子是一个表的,那么对于三个表、多个表呢
只要在table_sql中加入对应的表接口就可以了
table_sql = """
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 -- 支付时间,可以为空
);
"""
2、这个例子中数据库采用的是mysql,那么sqllite、ES、mongoDB集成也和这类似,只是修改对应的查询就可以了。不过现在已经有成熟的框架去调用了,可以不用fun_call去处理了,这里只是了解其原理。比如基于SQLDatabase+langchain+mysql搭建智能sql查询_langchain sqldatabasechain-CSDN博客这个例子中就是基于langchain框架进行数据处理的。
这个是function calling基本的用法,以及多工具调用实例,可以参考