Function Calling进行Mysql数据库查询

技术定义与核心价值

Function Calling(函数调用)是MySQL数据库查询优化的核心方法论之一,指通过预定义的存储过程(Stored Procedure)或自定义函数(User-Defined Function)执行数据操作,实现业务逻辑与数据库操作的深度耦合。相较于传统SQL语句拼接,其核心价值体现在:

  1. 逻辑封装‌:将高频查询、复杂计算封装为可复用的函数模块,例如通过CREATE PROCEDURE定义多表联查逻辑,或使用CREATE FUNCTION实现税率计算等业务规则;
  2. 性能优化‌:预编译的存储过程减少SQL解析开销,结合参数化查询降低网络传输负载;
  3. 安全增强‌:通过权限隔离(如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基本的用法,以及多工具调用实例,可以参考

大语言模型function calling的基本用法-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值