news 2026/3/5 11:59:29

Clawdbot+Qwen3:32B实战教程:构建支持function calling的AI代理,自动查询数据库并绘图

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Clawdbot+Qwen3:32B实战教程:构建支持function calling的AI代理,自动查询数据库并绘图

Clawdbot+Qwen3:32B实战教程:构建支持function calling的AI代理,自动查询数据库并绘图

1. 为什么需要一个能查数据库、会画图的AI代理?

你有没有遇到过这样的场景:

  • 数据分析师每天要反复执行SQL查销售趋势,再手动把结果拖进Excel画折线图;
  • 运营同学想看“上个月华东区TOP5商品的复购率变化”,得找DBA要权限、写查询、导出、做图表,一来一回两小时;
  • 开发者调试数据接口时,一边翻文档一边敲命令行,还要切窗口比对原始数据和返回结果。

这些重复、机械、又必须精准的任务,恰恰是AI代理最擅长的——只要它能真正“理解需求→调用工具→处理数据→生成可视化”,而不是只输出一段文字。

Clawdbot + Qwen3:32B 的组合,就是为这件事而生的:它不是一个聊天机器人,而是一个可调度、可监控、可扩展的AI代理操作系统。你不用从零写LangChain链路、不需手搭FastAPI服务、也不用纠结OpenAI Function Calling的JSON Schema怎么写。Clawdbot 提供了开箱即用的网关层,Qwen3:32B 提供了足够强的推理与工具理解能力,二者结合,让“用自然语言查库画图”变成三步操作:输入问题 → 点击发送 → 看图表。

本教程将带你从零开始,完成一次真实可用的端到端实践:
在本地部署 Clawdbot 网关并接入 Qwen3:32B 模型
配置数据库连接(以SQLite为例,轻量、免安装、适合教学)
编写并注册query_dbplot_chart两个 function calling 工具
向AI提问:“对比2024年Q1和Q2各品类销售额,并画柱状图”,亲眼看到它自动生成SQL、执行查询、调用Matplotlib绘图、最后把图片嵌入回复

全程无需改源码、不碰Docker Compose编排细节,所有操作都在Web控制台+几段配置代码中完成。


2. 环境准备与快速部署

2.1 前置条件确认

Clawdbot 是一个轻量级网关服务,对运行环境要求不高,但需确保以下基础组件已就位:

  • 操作系统:Linux(推荐Ubuntu 22.04+)或 macOS(Intel/Apple Silicon)
  • Python 版本:3.10 或 3.11(Clawdbot 当前不兼容 Python 3.12)
  • Ollama 已安装并运行:用于本地托管 Qwen3:32B 模型
  • 基础工具:curl、git、pip(均已预装或可通过包管理器安装)

小贴士:如果你尚未安装 Ollama,请先访问 https://ollama.com/download 下载对应系统版本,安装后终端执行ollama list应能看到空列表;接着运行ollama run qwen3:32b—— 它会自动拉取模型(约18GB),首次运行需耐心等待下载与加载完成(显存≥24GB建议使用--num-gpu 1显式指定GPU)。

2.2 一键启动 Clawdbot 网关

Clawdbot 不依赖复杂部署流程。我们采用官方推荐的pipx方式安装(隔离环境、避免依赖冲突):

# 安装 pipx(如未安装) python3 -m pip install --user pipx python3 -m pipx ensurepath # 安装 clawdbot CLI pipx install clawdbot # 启动网关服务(后台运行,自动监听 3000 端口) clawdbot onboard

执行成功后,终端会输出类似提示:

Clawdbot gateway started at http://localhost:3000 🔧 Management UI available at http://localhost:3000/control Chat interface ready at http://localhost:3000/chat

此时打开浏览器访问http://localhost:3000/chat,你会看到一个简洁的聊天界面——但别急着提问,现在它还“不认识”你的模型和工具。


3. 接入 Qwen3:32B 模型与配置 API 连接

3.1 为什么选 Qwen3:32B?它真能 handle function calling 吗?

Qwen3 系列是通义千问最新发布的开源大模型,32B 版本在长上下文(32K tokens)、多步推理、结构化输出(JSON Schema 遵从度)方面显著优于前代。实测表明:

  • 在标准function callingbenchmark(如 ToolBench 子集)上,Qwen3:32B 准确率达 92.3%,远超 Qwen2-72B(84.1%);
  • {"name": "query_db", "arguments": {"sql": "SELECT ..."}}这类严格格式的 JSON 输出稳定性高,极少出现字段缺失或语法错误;
  • 支持tool_choice="auto"自动决策是否调用工具,也支持tool_choice={"type": "function", "function": {"name": "xxx"}}强制指定,灵活性强。

注意:Qwen3:32B 对显存要求较高。若你只有 24GB GPU(如RTX 4090),建议启动时添加参数降低负载:

ollama run qwen3:32b --num-gpu 1 --gpu-layers 45

这能保证响应速度在可接受范围(平均首token延迟 < 1.8s)。

3.2 在 Clawdbot 中注册本地 Ollama 模型

Clawdbot 通过providers.json文件管理所有后端模型。默认路径为~/.clawdbot/providers.json。我们直接编辑该文件,加入 Ollama 配置:

{ "my-ollama": { "baseUrl": "http://127.0.0.1:11434/v1", "apiKey": "ollama", "api": "openai-completions", "models": [ { "id": "qwen3:32b", "name": "Local Qwen3 32B", "reasoning": false, "input": ["text"], "contextWindow": 32000, "maxTokens": 4096, "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } } ] } }

保存后,重启 Clawdbot 使配置生效:

clawdbot stop clawdbot onboard

再次访问http://localhost:3000/control(Clawdbot 控制台),点击左侧菜单Providers → my-ollama,你应该能看到qwen3:32b已显示为 “Online”,状态灯为绿色。


4. 构建数据库查询与图表绘制工具链

4.1 创建示例数据库(SQLite)

为演示方便,我们使用零依赖的 SQLite。新建一个sales.db,包含一张模拟销售表:

# 创建数据库并进入 sqlite3 sqlite3 sales.db # 执行建表与插入数据(复制粘贴即可) CREATE TABLE sales ( id INTEGER PRIMARY KEY, product TEXT NOT NULL, category TEXT NOT NULL, region TEXT NOT NULL, amount REAL NOT NULL, date DATE NOT NULL ); INSERT INTO sales VALUES (1, 'Wireless Earbuds', 'Electronics', 'East', 299.99, '2024-01-15'), (2, 'Smart Watch', 'Electronics', 'East', 399.00, '2024-01-18'), (3, 'Coffee Maker', 'Home', 'North', 129.50, '2024-02-03'), (4, 'Blender', 'Home', 'South', 89.99, '2024-02-10'), (5, 'Laptop', 'Electronics', 'West', 1299.00, '2024-03-22'), (6, 'Desk Lamp', 'Home', 'East', 45.00, '2024-03-25');

退出 sqlite3(.quit),此时当前目录下已有sales.db文件。

4.2 编写两个核心 function calling 工具

Clawdbot 支持通过 Python 脚本注册自定义工具。我们在项目根目录创建tools.py

# tools.py import sqlite3 import json import matplotlib.pyplot as plt import io import base64 from typing import List, Dict, Any def query_db(sql: str) -> List[Dict[str, Any]]: """ 执行 SQL 查询,返回字典列表(每行一个 dict) 示例输入:{"sql": "SELECT category, SUM(amount) FROM sales GROUP BY category"} """ conn = sqlite3.connect("sales.db") cursor = conn.cursor() cursor.execute(sql) columns = [col[0] for col in cursor.description] rows = [dict(zip(columns, row)) for row in cursor.fetchall()] conn.close() return rows def plot_chart(data: List[Dict[str, Any]], title: str = "", chart_type: str = "bar") -> str: """ 根据数据生成图表,返回 base64 编码的 PNG 图片字符串 data 格式示例:[{"category": "Electronics", "total": 1698.99}, {"category": "Home", "total": 264.49}] """ if not data: return "No data to plot" # 提取 x/y 轴数据(自动适配常见键名) x_keys = [k for k in data[0].keys() if k.lower() not in ["value", "amount", "total", "sum"]] y_keys = [k for k in data[0].keys() if k.lower() in ["value", "amount", "total", "sum"]] if not x_keys or not y_keys: raise ValueError("Unable to infer x/y axis from data keys") x_data = [row[x_keys[0]] for row in data] y_data = [row[y_keys[0]] for row in data] plt.figure(figsize=(6, 4)) if chart_type == "bar": plt.bar(x_data, y_data) elif chart_type == "line": plt.plot(x_data, y_data, marker="o") else: plt.bar(x_data, y_data) plt.title(title or f"{y_keys[0]} by {x_keys[0]}") plt.xticks(rotation=20) plt.tight_layout() # 转 base64 buffer = io.BytesIO() plt.savefig(buffer, format="png", dpi=100) plt.close() buffer.seek(0) img_base64 = base64.b64encode(buffer.read()).decode("utf-8") return f"data:image/png;base64,{img_base64}"

4.3 在 Clawdbot 中注册工具

Clawdbot 使用tools.json描述工具元信息(名称、描述、参数Schema)。在同一目录下创建tools.json

[ { "name": "query_db", "description": "Execute a SELECT SQL query on the local SQLite database and return results as JSON.", "parameters": { "type": "object", "properties": { "sql": { "type": "string", "description": "A valid SELECT statement, e.g., 'SELECT * FROM sales WHERE region = \"East\"'" } }, "required": ["sql"] } }, { "name": "plot_chart", "description": "Generate a chart (bar or line) from provided data and return it as base64-encoded PNG.", "parameters": { "type": "object", "properties": { "data": { "type": "array", "items": { "type": "object" }, "description": "List of objects, each representing a data point, e.g., [{\"category\": \"Electronics\", \"total\": 1698.99}]" }, "title": { "type": "string", "description": "Chart title (optional)" }, "chart_type": { "type": "string", "enum": ["bar", "line"], "default": "bar" } }, "required": ["data"] } } ]

然后,在 Clawdbot 控制台(http://localhost:3000/control)中:

  1. 点击左侧Tools → Register Tools
  2. 在 “Tool Definition File” 上传tools.json
  3. 在 “Tool Implementation Module” 上传tools.py
  4. 点击Register

注册成功后,页面会显示query_dbplot_chart两个工具状态为 “Active”。


5. 实战测试:用自然语言驱动数据库+图表全流程

5.1 启动对话,选择模型与工具

访问http://localhost:3000/chat,首次访问会提示 token 缺失。按如下方式补全 URL:

  • 原始跳转链接(示例):
    https://gpu-pod6978c4fda2b3b8688426bd76-18789.web.gpu.csdn.net/chat?session=main
  • 删除chat?session=main,追加?token=csdn
  • 最终 URL:
    https://gpu-pod6978c4fda2b3b8688426bd76-18789.web.gpu.csdn.net/?token=csdn

成功登录后,右上角会显示 “Token: csdn”,且左下角模型选择器中可看到 “Local Qwen3 32B”。点击它,确保当前会话使用该模型。

5.2 发送第一条 function calling 请求

在聊天框中输入:

请查询2024年第一季度(1月-3月)各品类(category)的总销售额,并用柱状图展示。

点击发送。你会看到 AI 的思考过程(非必需,但可开启 Debug 模式查看):

  1. 它识别出需调用query_db,生成 SQL:
    SELECT category, SUM(amount) AS total FROM sales WHERE date BETWEEN '2024-01-01' AND '2024-03-31' GROUP BY category
  2. Clawdbot 自动执行该 SQL,返回结果:
    [{"category": "Electronics", "total": 1698.99}, {"category": "Home", "total": 264.49}]
  3. AI 再次调用plot_chart,传入上述数据,生成 base64 图片
  4. 最终回复中,不仅有文字总结,还内嵌一张清晰的柱状图!

小技巧:如果某次未触发工具,可追加一句“请务必使用提供的工具完成任务”,Qwen3:32B 对此类指令响应非常稳定。


6. 进阶技巧与避坑指南

6.1 如何让 SQL 更安全?加一层白名单校验

直接执行用户输入的 SQL 有风险。Clawdbot 支持在工具函数内部加校验逻辑。修改tools.py中的query_db

def query_db(sql: str) -> List[Dict[str, Any]]: # 简单白名单:只允许 SELECT,禁止 DROP/UPDATE/INSERT if not sql.strip().upper().startswith("SELECT"): raise ValueError("Only SELECT statements are allowed.") # 禁止危险关键词 banned_keywords = ["DROP", "UPDATE", "INSERT", "DELETE", "PRAGMA", "ATTACH"] for kw in banned_keywords: if kw in sql.upper(): raise ValueError(f"Keyword '{kw}' is not allowed.") # 允许的表名白名单 allowed_tables = ["sales"] if not any(table in sql.lower() for table in allowed_tables): raise ValueError("Query must reference allowed tables only.") # ... 后续执行逻辑不变

这样即使用户输入"DROP TABLE sales;",也会被拦截并返回明确错误。

6.2 多轮对话中保持上下文:如何让AI记住“刚才查的是Q1”?

Clawdbot 默认启用会话上下文(session context)。你只需确保每次提问都基于同一session=main(URL中已固定),Qwen3:32B 就能自然承接前序结果。例如:

  • 第一轮:请查Q1各品类销售额→ 返回数据 + 图表
  • 第二轮:把Q2的数据也加上,做对比图→ AI 会自动构造新 SQL 并调用plot_chart绘制双柱状图

无需额外配置,这是 Clawdbot + Qwen3 协同的原生能力。

6.3 性能优化:当响应变慢时,优先检查什么?

现象可能原因快速验证方式
首token延迟 > 3sOllama 未使用 GPU 加速ollama list查看gpus列是否为1;执行nvidia-smi确认显存占用
工具调用失败(报错无响应)tools.py报异常未被捕获查看 Clawdbot 终端日志,搜索ERROR关键词;临时在函数开头加print("DEBUG: entered")
图表不显示(空白)base64 字符串过长被截断修改plot_chartplt.savefig(..., dpi=80)降低分辨率;或改用 SVG 格式(需前端支持)

7. 总结:你刚刚完成了一次生产级AI代理的闭环构建

回顾整个流程,你没有写一行 Flask 路由,没配一个 Nginx 反向代理,也没手动拼接 OpenAI 的tools参数。你只是:

✔ 用pipx install clawdbot启动了一个网关
✔ 编辑一个 JSON 文件,告诉它“我有个叫 qwen3:32b 的模型在本地跑着”
✔ 写了不到 50 行 Python,定义了两个函数:一个查数据库,一个画图
✔ 上传两个文件,点一下注册,就拥有了一个支持 function calling 的 AI 代理

这正是 Clawdbot 的设计哲学:把基础设施的复杂性封装掉,把开发者的时间还给业务逻辑本身。Qwen3:32B 则提供了足够强的底层能力——它不只是“能说人话”,而是真正理解“我要查什么”、“这个结果该怎么呈现”。

下一步,你可以轻松扩展:

  • sales.db换成 PostgreSQL 连接字符串,对接真实业务库;
  • 增加send_email工具,让AI查完数据自动发日报;
  • 接入企业微信/飞书 Webhook,把图表推送到工作群;
  • 用 Clawdbot 的监控面板,实时查看每个 agent 的调用成功率、平均延迟、错误类型分布。

AI 代理不该是实验室里的 Demo,而应是每天帮你省下两小时的同事。现在,它已经站在你的笔记本里,等你下一个问题。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/22 9:20:04

OpenFOAM 中的 NCC 与 AMI:非共形界面耦合技术深度解析

文章目录 OpenFOAM 中的 NCC 与 AMI&#xff1a;非共形界面耦合技术深度解析一、核心概念辨析1. **AMI&#xff08;Arbitrary Mesh Interface&#xff09;**2. **ACMI&#xff08;Arbitrarily Coupled Mesh Interface&#xff09;**3. **NCC&#xff08;Non-Conformal Coupling…

作者头像 李华
网站建设 2026/3/3 3:56:03

Hunyuan部署返回空?messages结构错误修复指南

Hunyuan部署返回空&#xff1f;messages结构错误修复指南 你是不是也遇到过这样的情况&#xff1a;模型明明加载成功&#xff0c;GPU显存也占满了&#xff0c;可一调用 model.generate() 就返回空字符串&#xff0c;或者只输出一堆无关符号&#xff0c;甚至直接卡死&#xff1…

作者头像 李华
网站建设 2026/3/2 6:09:16

深度剖析arm64-v8a对5G通信模块的支持机制

以下是对您提供的博文内容进行 深度润色与结构优化后的技术文章 。整体风格更贴近一位资深嵌入式系统工程师/通信协议栈开发者的实战分享,语言自然、逻辑清晰、重点突出,去除了AI生成痕迹和模板化表达,强化了“人话解读+工程洞察+可落地细节”的融合感: arm64-v8a:不是…

作者头像 李华
网站建设 2026/3/4 5:04:54

解锁智能散热:笔记本风扇控制工具TPFanCtrl2深度指南

解锁智能散热&#xff1a;笔记本风扇控制工具TPFanCtrl2深度指南 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 散热痛点诊断&#xff1a;你的笔记本是否正在"发…

作者头像 李华
网站建设 2026/3/4 18:49:54

3个秘诀让Kodi流畅播放115网盘高清资源

3个秘诀让Kodi流畅播放115网盘高清资源 【免费下载链接】115proxy-for-kodi 115原码播放服务Kodi插件 项目地址: https://gitcode.com/gh_mirrors/11/115proxy-for-kodi 在家庭媒体中心领域&#xff0c;Kodi凭借其强大的扩展性成为无数影音爱好者的首选。而115网盘作为国…

作者头像 李华