MCP智能体构建示例:用TaoToken统一Key打通大模型与SQL可视化
发布时间:2026/9/29 10:22:21来源:尧图网络
1. 从一句自然语言到一张图表中间到底缺了什么MCP 智能体构建示例这件事很多人卡在第一步模型能聊天但碰不到你的数据库。你问“哪个区域的企业利润最高”它只能给你一段听起来很对、但跑不通的 SQL。原因不复杂——大模型本身没有连接你本地数据的能力它需要一个标准化的通道去调用外部工具这个通道就是 MCPModel Context Protocol。它由 Anthropic 主导提出本质上是把 function calling 抽象成一套开放协议让模型和外部数据源、工具之间用统一接口通信。你可以把它理解成“AI 世界的 USB-C”不管对面是数据库、文件系统还是画图服务插上就能用。这篇要解决的是一个最小闭环用 MCP 协议搭一个智能体服务端通过 TaoToken 统一 Key 接入大模型让它根据自然语言自动生成 SQL、执行查询、再把结果渲染成图表。适合谁适合已经会一点 Python、想让大模型真正操作自己数据的开发者也适合正在选型 MCP 接入方案、不想为每个模型单独维护一套 Key 的团队。我试过把模型调用、SQL 生成、可视化拆成三个 MCP 工具串起来跑通之后从提问到出图大概十几秒。下面把可复制的骨架、TaoToken 的接入参数、以及一次端到端验证动作完整给出来。2. 为什么用 TaoToken 统一 Key 接 MCP 服务端MCP 服务端里最绕的一环是模型调用。你写 SQL 生成要调一次模型写可视化代码又要调一次模型如果每个环节都单独配 Key、单独改 base_url代码会迅速变成一团乱麻。更麻烦的是换模型今天用这个明天想换另一个每个调用点都得动。TaoToken 在这里的价值是提供一个统一的 API 通道。你只需要在环境变量里维护一份 Key 和一个 base_urlMCP 服务端里所有模型调用都走它。这样换模型时只改一个 model 名字不用碰业务代码。对 MCP 这种“一个服务端里可能有多处模型调用”的场景统一 Key 能省掉大量重复配置。接入信息如下建议直接写进.env不要硬编码在代码里配置项值说明API Basehttps://taotoken.net/apiOpenAI 兼容格式langchain 可直接用API Key在控制台创建形如sk-开头注意保密模型名按需填写例如对话/代码类模型填控制台里可用的名字官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content注册与文档入口注意API Base 用https://taotoken.net/api不要在后面拼多余的路径。langchain 的ChatOpenAI会自动补/chat/completions。Key 的创建入口在控制台的 API Keys 页面文档在接入文档里两个地址都带上来源参数方便你回查API Keyshttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite如果你后面要做长期编码或 Agent 类任务可以了解下 Coding Plan它更适合高频调用场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite。3. 可复制的 MCP 服务端配置骨架整个服务端分三块模型调用模块、SQL 生成与执行模块、可视化模块。用FastMCP起服务用 SSE 传输这样客户端可以直接通过 URL 连接不用自己写 stdio 进程管理。先装依赖pip install mcp langchain langchain-openai sqlalchemy psycopg2-binary pandas matplotlib python-dotenv3.1 统一模型调用模块把模型初始化抽成一个函数所有工具共用。这样 TaoToken 的 Key 只读一次换模型也只改一处。import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.prompts import PromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain.schema.runnable import RunnablePassthrough load_dotenv() def build_model(): return ChatOpenAI( modelos.getenv(TAOTOKEN_MODEL, deepseek-chat), openai_api_keyos.getenv(TAOTOKEN_API_KEY), openai_api_basehttps://taotoken.net/api, max_tokens1024, temperature0, ) model build_model().env文件长这样TAOTOKEN_API_KEYsk-你的key TAOTOKEN_MODELdeepseek-chat DATABASE_URIpostgresql://postgres:123456localhost:5432/demo3.2 SQL 生成工具模型不知道你的表结构所以要先喂元数据。把表结构写成一个 JSON 文件运行时读进来拼进 prompt。这里用metadata.json描述两张表企业表company和利润表profit。import json def load_metadata(pathmetadata.json): with open(path, r, encodingutf-8) as f: return json.load(f) SQL_PROMPT PromptTemplate( template( 有如下表结构信息{metadata}。 请将自然语言查询 {question} 转换为 PostgreSQL SQL 表名和字段名都要加双引号仅返回 SQL 语句不要解释。 ), input_variables[metadata, question], ) sql_chain ( {metadata: RunnablePassthrough(), question: RunnablePassthrough()} | SQL_PROMPT | model | StrOutputParser() ) async def generate_sql_query(question: str) - str: metadata load_metadata() result sql_chain.invoke({metadata: metadata, question: question}) return result.replace(sql, ).replace(, ).strip()3.3 注册 MCP 工具用FastMCP起服务把三个能力注册成工具生成 SQL、执行 SQL、生成图表。SSE 模式监听 8001 端口。from mcp.server.fastmcp import FastMCP import pandas as pd from sqlalchemy import create_engine import psycopg2 mcp FastMCP(DataBase Server, port8001, request_timeout30000) mcp.tool() async def generate_sql(query: str) - str: 根据自然语言生成 SQL 查询语句 return await generate_sql_query(query) mcp.tool() async def execute_sql(sql: str) - str: 执行 SQL 并返回 JSON 结果 engine create_engine(os.getenv(DATABASE_URI)) try: conn psycopg2.connect( dbnamedemo, userpostgres, password123456, hostlocalhost, port5432, options-c client_encodingutf-8, ) df pd.read_sql(sql, conn) conn.close() return df.to_json(orientrecords, force_asciiFalse) except Exception as e: return f查询出错: {e} mcp.tool(namegenerate_chart, description根据数据生成图表) async def generate_chart(df_json: str) - str: 根据传入的数据生成 matplotlib 图表并保存为 chart.png chart_prompt PromptTemplate( template( 你是数据可视化专家。有如下数据 {df} 用 matplotlib 选择合适的图表配色美观 保存为 chart.png支持中文显示只给代码。 ), input_variables[df], ) chain ( {df: RunnablePassthrough()} | chart_prompt | model | StrOutputParser() ) code chain.invoke({df: df_json}) code code.replace(python, ).replace(, ).strip() exec(code) return chart.png if __name__ __main__: mcp.run(transportsse)启动后服务地址是http://127.0.0.1:8001/sse这个 URL 后面客户端要用。4. 端到端验证从提问到出图服务端跑起来后用支持 MCP 的客户端连上去测。这里用 Cherry Studio它内置了 MCP Client不用自己写连接代码。在 MCP 设置里新增一个 SSE 类型的服务器URL 填http://127.0.0.1:8001/sse保存后能看到三个工具被识别出来。然后直接在对话框里问“帮我查一下各个区域的企业利润总和并画个图。” 预期流程是这样的客户端把问题发给模型模型决定调用generate_sqlgenerate_sql走 TaoToken 通道生成 SQL比如SELECT district, SUM(profit) FROM company JOIN profit ON ... GROUP BY district模型拿到 SQL 后调用execute_sql返回 JSON 数据模型再调用generate_chart把数据交给可视化工具生成chart.png客户端返回结果你打开本地图片就能看到各区域利润对比图。验证成功的标志是chart.png出现在工作目录且图表里的区域名和数值跟数据库对得上。如果只想先验证模型通道是否通可以单独跑一段最小请求from langchain_openai import ChatOpenAI import os llm ChatOpenAI( modelos.getenv(TAOTOKEN_MODEL), openai_api_keyos.getenv(TAOTOKEN_API_KEY), openai_api_basehttps://taotoken.net/api, ) print(llm.invoke(只回复两个字通了).content)返回“通了”就说明 TaoToken 的 Key 和 base_url 配置正确可以继续排查 MCP 层的问题。想直接在网页里试模型对话可以用模型对话入口https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite。5. 本篇常见错排查报错一openai.AuthenticationError: Incorrect API key九成是 Key 没读到。检查.env是否被load_dotenv()加载变量名是否和代码里一致。另外确认 base_url 是https://taotoken.net/api不要写成带/v1或其他后缀的地址。报错二psycopg2.OperationalError: could not connect to server数据库没起或端口不对。先用psql或 DBeaver 手动连一次确认DATABASE_URI里的库名、用户、密码、端口都对。注意execute_sql里我用了options-c client_encodingutf-8中文表名或字段名乱码时这个参数很关键。报错三生成的 SQL 执行报column does not exist模型没按双引号规则来。PostgreSQL 对大小写敏感字段名不加双引号会被转成小写。在 prompt 里强调“表名和字段名都要加双引号”并且把metadata.json里的字段名写准确模型才有依据。报错四generate_chart执行后没有图片exec(code)里的代码可能用了plt.show()而不是savefig。在 prompt 里明确“保存为 chart.png不需要显示”。另外 matplotlib 默认不支持中文代码里要加plt.rcParams[font.sans-serif] [SimHei]否则中文会变方块。报错五查询结果太大导致 token 超限如果execute_sql返回几千行直接塞给模型会爆 token。在execute_sql里加个截断比如df.head(50)或者在 prompt 里让模型先做聚合再返回。可视化场景通常只需要聚合后的几十行数据。报错六SSE 连接不上确认服务端mcp.run(transportsse)已启动端口 8001 没被占用。客户端 URL 要带/sse后缀。如果本机有防火墙放行对应端口。6. 把这条链路固定下来跑通一次之后建议把三个工具的参数和返回格式固定成约定generate_sql只返回纯 SQL 字符串execute_sql只返回 JSONgenerate_chart只返回图片路径。这样客户端和模型之间的交互会稳定很多不会因为返回格式飘忽而反复重试。另外元数据文件建议跟着数据库 schema 一起维护表结构变了就更新metadata.json比让模型去猜字段靠谱得多。如果后面要接更多数据源比如 MySQL 或 SQLite只需要改execute_sql里的连接方式模型调用和 MCP 工具注册那两层不用动——这正是统一 Key 加 MCP 分层带来的好处。需要长期跑编码或 Agent 任务的话Coding Plan 的额度模型更适合高频调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite。接入过程中遇到 Key 或通道问题先查接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。
网站建设高端定制企业官网