当前位置: 首页 > news >正文

私有化部署本地大模型+function Calling+本地数据库

目录

什么是function Calling?

为什么有function calling?

实现过程

项目背景

运行本地模型

代码

执行结果

思考


什么是function Calling?

Function Calling‌ 是大型语言模型(LLM)连接外部工具和系统的核心技术,通过结构化参数生成实现模型与真实世界交互的能力。‌

为什么有function calling?

‌弥补大模型时效性与实时性不足‌:大模型训练数据存在时间滞后性(如训练时间是2023年,但是2023年后的数据没有),通过Function Calling可动态调用外部API(如天气、股价接口)获取最新信息‌

实现过程

1、使用ollama运行qwen2:7b,启动本地大模型。

2、使用qwen_agent执行function Calling

from qwen_agent.tools.base import BaseTool, register_tool
@register_tool('exc_sql')  # <-- 使用 register_tool 装饰器

3、连接本地数据库

database = args.get('database', 'bjgk')# 创建数据库连接engine = create_engine(f'mysql+pymysql://root:xxxxxx@localhost:3306/{database}?charset=utf8mb4',connect_args={'connect_timeout': 10}, pool_size=10, max_overflow=20)

项目背景

搭建高校录取分数查询助手,在前端UI上面输入问题,例:中央民族大学2025年北京录取分数,发送给大模型进行查询,然后返回前端数据,前端以表格的形式显示查询的结果。

运行本地模型

本次选择的模型为Qwen2:7B,其优势为以下:

  • 更好的中文理解能力
  • 更成熟的Function Calling支持
  • 对结构化数据查询任务处理更好
  • 更容易理解复杂的SQL生成需求

运行qwen2:7b:使用 ollama 拉取ollama pull qwen2:7b(大小4.4G),然后执行命令运行 ollama run qwen2:7b

代码

import os
import asyncio
from typing import Optional
import dashscope
from qwen_agent.agents import Assistant
from qwen_agent.gui import WebUI
import pandas as pd
from sqlalchemy import create_engine
from qwen_agent.tools.base import BaseTool, register_tool# 定义资源文件根目录
ROOT_RESOURCE = os.path.join(os.path.dirname(__file__), 'resource')# ====== 助手 system prompt 和函数描述 ======
system_prompt = """我是高校录取分数查询助手,以下是关于录取分数相关的字段,我可能会编写对应的SQL,对数据进行查询,每次查询显示所有,不要只显示10条
重要规则:
1. 当用户询问与高校录取分数相关的问题时,必须使用 exc_sql 工具执行SQL查询
2. 必须根据用户的具体需求编写准确的SQL语句
3. 查询结果必须包含用户要求的所有字段和排序规则-- 录取分数表,包括提前批、普通批、专科
CREATE TABLE `admission_score` (`id` int NOT NULL AUTO_INCREMENT COMMENT '录取分数表,包括提前批、普通批、专科',`batch` int DEFAULT NULL COMMENT '1-提前批A\\n2-提前批B\\n3-普通批',`school_code` varchar(45) DEFAULT NULL COMMENT '院校代码',`school_name` varchar(200) DEFAULT NULL COMMENT '学校名称',`professional_group_code` varchar(10) DEFAULT NULL COMMENT '专业组代码',`professional_group_name` varchar(45) DEFAULT NULL COMMENT '专业组名称',`score` int DEFAULT NULL,`chinese` int DEFAULT NULL COMMENT '语文',`math` int DEFAULT NULL COMMENT '数学',`english` int DEFAULT NULL COMMENT '英语',`other` int DEFAULT NULL COMMENT '选考科目',`notes` varchar(2000) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- 一分一段表
CREATE TABLE `score_distribution` (`id` int NOT NULL AUTO_INCREMENT COMMENT '一分一段表',`score` varchar(200) DEFAULT NULL COMMENT '分数',`score_number` int DEFAULT NULL COMMENT '本段人数',`amount_number` int DEFAULT NULL COMMENT '排名',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=348 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `professional_and_people_number` (`id` int NOT NULL AUTO_INCREMENT COMMENT '高校招生计划',`school_code` varchar(45) DEFAULT NULL COMMENT '学校代码',`school_name` varchar(200) DEFAULT NULL COMMENT '学校名称',`professional_group_code` varchar(45) DEFAULT NULL COMMENT '专业组代码',`professional_group_name` varchar(45) DEFAULT NULL COMMENT '专业组名称',`professional_code` varchar(45) DEFAULT NULL COMMENT '专业代码',`professional_name` varchar(2000) DEFAULT NULL COMMENT '专业名称',`pepole_number` int DEFAULT NULL COMMENT '人数',`notes` varchar(200) DEFAULT NULL COMMENT '备注',`adress` varchar(45) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;我将回答用户关于录取分数相关的问题
"""# ====== exc_sql 工具类实现 ======
@register_tool('exc_sql')
class ExcSQLTool(BaseTool):"""SQL查询工具,执行传入的SQL语句并返回结果。"""description = '对于生成的SQL,进行SQL查询'parameters = [{'name': 'sql_input','type': 'string','description': '生成的SQL语句','required': True}]def call(self, params: str, **kwargs) -> str:import jsonargs = json.loads(params)sql_input = args['sql_input']database = args.get('database', 'bjgk')# 创建数据库连接engine = create_engine(f'mysql+pymysql://root:xxxxxx@localhost:3306/{database}?charset=utf8mb4',connect_args={'connect_timeout': 10}, pool_size=10, max_overflow=20)try:df = pd.read_sql(sql_input, engine)return df.head(200).to_markdown(index=False)except Exception as e:return f"SQL执行出错: {str(e)}"# ====== 初始化助手服务 ======
def init_agent_service():"""初始化助手服务"""print("系统提示内容:")print(system_prompt[:200] + "..." if len(system_prompt) > 200 else system_prompt)llm_cfg = {'model': 'qwen2:7b','model_server': 'http://localhost:11434/v1','api_key': 'EMPTY','timeout': 30,'retry_count': 3,}try:bot = Assistant(llm=llm_cfg,name='高考志愿查询',description='查询各个高校的录取分数',system_message=system_prompt,function_list=['exc_sql'],  # 只传工具名字符串)print("助手初始化成功!")return botexcept Exception as e:print(f"助手初始化失败: {str(e)}")raisedef app_tui():"""终端交互模式提供命令行交互界面,支持:- 连续对话- 文件输入- 实时响应"""try:# 初始化助手bot = init_agent_service()# 对话历史messages = []while True:try:# 获取用户输入query = input('user question: ')# 获取可选的文件输入file = input('file url (press enter if no file): ').strip()# 输入验证if not query:print('user question cannot be empty!')continue# 构建消息if not file:messages.append({'role': 'user', 'content': query})else:messages.append({'role': 'user', 'content': [{'text': query}, {'file': file}]})print("正在处理您的请求...")# 运行助手并处理响应response = []for response in bot.run(messages):print('bot response:', response)messages.extend(response)except Exception as e:print(f"处理请求时出错: {str(e)}")print("请重试或输入新的问题")except Exception as e:print(f"启动终端模式失败: {str(e)}")def app_gui():"""图形界面模式,提供 Web 图形界面"""try:print("正在启动 Web 界面...")# 初始化助手bot = init_agent_service()# 配置聊天界面,列举3个典型门票查询问题chatbot_config = {'prompt.suggestions': ['中央民族大学所有专业组录取分数','中央民族大学所有专业组录取分数,包括专业组代码、专业组名称、专业代码、专业名称、录取分数、排名,按专业组代码、专业代码正序排序。表格显示时,专业代码与专业名称进行单元格合并,换行进行分隔',]}print("Web 界面准备就绪,正在启动服务...")# 启动 Web 界面WebUI(bot,chatbot_config=chatbot_config).run()except Exception as e:print(f"启动 Web 界面失败: {str(e)}")print("请检查网络连接和 API Key 配置")if __name__ == '__main__':# 运行模式选择app_gui()  # 图形界面模式(默认)

执行结果

思考

如果建表语句有更新,如何让大模型进行查询呢?

http://www.lryc.cn/news/624854.html

相关文章:

  • 【秋招笔试】2025.08.17字节跳动秋招机考真题
  • 技术赋能安全:智慧工地构建城市建设新防线
  • IB数学课程知识点有哪些?IB数学课程辅导机构怎么选?
  • [系统架构设计师]未来信息综合技术(十一)
  • 【秋招笔试】2025.08.17大疆秋招机考第一套
  • C++ STL容器相关操作的复杂度分析
  • FPGA驱动量子革命:微美全息(NASDAQ:WIMI)实现数字量子计算关键验证
  • 认证授权系统设计
  • redis-集成prometheus监控(k8s)
  • 【K8s】harbor安装与推送镜像
  • 中断线程化
  • 虚幻基础:动作时间窗
  • 徕芬的冰火两重天:增长困局,转型阵痛还是衰落前奏?
  • SQL注入防御
  • 【168页PPT】IBM五粮液集团数字化转型项目实施方案建议书(附下载方式)
  • 力扣2道dp
  • Dijkstra和多层图 0
  • [NSSCTF 2022 Spring Recruit]rrrsssaaa
  • 决策树学习报告
  • 决策树简单实战
  • 容器化 Android 开发效率:cpolar 内网穿透服务优化远程协作流程
  • 【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统
  • Swift + Xcode 开发环境搭建终极指南
  • 一个月内快速掌握蓝牙原理与应用的全面学习规划
  • 104、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(上)
  • Day7--滑动窗口与双指针--1695. 删除子数组的最大得分,2958. 最多 K 个重复元素的最长子数组,2024. 考试的最大困扰度
  • 负载均衡终极指南:从流量分发到云原生架构的核心解析
  • Apache IoTDB集群部署实战:1C2D架构的高性能时序数据库搭建与优化指南
  • 第4章-04-用WebDriver页面元素操作
  • onRequestHide at ORIGIN_CLIENT reason HIDE_SOFT_INPUT fromUser false