首页 / 正文

数据库接入 AI Agent 后 Token 狂飙?别把工作流塞进 Memory,改用 Skill + Script

Mooko
发布于 2026-05-30 · 5分钟阅读
61 浏览
0 点赞 暴击点赞!

数据库接入 AI Agent 后 Token 狂飙?别把工作流塞进 Memory,改用 Skill + Script

你可能也遇到过这个场景:

你在手机上给 AI Agent 发一句:

帮我查一下昨天各渠道的订单量,导出成 Excel 发我。

Agent 确实能干活。

它会理解需求、查数据库、整理结果、生成文件。

听起来很美。

可用几次之后你一看账单:Token 怎么烧得这么快?🔥

更气人的是,你明明已经把完整流程写进了 Agent 的 Memory:

  • 查数据要先看表结构
  • 只能查只读库
  • 查询后要格式化
  • 文件要导出成 Excel
  • 导出后上传到指定位置

结果它有时候照做,有时候乱跑。

问题不在你写得不够细。

问题在于:Memory 根本不是拿来跑流程的。


关键原因:Memory 是背景信息,不是执行引擎

很多人会误会 Memory。

以为把流程写进去,Agent 就会像程序一样稳定执行。

但真实情况是:

Memory 更像“它知道的一些背景”,不是“它必须执行的代码”。

每次你发消息,Agent 还是会重新做这些事:

  • 理解你的自然语言
  • 回忆 Memory 里的内容
  • 判断你想查什么
  • 推断应该用哪些表
  • 规划查询步骤
  • 决定是否导出文件
  • 决定如何格式化
  • 决定下一步工具调用

这些“思考过程”都要吃 Token。

而且,LLM 的规划不是确定性的。

你今天说“导出昨天数据”,它可能走 A 流程。

你明天说“把昨天数据发我一份”,它可能走 B 流程。

意思差不多,执行路径却变了。

这就是很多 Agent 接数据库后不稳定、成本高的根源。


正确拆法:LLM 只做翻译,脚本负责干活

咱们别让大模型包办一切。

它很聪明,但不适合做每一步都固定的脏活累活。

更好的架构是:

用户自然语言
   ↓
Agent Skill:识别任务 + 生成 SQL 参数
   ↓
脚本:执行 SQL / 格式化 / 导出 Excel / 上传文件
   ↓
返回结果给用户

把任务切成两类:

交给 LLM 的部分

LLM 擅长处理模糊表达。

比如你说:

查一下上周五抖音渠道的支付订单数。

它可以帮你转成结构化查询意图:

{
  "date": "2025-01-10",
  "channel": "douyin",
  "metric": "paid_orders"
}

或者生成 SQL:

SELECT
  COUNT(*) AS paid_orders
FROM orders
WHERE channel = 'douyin'
  AND pay_status = 'paid'
  AND order_date = '2025-01-10';

这才是它该干的活。

交给脚本的部分

这些动作没必要让 LLM 想:

  • 连接数据库
  • 执行 SQL
  • 限制查询超时时间
  • 检查返回行数
  • 格式化表格
  • 生成 Excel / CSV
  • 上传到对象存储
  • 返回下载链接

这些都应该写进 Python、Shell 或后端接口里。

机器能稳定跑,别让模型每次重新“琢磨”。

一句话:

能用脚本干的事,别让 LLM 干。LLM 负责翻译,脚本负责执行。


为什么 Skill 比 Memory 更适合放工作流?

Memory 放的是背景。

Skill 放的是能力。

这俩差别很大。

你可以把 Memory 想成便利贴:

这个用户常查订单数据。

而 Skill 更像一个封装好的按钮:

当用户要查订单数据时,调用这个能力,按固定输入输出执行。

数据库查询这类任务,天然适合做成 Skill。

因为它通常有明确流程:

  1. 识别用户想查什么
  2. 补全查询条件
  3. 生成 SQL 或结构化参数
  4. 调用脚本执行
  5. 返回结果或文件链接

注意,文章里这里的数字只是方便你看清结构,不是让模型靠 Memory 自由发挥。

真正上线时,流程要写进 Skill 和脚本里。


推荐架构:Agent Skill + SQL 模板 + 执行脚本

一个稳一点的数据库 Agent,可以这样设计:

用户:帮我导出昨天各渠道订单量

Agent Skill:
- 判断任务类型:订单统计
- 识别时间:昨天
- 识别维度:渠道
- 识别指标:订单量
- 选择 SQL 模板
- 填入参数

Python Script:
- 执行 SQL
- 生成 Excel
- 上传文件
- 返回链接

Agent:
- 把链接发给用户

核心变化是:

以前让 Agent 从零规划。

现在让 Agent 填空。

成本差别会很明显。


Skill 里应该放什么?

别把一大坨业务说明塞进去。

Skill 要短、准、可执行。

建议放这些内容:

1. 可查询范围

告诉 Agent 哪些数据能查,哪些不能查。

本 Skill 只用于查询订单统计数据。
可查询指标:订单量、支付订单量、GMV、退款金额。
可查询维度:日期、渠道、商品类目、城市。
禁止查询用户手机号、身份证、详细地址等敏感字段。

2. 表结构精简说明

别把整个数据库文档贴进去。

只放当前 Skill 需要的表。

orders 表:
- order_id:订单 ID
- order_date:下单日期,格式 YYYY-MM-DD
- channel:渠道,如 douyin、kuaishou、wechat
- pay_status:支付状态,paid 表示已支付
- amount:订单金额,单位元
- refund_amount:退款金额,单位元
- category:商品类目
- city:城市

3. 常用 SQL 模板

让 Agent 选模板填参数,而不是从零写 SQL。

-- 按渠道统计订单量
SELECT
  channel,
  COUNT(*) AS order_count
FROM orders
WHERE order_date BETWEEN '{{start_date}}' AND '{{end_date}}'
GROUP BY channel
ORDER BY order_count DESC;
-- 按日期统计 GMV
SELECT
  order_date,
  SUM(amount) AS gmv
FROM orders
WHERE order_date BETWEEN '{{start_date}}' AND '{{end_date}}'
  AND pay_status = 'paid'
GROUP BY order_date
ORDER BY order_date;

4. 输出格式约定

让 Agent 输出结构化参数,别输出一段散文。

推荐这样:

{
  "template_name": "orders_by_channel",
  "params": {
    "start_date": "2025-01-14",
    "end_date": "2025-01-14"
  },
  "export_format": "xlsx"
}

脚本拿到 JSON 后直接跑。

不用猜。

不用问。

不用读一大段自然语言。


Python 脚本怎么写?给你一个简化版

下面是一个简化示例。

真实项目里你要加权限、审计、脱敏、超时控制。

import pandas as pd
import pymysql
from datetime import datetime

SQL_TEMPLATES = {
    "orders_by_channel": """
        SELECT
          channel,
          COUNT(*) AS order_count
        FROM orders
        WHERE order_date BETWEEN %(start_date)s AND %(end_date)s
        GROUP BY channel
        ORDER BY order_count DESC;
    """,
    "gmv_by_date": """
        SELECT
          order_date,
          SUM(amount) AS gmv
        FROM orders
        WHERE order_date BETWEEN %(start_date)s AND %(end_date)s
          AND pay_status = 'paid'
        GROUP BY order_date
        ORDER BY order_date;
    """
}


def run_query(task: dict):
    template_name = task["template_name"]
    params = task["params"]
    export_format = task.get("export_format", "xlsx")

    if template_name not in SQL_TEMPLATES:
        raise ValueError("不支持的查询模板")

    sql = SQL_TEMPLATES[template_name]

    conn = pymysql.connect(
        host="readonly-db.example.com",
        user="readonly_user",
        password="your_password",
        database="biz_data",
        charset="utf8mb4"
    )

    try:
        df = pd.read_sql(sql, conn, params=params)
    finally:
        conn.close()

    filename = f"report_{template_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"

    if export_format == "csv":
        path = f"/tmp/{filename}.csv"
        df.to_csv(path, index=False)
    else:
        path = f"/tmp/{filename}.xlsx"
        df.to_excel(path, index=False)

    return {
        "rows": len(df),
        "file_path": path
    }

这个脚本做了几件很关键的事:

  • 只能执行预设模板
  • 参数通过字典传入
  • 数据库账号只读
  • 导出逻辑固定
  • 返回结构固定

Agent 不需要参与这些步骤。

它只需要交出一个合格的 JSON。


手机发消息时,流程应该长什么样?

你在手机上说:

帮我导出昨天各渠道订单量。

Agent 不应该开始长篇分析。

它应该生成类似这样的任务:

{
  "template_name": "orders_by_channel",
  "params": {
    "start_date": "2025-01-14",
    "end_date": "2025-01-14"
  },
  "export_format": "xlsx"
}

脚本执行后返回:

{
  "rows": 8,
  "file_url": "https://files.example.com/report_orders_by_channel_20250115.xlsx"
}

Agent 回复你:

已导出昨天各渠道订单量,共 8 行数据。文件在这里:xxx

这才是舒服的体验。

没有废话。

没有临场发挥。

Token 也不会莫名其妙爆掉。


Token 为什么能降这么多?

因为大头被砍掉了。

原来的 Agent 可能每次都要读:

  • 业务流程说明
  • 数据库表结构
  • 字段含义
  • 查询规则
  • 导出规则
  • 历史上下文
  • 工具调用结果
  • 中间推理内容

改成 Skill + Script 后,模型只需要处理:

  • 用户这句话想查什么
  • 选择哪个模板
  • 填哪些参数

工作量小太多。

从“让一个顾问全程操盘”,变成“让前台填一张工单”。

你说哪个省钱?


避坑清单:数据库 Agent 千万别这么做

坑 1:把完整 SOP 塞进 Memory

Memory 不是流程引擎。

写得再详细,也只是参考资料。

Agent 还是可能漏步骤。

坑 2:让 LLM 自由生成 SQL 并直接执行

这个很危险。

一旦生成错 SQL,轻则查错数,重则拖垮数据库。

更别提敏感字段泄露。

建议只允许:

  • 预设 SQL 模板
  • 白名单字段
  • 只读账号
  • 查询行数限制
  • 超时时间限制

坑 3:每次都把全量表结构塞给模型

几十张表、几百个字段,全塞进去就是烧钱。

按场景拆 Skill。

订单查询一个 Skill。

用户画像一个 Skill。

库存统计一个 Skill。

每个 Skill 只带自己需要的表结构。

坑 4:让 Agent 负责导出 Excel

导出文件是确定性任务。

Python 的 pandas 比 LLM 靠谱多了。

别让模型描述怎么导出。

让脚本直接导出。

坑 5:没有权限和审计

数据库接 Agent,一定要留痕。

至少记录:

  • 谁发起的查询
  • 原始问题是什么
  • 使用了哪个模板
  • 查询参数是什么
  • 返回多少行
  • 文件保存在哪里
  • 是否包含敏感字段

别等出事了再补。

那时候就不是优化 Token 了,是写事故复盘。


一个更稳的 Skill 提示词模板

你可以参考下面这个写法:

你是订单数据查询 Skill。

你的任务:
把用户的自然语言查询请求转换为结构化 JSON。
你不执行 SQL。
你不导出文件。
你不编造字段。
你只能从给定 SQL 模板中选择一个。

可用模板:

1. orders_by_channel
用途:按渠道统计订单量
参数:start_date, end_date

2. gmv_by_date
用途:按日期统计 GMV
参数:start_date, end_date

字段说明:
orders.order_date:订单日期,YYYY-MM-DD
orders.channel:渠道
orders.pay_status:支付状态,paid 表示已支付
orders.amount:订单金额

输出要求:
只输出 JSON,不要输出解释文字。

JSON 格式:
{
  "template_name": "",
  "params": {
    "start_date": "YYYY-MM-DD",
    "end_date": "YYYY-MM-DD"
  },
  "export_format": "xlsx"
}

如果用户的问题超出可用模板范围,输出:
{
  "error": "unsupported_request",
  "message": "当前 Skill 不支持该查询"
}

这个提示词的重点是边界清楚。

Agent 不再“自我发挥”。

它只做选择题和填空题。


什么时候还需要 Memory?

Memory 不是没用。

只是别拿它当工作流。

它适合存这些东西:

  • 用户常用的时间口径,比如“昨天”按北京时间算
  • 用户偏好的文件格式,比如默认 Excel
  • 用户常看的业务线,比如华东区
  • 用户常用渠道命名,比如“抖音”对应 douyin

但执行规则、SQL 模板、导出流程,建议放到 Skill 和脚本。

简单说:

Memory 记偏好,Skill 管能力,Script 干重活。


可以照抄的落地步骤

你可以按这个顺序改造现有 Agent:

  • 把当前 Memory 里的流程拆出来
  • 梳理用户最常问的 10 类数据库问题
  • 每类问题设计一个 SQL 模板
  • 每个模板只开放必要参数
  • 写一个脚本负责执行 SQL 和导出文件
  • 把表结构精简后放进对应 Skill
  • 让 Agent 输出结构化 JSON
  • 脚本校验 JSON 后再执行
  • 加上查询超时、行数限制、只读账号
  • 记录每次查询日志

改完之后,你会发现 Agent 变“笨”了。

这是好事。

它不再到处乱想。

它只在该聪明的地方聪明。


结论:别让 LLM 扮演数据库工程师

数据库查询 Agent 想要稳定、省钱、可控,关键不是把提示词写得更长。

而是重新分工。

LLM 负责理解人话。

Skill 负责限定能力。

Script 负责执行动作。

数据库负责返回结果。

这套拆开之后,Token 通常能明显下降,流程也会稳很多。

你要的是每天在手机上发一句话就拿到报表,不是看 Agent 在那儿写小作文。

让模型少想一点。

让脚本多干一点。

钱省了,结果也更靠谱。

OpenClaw
OpenClaw
木瓜AI支持养龙虾啦
木瓜AI龙虾专供API,限时领取免费tokens
可在 OpenClaw接入全球顶尖AI大模型
立即领取