资讯详情

web人工智能开发实战:基于vue+echart+fastapi+langchain+mcp构建AI智能体助手系统,TaoToken统一Key打通多模型调用

📅 2026/10/7 15:00:18 | 华诺云谱 👁 阅读
web人工智能开发实战:基于vue+echart+fastapi+langchain+mcp构建AI智能体助手系统,TaoToken统一Key打通多模型调用
1. 从零搭建 AI 智能体助手Vue ECharts FastAPI LangChain MCP 全链路拆解很多人第一次做 AI 智能体助手系统卡住的地方往往不是模型本身而是「前端对话、后端编排、数据看板、多模型 Key 管理」这四件事怎么串起来。我这次要分享的这套方案前端用 Vue3 ECharts 做对话窗口和数据看板后端用 Python FastAPI LangChain MCP 编排 Agent 与 SkillMySQL 存会话与任务模型调用统一走 TaoToken 的 Key一个 Key 打通多家模型。适合谁适合已经会一点 Vue 和 Python、想做一个能跑起来、能演示、能扩展的智能体助手系统的开发者。整套系统的核心检索词就是「Vue ECharts FastAPI LangChain MCP 智能体助手系统」。它能做什么用户在前端输入问题后端 Agent 判断意图、调用对应 Skill、必要时通过 MCP 访问外部工具把结果流式返回前端同时把每次调用的模型、耗时、Token 消耗写进 MySQL前端用 ECharts 画出调用趋势和模型分布。下面我按目录结构、依赖、配置、验证、排障的顺序把每一步都写成可复制、可跟做的形式。2. TaoToken 前置准备统一 Key 打通多模型调用在写代码之前先把模型调用这一层理顺。传统做法是每个模型厂商申请一个 Key代码里写一堆 if-else 判断走哪家 SDK维护成本很高。TaoToken 的思路是提供一个统一的 API 入口你用同一个 Key 就能调用不同模型后端只需要改 model 字段不用改调用逻辑。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。你需要先拿到 API Key。登录后进入控制台在 API Keys 页面创建一个新 Key复制保存。这个 Key 后面会写进后端的环境变量不要硬编码到代码里也不要提交到 Git。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到 Key 之后先别急着写业务代码用最简方式验证一下能不能调通。你可以用 curl 直接请求curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: gpt-4o-mini, messages: [{role: user, content: 用一句话解释什么是智能体}] }如果返回里有 choices 字段和正常的中文回复说明 Key 和网络都没问题。这一步很重要因为后面 FastAPI 里报的很多错根源其实在这一层。模型对话的在线体验入口是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 你可以先在网页上试几个模型确认哪些模型 ID 可用再写进后端配置。关于模型 ID建议后端维护一个白名单比如 gpt-4o-mini、claude-3-5-sonnet、deepseek-chat 等前端下拉框只展示白名单里的模型。这样既方便切换也避免用户传入不存在的模型导致 400 错误。如果你后面要做长期编码类 Agent可以关注 Coding Plan 相关入口 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合持续性的代码生成场景。3. 可复制配置目录结构、依赖清单与环境变量先给目录结构这是整套系统的骨架照着建就行ai-agent-assistant/ ├── backend/ │ ├── app/ │ │ ├── main.py │ │ ├── config.py │ │ ├── agent/ │ │ │ ├── orchestrator.py │ │ │ └── skills/ │ │ │ ├── weather_skill.py │ │ │ └── db_skill.py │ │ ├── mcp/ │ │ │ └── client.py │ │ ├── api/ │ │ │ ├── chat.py │ │ │ └── stats.py │ │ └── db/ │ │ ├── models.py │ │ └── session.py │ ├── requirements.txt │ └── .env ├── frontend/ │ ├── src/ │ │ ├── views/ │ │ │ ├── ChatView.vue │ │ │ └── Dashboard.vue │ │ ├── api/ │ │ │ └── request.js │ │ └── main.js │ ├── package.json │ └── vite.config.js └── docker-compose.yml后端依赖清单 requirements.txtfastapi0.115.0 uvicorn[standard]0.30.6 langchain0.3.7 langchain-openai0.2.5 langchain-community0.3.5 mcp1.1.0 sqlalchemy2.0.35 pymysql1.1.1 python-dotenv1.0.1 pydantic2.9.2 sse-starlette2.1.3前端依赖 package.json 关键部分{ dependencies: { vue: ^3.5.12, vue-router: ^4.4.5, axios: ^1.7.7, echarts: ^5.5.1, pinia: ^2.2.4 }, devDependencies: { vite: ^5.4.10, vitejs/plugin-vue: ^5.1.4 } }环境变量 .env 是重点TaoToken 的 Key 和 Base URL 都放这里TAOTOKEN_API_KEYsk-你的Key TAOTOKEN_BASE_URLhttps://taotoken.net/api DEFAULT_MODELgpt-4o-mini MYSQL_URLmysqlpymysql://root:password127.0.0.1:3306/ai_agentconfig.py 里读取这些变量import os from dotenv import load_dotenv load_dotenv() class Settings: api_key: str os.getenv(TAOTOKEN_API_KEY, ) base_url: str os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api) default_model: str os.getenv(DEFAULT_MODEL, gpt-4o-mini) mysql_url: str os.getenv(MYSQL_URL, ) settings Settings()LangChain 接入时用 ChatOpenAI 指向 TaoToken 的 Base URL 即可因为接口是兼容 OpenAI 格式的from langchain_openai import ChatOpenAI from app.config import settings def build_llm(model: str | None None): return ChatOpenAI( modelmodel or settings.default_model, api_keysettings.api_key, base_urlsettings.base_url, temperature0.3, streamingTrue, )这里有个坑要提醒base_url 结尾不要多加/v1因为 SDK 内部会自己拼/chat/completions。如果你写成https://taotoken.net/api/v1实际请求会变成/api/v1/v1/chat/completions直接 404。我试过这个错排查了半小时才发现是路径重复。MCP 客户端部分用一个简单的封装管理工具注册from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client class MCPManager: def __init__(self): self.sessions {} async def connect(self, name: str, command: str, args: list[str]): params StdioServerParameters(commandcommand, argsargs) read, write await stdio_client(params).__aenter__() session await ClientSession(read, write).__aenter__() await session.initialize() self.sessions[name] session return session async def list_tools(self, name: str): session self.sessions.get(name) if not session: return [] result await session.list_tools() return result.toolsAgent 编排层 orchestrator.py 负责把用户输入、Skill、MCP 工具串起来from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_core.prompts import ChatPromptTemplate from app.agent.skills.weather_skill import weather_tool from app.agent.skills.db_skill import query_task_tool from app.config import settings from app.agent.llm import build_llm PROMPT ChatPromptTemplate.from_messages([ (system, 你是一个智能体助手优先调用工具获取事实再回答用户。), (human, {input}), (placeholder, {agent_scratchpad}), ]) def build_agent(model: str | None None): llm build_llm(model) tools [weather_tool, query_task_tool] agent create_openai_tools_agent(llm, tools, PROMPT) return AgentExecutor(agentagent, toolstools, verboseTrue)FastAPI 的 chat 接口用 SSE 流式返回from fastapi import APIRouter from sse_starlette.sse import EventSourceResponse from app.agent.orchestrator import build_agent router APIRouter() router.post(/api/chat/stream) async def chat_stream(payload: dict): agent build_agent(payload.get(model)) async def event_gen(): async for event in agent.astream_events( {input: payload[message]}, versionv2 ): if event[event] on_chat_model_stream: chunk event[data][chunk].content if chunk: yield {event: message, data: chunk} yield {event: done, data: [DONE]} return EventSourceResponse(event_gen())前端 ChatView.vue 用 EventSource 接收流式内容Dashboard.vue 用 ECharts 画调用统计。ECharts 初始化时注意在 onMounted 里执行否则容器宽度为 0 会导致图表不显示import * as echarts from echarts import { onMounted, ref } from vue const chartRef ref(null) onMounted(() { const chart echarts.init(chartRef.value) chart.setOption({ tooltip: { trigger: axis }, xAxis: { type: category, data: [] }, yAxis: { type: value }, series: [{ type: line, data: [], smooth: true }] }) })4. 验证请求多模型调用与 ECharts 图表联动配置写完后先启动后端cd backend uvicorn app.main:app --reload --port 8000再启动前端cd frontend npm install npm run dev打开浏览器访问前端页面在对话框输入「帮我查一下北京天气并统计今天的任务数量」。正常情况下后端日志会显示 Agent 先调用 weather_tool再调用 query_task_tool最后把结果流式返回。前端对话区会逐字显示回复同时 Dashboard 页面的 ECharts 折线图会新增一个数据点表示这次调用的耗时。验证多模型切换在前端下拉框把模型从 gpt-4o-mini 换成 claude-3-5-sonnet再发一条消息。后端不需要重启因为 build_agent 每次请求都会根据传入的 model 重新构建 LLM 实例。你可以在 MySQL 的 call_log 表里看到两条记录model 字段不同但 api_key 是同一个。这就是统一 Key 的价值——切换模型只改一个字段。验证 MCP 工具如果你接了一个本地文件查询的 MCP Server可以在对话里说「列出当前目录下的文件」Agent 会通过 MCP 调用对应工具。MCP 的返回结果会作为 observation 进入 Agent 的推理链最终体现在回复里。验证 ECharts 联动Dashboard 页面每 5 秒轮询一次 /api/stats 接口返回最近 20 次调用的耗时和模型分布。折线图展示耗时趋势饼图展示各模型调用占比。如果图表不更新先检查接口是否返回了数据再检查 ECharts 的 setOption 是否被调用。5. 常见错误排查401、local proxy failed、reading choices、OAuth第一个高频错误是 401 Unauthorized。报错信息通常是{error: {message: Invalid API key}}。原因有三种Key 复制时带了空格、.env 文件没被 load_dotenv 读到、或者 Key 已经被删除。排查方法是在 Python 里打印settings.api_key[:8]确认前几位是否正确。如果 .env 放在 backend 根目录但启动目录不对load_dotenv 会找不到文件建议用绝对路径load_dotenv(dotenv_pathPath(__file__).parent.parent / .env)。第二个错误是local proxy failed或连接超时。这通常是 base_url 写错或者本机网络环境有额外限制。先确认TAOTOKEN_BASE_URLhttps://taotoken.net/api不要带多余路径。然后用 curl 单独测试如果 curl 能通但 Python 不通检查是不是 requests 走了系统代理。可以在代码里显式设置os.environ[NO_PROXY] taotoken.net。第三个错误是reading choices相关报错比如KeyError: choices或list index out of range。这通常发生在流式响应解析时某些模型返回的 chunk 结构不同。解决方法是加防御性判断data response.json() if choices not in data or not data[choices]: raise ValueError(fUnexpected response: {data})第四个错误是 OAuth 相关报错比如OAuth token expired或invalid_grant。如果你用的是需要 OAuth 的模型或工具检查 token 刷新逻辑。对于 TaoToken 的 API Key 方式一般不会遇到 OAuth 问题但如果你的 MCP Server 需要 OAuth 授权要确保授权回调地址配置正确。第五个错误是 MySQL 连接失败报Access denied for user或Cant connect to MySQL server。检查 MYSQL_URL 里的用户名、密码、端口是否正确MySQL 是否允许远程连接。本地开发建议用 docker-compose 起一个 MySQL避免环境差异。第六个错误是 ECharts 图表不显示。打开浏览器控制台如果报Cannot read properties of null (reading getWidth)说明图表容器还没渲染就初始化了。把 echarts.init 放到 nextTick 里或者用 ResizeObserver 监听容器尺寸变化。6. 继续扩展从演示系统到可落地 Agent这套系统跑通之后你可以按自己的需求继续加东西。比如给 Agent 加更多 Skill每个 Skill 就是一个 LangChain Tool注册到 tools 列表里即可。再比如把 MCP 的 stdio 模式换成 SSE 模式让远程工具也能接入。数据看板那边可以加一个「模型成本估算」的柱状图按 Token 消耗乘以单价算出每次调用的成本。如果你要做长期运行的编码类 Agent建议单独走 Coding Plan 的接入方式入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言的示例代码。Claude Code 相关的接入可以参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。最后说一个实用技巧把 Agent 的每次调用都记一条日志到 MySQL字段包括 request_id、model、prompt_tokens、completion_tokens、latency_ms、created_at。这样前端 ECharts 可以画出任意维度的统计也方便你排查线上问题。日志表建好之后整个系统就从「能跑」变成「能观测」了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑