大模型“喂养”秘籍:解锁数据库数据投喂技巧

有时候, 你会面对一个大型的数据库,它可能有数千张表,当你需要进行查询数据时,你需要阅读这些表的结构和数据,了解它们之间的关系。但这个过程是非常繁琐的,特别是你可能并不是一个专业的数据库专家,而是数据的使用者。

在这种情况下,DeepSeek等大模型可以帮助你来编写SQL查询语句,你通过自然语言描述你想要查询的数据,DeepSeek非常擅长编写相应的SQL语句。

但是,要让DeepSeek来帮助你,你需要提供给它足够的信息,包括表名,字段名,数据类型,表之间的关系等等,当你表比较少时,你可以手动一次将这些信息提供给DeepSeek,尽管会多占用一些 Token,但它至少是可行的。

不过,当你的表有数千张时,你就需要考虑如何将这些信息提供给DeepSeek了,因为这些信息的量是非常庞大的,大模型没法一次性处理这么多的信息。以某金融数据库为例,它大概有2300+张表,所有的元数据大概有40+MB,这远远超过了大模型的上下文长度限制。即便在将来, 大模型有可能会有更大的上下文长度限制,但在这个时候,每次请求耗费数百万Token, 成本从数元到数十元, 这个也是不可接受的。

所以, 我们需要一个方法来将这些信息提供给DeepSeek, 让它来帮助我们查询数据。我们可以使用MCP(Model Context Protocol)来实现这个目标。MCP是一种让大模型与外部数据源进行交互的协议,它可以让大模型在查询数据时,自动从外部数据源中获取所需的信息.

我们将提供一个MCP的实现,它提供了两个工具(Tool)

  • search_table: 根据用户的输入,让大模型来查找可能需要的表名
  • get_table_schema: 根据表名,获取表的结构信息,包括字段名,数据类型,表之间的关系等等

下面, 我们将介绍如何使用MCP来实现这个目标。

MCP的实现

前置

在使用编写这个MCP之前,我们需要先准备数据的元数据, 这包括表名、字段名、数据类型等信息,这些信息一般有两种途径获取

  • 直接读取数据库的元数据: 所有的数据库都提供了获取元数据的接口, 你可以直接读取数据库的元数据, 这也是最常用的方法, 但这种方法有一个问题,尽管理想情况下, 数据库的元数据是有良好的命名和注释, 但在实际应用中,这一点很难达到, 特别是当你面对的是一个国内的数据库时, 你会发现很多非常规的命名, 这些会困扰大模型, 同时, 注释也总是缺失的.
  • 通过文档或数据字典: 一般来说, 文档中会包含关于数据库结构的详细信息,包括表的描述、字段的含义等,这些信息可以帮助大模型更好地理解数据的上下文。但你需要从这些文档中提取出这些信息, 这也是一个非常繁琐的工作, 但相对来说, 这种方法是比较可靠的, 从实践来看, 这远比直接读取数据库的元数据要好, 你可能需要一个特定的工具来提取这些信息.

当你准备好了这些信息后, 你就可以开始编写MCP了.

MCP的实现

我们将使用Python来实现这个MCP, 但你可以使用任何你喜欢的编程语言来实现这个MCP.

作者:LiGood
链接:https://www.zhihu.com/question/11675078024/answer/1889287347008435862
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

import io
import json

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("DemoDB", port="30059")


def load_tables() -> dict[int, any]:
  with open("doc/demo.jsonl", "r", encoding="utf-8") as f:
    tables = {}
    for line in f:
      table = json.loads(line)
      tables[table["id"]] = table
    return tables


ALL_TABLES = load_tables()


@mcp.tool()
def search_table(keyword: list[str]) -> str:
  """
  Search table by keyword.
  """
  table = [
    "id  | name",
    "--- | ---",
  ]
  with open("doc/demo_table.md", "r", encoding="utf-8") as f:
    for line in f:
      for kw in keyword:
        if kw in line:
          table.append(line.strip())

  if len(table) == 2:
    return "No table found."

  return "\n".join(table)


def format_table(table: dict) -> str:
  """
  Format the table to markdown.
  """
  buf = io.StringIO()
  buf.write(f"# 表名: {table['name']} 中文名: {table['cn_name']}\n")
  buf.write("## 字段列表\n")

  buf.write("| 字段名 | 中文名 | 类型 | 说明 |\n")
  buf.write("| --- | --- | --- | --- |\n")
  for col in table["columns"]:
    buf.write(f"| {col['name']} | {col['cn_name']} | {col['type']} | {col['desc']} |\n")
  buf.write("\n")

  return buf.getvalue()


@mcp.tool()
def get_table_schema(ids: list[int]) -> str:
  """
  Get the schema of the tables by ID.
  """

  if len(ids) == 0:
    return ""
  buf = io.StringIO()
  for id in ids:
    table = ALL_TABLES.get(id, None)
    if table is not None:
      buf.write(format_table(table))
  return buf.getvalue()


if __name__ == "__main__":
  mcp.run("sse")

MCP的使用

我们需要一个支持MCP的客户端来使用这个MCP, 例如

其中, Claude Desktop 仅支持它自家的大模型, 而其他的两个开源的客户端都支持多种大模型, 你可以根据自己的需求来选择.

我们以DeepChat为例, 来介绍如何使用这个MCP.

首先, 启动MCP, 你可以在终端中运行以下命令

python3 db_mcp.py

然后, 在DeepChat中, 配置你的连接设置以便与MCP进行通信。

配置MCP
​​​

 在配置完成后, 你就可以使用MCP了。

 在这个示例中, DeepSeek 根据我们的输入, 自动的找到了 Fund_Performance_Compare 这个表, 然后获取了这个表的结构信息, 用需要的字段来编写了SQL查询语句.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值