资讯动态

千问智能体定制开发实战:Qwen-Agent+MCP+RAG全流程解析,附源码与TaoToken统一Key配置

发布时间:2026/10/8 5:59:18 来源:尧图企业网站定制
1. 企业级 Agent 落地为什么总卡在“最后一公里”很多团队在 Demo 阶段跑通一个 Qwen-Agent 对话循环只花半天但一进生产环境就发现工具调用散落在各个脚本里、知识库更新要重启服务、模型 Key 在五个配置文件里各写一份。我见过最夸张的一个项目光是切换测试/生产环境的模型通道就维护了三套环境变量改一次要动六个文件。Qwen-Agent 本身提供了 Agent 编排能力MCP 解决了工具协议标准化的问题RAG 补上了私有知识的短板。这三者单独看都不复杂难的是把它们串成一条可维护的链路并且让模型接入层保持统一。这篇就按“从零搭建企业级 Agent”的路径把 Qwen-Agent MCP RAG 的完整流程拆开每一步都给可复制的配置和源码最后用 TaoToken 的统一 Key 通道完成端到端验证。适合谁看已经了解 Python 基础、想把手里的 Agent Demo 推进到可交付状态的开发者或者正在选型企业智能体框架、需要一份能直接跑通的参考实现的技术负责人。全文代码基于 Python 3.10依赖版本以实际安装为准建议在虚拟环境里操作。核心检索词先明确Qwen-Agent 是阿里云推出的智能体开发框架MCP 是模型与工具之间的标准化通信协议RAG 是检索增强生成。三者组合起来就是一套“模型能思考、工具有协议、知识可检索”的企业级 Agent 底座。2. TaoToken 统一 Key 通道的前置准备在写 Agent 代码之前先把模型接入层定下来。企业项目里最常见的坑是Qwen-Agent 里写一套 DashScope KeyRAG 的 Embedding 又写一套MCP 工具如果调外部模型再来一套。环境一多Key 管理就失控。我的做法是统一走一个兼容 OpenAI 协议的 API 通道TaoToken 提供的就是这个能力。它的 API 地址是https://taotoken.net/api兼容 OpenAI 的/v1/chat/completions和/v1/embeddings接口Qwen-Agent 和 LangChain 都能直接对接。这样模型层只维护一个 Base URL 和一个 Key切换模型只改 Model ID。2.1 获取 Key 与确认通道先到控制台创建 API Key。入口在https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole登录后在 API Keys 页面新建一个复制出来形如sk-xxxx的字符串。这个 Key 同时用于对话模型和 Embedding 模型不需要分开申请。创建完 Key 之后建议先到模型对话页面确认通道可用https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat。在里面选一个 qwen-plus 或 qwen-max发一句“你好”看是否正常返回。这一步能排除掉 Key 权限或余额问题避免后面写代码时把通道问题误判成代码 bug。2.2 环境变量规划企业项目里我习惯把模型配置集中到一个.env文件代码里只读环境变量。这样本地、测试、生产三套环境只换.env不动代码。# .env TAOTOKEN_API_KEYsk-你的Key TAOTOKEN_BASE_URLhttps://taotoken.net/api QWEN_CHAT_MODELqwen-plus QWEN_EMBEDDING_MODELtext-embedding-v3注意 Base URL 后面不要带/v1Qwen-Agent 和 OpenAI SDK 会自动拼接路径。如果你用的是 LangChain 的ChatOpenAI它默认会加/v1所以填https://taotoken.net/api即可。2.3 安装依赖项目初始化用虚拟环境隔离mkdir qwen-agent-enterprise cd qwen-agent-enterprise python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install qwen-agent mcp fastmcp langchain-community chromadb python-dotenv openai装完验证一下 Qwen-Agent 是否可用python -c from qwen_agent.agents import Assistant; print(Qwen-Agent OK)如果这里报ModuleNotFoundError大概率是虚拟环境没激活或者 pip 装到了全局。先which python确认路径在 venv 里再重试。2.4 为什么不用直连各家模型有同学会问Qwen-Agent 原生支持 DashScope为什么还要套一层统一通道原因有三个。第一企业项目往往不止用千问一个模型可能还要对比其他模型效果统一通道后切换只改 Model ID。第二Key 集中管理审计和轮换方便不用在多个框架配置里翻找。第三RAG 的 Embedding 和 Agent 的对话模型走同一个通道计费和限流口径一致排查问题简单。TaoToken 的接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc里面有各语言 SDK 的对接示例遇到协议细节可以对照查。3. Qwen-Agent MCP RAG 可复制配置这一节是全文的核心把 Agent 配置、MCP 服务注册、RAG 索引构建三块拆开写。每一块都给完整文件你可以直接复制到项目里改路径。3.1 项目结构先定目录后面所有文件按这个结构放qwen-agent-enterprise/ ├── .env ├── config.py ├── main.py ├── tools/ │ ├── __init__.py │ ├── mcp_tools.py │ └── rag_tool.py ├── mcp_server/ │ └── order_server.py ├── knowledge/ │ └── enterprise_knowledge.txt └── requirements.txt3.2 config.py统一读取模型配置# config.py import os from dotenv import load_dotenv load_dotenv() class ModelConfig: API_KEY os.getenv(TAOTOKEN_API_KEY) BASE_URL os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api) CHAT_MODEL os.getenv(QWEN_CHAT_MODEL, qwen-plus) EMBEDDING_MODEL os.getenv(QWEN_EMBEDDING_MODEL, text-embedding-v3) classmethod def validate(cls): if not cls.API_KEY: raise ValueError(TAOTOKEN_API_KEY 未设置请检查 .env 文件) return True这个类的作用是把模型配置收口。Qwen-Agent 的llm参数支持传字典格式是{model: ..., model_server: ..., api_key: ...}正好用这里的配置拼。3.3 MCP Server暴露企业订单工具MCP 的核心价值是让工具以标准协议暴露Agent 端不用关心工具内部实现。下面用 FastMCP 写一个订单查询服务# mcp_server/order_server.py from fastmcp import FastMCP mcp FastMCP(企业订单服务) # 模拟企业订单数据实际项目替换为数据库查询 ORDERS { 20240901: {status: 已发货, logistics: 运输中, eta: 2-3天}, 20240902: {status: 待发货, logistics: 仓库处理中, eta: 1天}, } mcp.tool() def get_order_status(order_id: str) - dict: 根据订单号查询订单状态和物流信息 order ORDERS.get(order_id) if not order: return {error: f未找到订单 {order_id}} return {order_id: order_id, **order} mcp.tool() def list_recent_orders(limit: int 5) - list: 列出最近的订单号 return list(ORDERS.keys())[:limit] if __name__ __main__: mcp.run(transportsse, port8000)启动服务python mcp_server/order_server.py看到Uvicorn running on http://0.0.0.0:8000就说明 MCP Server 起来了。注意这里用的是 SSE 传输Qwen-Agent 端要对应配 SSE 连接。3.4 MCP 工具注册到 Qwen-AgentQwen-Agent 通过MCPManager管理 MCP 连接。下面这个文件把 MCP Server 的工具拉进来包装成 Agent 可调用的工具列表# tools/mcp_tools.py from qwen_agent.tools.mcp import MCPManager def build_mcp_tools(): 连接 MCP Server 并返回工具列表 manager MCPManager( server_configs{ order_service: { url: http://localhost:8000/sse, transport: sse, } } ) return manager.get_tools()这里有个细节MCPManager的server_configs里 key 是服务别名url要带/sse路径。如果你的 MCP Server 用的是 stdio 传输配置格式不同需要改成command和args。企业内网服务建议用 SSE方便跨容器访问。3.5 RAG 索引构建RAG 分两步离线建索引在线检索。先写建索引脚本# tools/rag_tool.py import os from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.vectorstores import Chroma from config import ModelConfig PERSIST_DIR ./chroma_db def build_index(doc_path: str knowledge/enterprise_knowledge.txt): 构建向量索引 loader TextLoader(doc_path, encodingutf-8) documents loader.load() splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , , , ], ) chunks splitter.split_documents(documents) embeddings OpenAIEmbeddings( modelModelConfig.EMBEDDING_MODEL, api_keyModelConfig.API_KEY, base_urlModelConfig.BASE_URL, ) vector_store Chroma.from_documents( documentschunks, embeddingembeddings, persist_directoryPERSIST_DIR, ) vector_store.persist() print(f索引构建完成共 {len(chunks)} 个片段) return vector_store def get_retriever(): 获取检索器 embeddings OpenAIEmbeddings( modelModelConfig.EMBEDDING_MODEL, api_keyModelConfig.API_KEY, base_urlModelConfig.BASE_URL, ) vector_store Chroma( persist_directoryPERSIST_DIR, embedding_functionembeddings, ) return vector_store.as_retriever(search_kwargs{k: 3}) if __name__ __main__: build_index()注意OpenAIEmbeddings的base_url填https://taotoken.net/api它会自动请求/v1/embeddings。如果你的 LangChain 版本对 base_url 处理不同可以在末尾手动加/v1试一下以实际请求日志为准。准备一份知识文档knowledge/enterprise_knowledge.txt内容随意比如公司年假政策、产品说明等。然后跑python tools/rag_tool.py看到“索引构建完成”就说明向量库建好了chroma_db目录下会有持久化文件。3.6 把 RAG 包装成 Agent 工具Qwen-Agent 的工具需要继承BaseTool把检索器包进去# tools/rag_tool.py 追加 from qwen_agent.tools.base import BaseTool, register_tool register_tool(knowledge_retrieval) class KnowledgeRetrievalTool(BaseTool): name knowledge_retrieval description 从企业知识库中检索相关信息用于回答政策、产品等知识类问题 parameters [{ name: query, type: string, description: 检索关键词或问题, required: True, }] def __init__(self): super().__init__() self.retriever get_retriever() def call(self, params: str, **kwargs) - str: import json args json.loads(params) if isinstance(params, str) else params query args.get(query, ) docs self.retriever.invoke(query) return \n\n.join([d.page_content for d in docs])register_tool装饰器把工具注册到 Qwen-Agent 的工具表里后面 Agent 初始化时用名字引用即可。3.7 Agent 主配置最后把 MCP 工具和 RAG 工具组装到 Agent 里# main.py from qwen_agent.agents import Assistant from config import ModelConfig from tools.mcp_tools import build_mcp_tools from tools.rag_tool import KnowledgeRetrievalTool def create_agent(): ModelConfig.validate() llm_cfg { model: ModelConfig.CHAT_MODEL, model_server: ModelConfig.BASE_URL, api_key: ModelConfig.API_KEY, } mcp_tools build_mcp_tools() agent Assistant( llmllm_cfg, name企业智能客服, description企业级智能客服支持订单查询和知识检索, function_listmcp_tools [knowledge_retrieval], system_message( 你是企业智能客服助手。 用户询问订单、物流时调用订单工具查询 用户询问政策、产品知识时调用知识检索工具 回答要准确、简洁不确定的信息不要编造。 ), ) return agent def main(): agent create_agent() print(企业智能客服已启动输入 exit 退出) messages [] while True: user_input input(\n用户: ) if user_input.lower() exit: break messages.append({role: user, content: user_input}) response [] for chunk in agent.run(messages): response chunk messages.extend(response) print(f\n客服: {response[-1][content]}) if __name__ __main__: main()这里function_list里 MCP 工具是对象列表RAG 工具用注册名knowledge_retrieval字符串引用Qwen-Agent 会自动实例化。llm字典里的model_server就是 TaoToken 的 Base URLapi_key从环境变量读。4. 端到端验证与成功结果配置写完跑起来验证。分三步先单独验证模型通道再验证 MCP 工具最后验证 RAG 检索全部通过后跑完整 Agent。4.1 验证模型通道写一个最小脚本确认 TaoToken 通道能正常返回# verify_model.py from openai import OpenAI from config import ModelConfig client OpenAI( api_keyModelConfig.API_KEY, base_urlModelConfig.BASE_URL, ) resp client.chat.completions.create( modelModelConfig.CHAT_MODEL, messages[{role: user, content: 用一句话介绍你自己}], ) print(resp.choices[0].message.content)运行python verify_model.py如果打印出模型回复说明 Key 和 Base URL 都对。如果报 401检查 Key 是否复制完整如果报连接错误检查 Base URL 是否写成了https://taotoken.net/api。4.2 验证 MCP 工具先确保 MCP Server 在跑然后单独测工具调用# verify_mcp.py from tools.mcp_tools import build_mcp_tools tools build_mcp_tools() print(f加载到 {len(tools)} 个 MCP 工具) for t in tools: print(f- {t.name}: {t.description})正常输出应该能看到get_order_status和list_recent_orders两个工具。如果数量为 0检查 MCP Server 是否启动、端口是否被占用、URL 路径是否带/sse。4.3 验证 RAG 检索# verify_rag.py from tools.rag_tool import get_retriever retriever get_retriever() docs retriever.invoke(年假政策) for i, d in enumerate(docs): print(f--- 片段 {i1} ---) print(d.page_content[:200])如果检索结果和问题相关说明索引和 Embedding 都正常。如果返回空或无关内容先确认chroma_db目录存在再检查知识文档是否真的被切分入库。4.4 完整 Agent 运行效果三个单点验证通过后跑python main.py输入测试问题用户: 我的订单 20240901 发货了吗 客服: 您好我帮您查询了订单 20240901。根据系统记录该订单已发货 当前物流状态为「运输中」预计 2-3 天内送达。 用户: 公司的年假政策是怎样的 客服: 根据企业知识库公司年假政策为入职满一年享受 5 天年假 每满一年增加 1 天上限 15 天。具体请以 HR 最新通知为准。看到 Agent 能根据问题类型自动选择订单工具或知识检索工具就说明整条链路通了。这里的关键是system_message里的路由规则它决定了 Agent 什么时候调哪个工具。实际项目里可以把规则写得更细比如加上“订单号格式为 8 位数字”这类约束减少误调用。4.5 流式输出优化上面的main.py用的是非流式用户要等完整回复。生产环境建议改成流式for chunk in agent.run(messages): if chunk and chunk[-1].get(content): print(chunk[-1][content], end, flushTrue)Qwen-Agent 的run返回的是生成器每次 yield 一个消息列表。流式输出能显著降低首字延迟体验好很多。5. 本篇常见报错排查这一节按真实报错整理都是我在接入过程中实际遇到的。5.1 401 Unauthorized报错原文openai.AuthenticationError: Error code: 401 - {error: {message: Invalid API key}}原因通常是 Key 没读到或复制不全。排查顺序先echo $TAOTOKEN_API_KEY确认环境变量有值再检查.env文件是否被load_dotenv()正确加载注意.env要和运行脚本在同一目录或者用绝对路径最后确认 Key 没有多余空格或换行。如果用的是 TaoToken 的 Key到控制台重新复制一次避免复制到旧 Key。5.2 local proxy failed / connection refused报错原文openai.APIConnectionError: Connection error. httpx.ConnectError: [Errno 111] Connection refused这种多半是 Base URL 写错或网络不通。先确认TAOTOKEN_BASE_URL是https://taotoken.net/api不要带/v1也不要带尾部斜杠。然后curl https://taotoken.net/api/v1/models -H Authorization: Bearer $TAOTOKEN_API_KEY测一下通道。如果 curl 通但代码不通检查代码里是否被其他代理配置覆盖比如HTTP_PROXY环境变量。5.3 reading choices 报错报错原文KeyError: choices或者TypeError: NoneType object is not subscriptable这通常是响应结构不符合预期。原因可能是 Model ID 写错通道返回了错误信息而不是正常响应。先打印完整响应体resp client.chat.completions.create(...) print(resp.model_dump())看返回里有没有error字段。如果 Model ID 是qwen-plus但通道不支持换成qwen-max或到模型对话页面确认可用模型列表。另外注意 Embedding 模型和对话模型是分开的text-embedding-v3不能用于 chat 接口。5.4 MCP 工具加载为 0现象是build_mcp_tools()返回空列表。排查先确认 MCP Server 进程在跑curl http://localhost:8000/sse看是否有事件流返回再检查server_configs里的 URL 是否带/sse如果 MCP Server 在容器里localhost要换成容器服务名或宿主机 IP。FastMCP 默认 SSE 路径是/sse如果你改了mcp.run的路径参数这里要对应改。5.5 RAG 检索结果不相关检索出来的片段和问题无关通常是切分参数或 Embedding 模型问题。先把chunk_size从 500 调到 300 试试中文文档切太大会混入无关内容。再检查 Embedding 模型是否和建索引时一致建索引用text-embedding-v3检索也必须用同一个否则向量空间不对齐。如果还是不行加一个 rerank 环节用模型对 Top-K 结果重排。5.6 OAuth / 权限类报错如果报错里出现OAuth或permission denied先确认 Key 的权限范围。TaoToken 控制台里可以查看 Key 的可用模型列表如果 Key 只开了部分模型权限调用未授权的 Model ID 会报权限错误。到https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys检查 Key 配置必要时新建一个全权限 Key 测试。5.7 工具调用参数解析失败Qwen-Agent 调用工具时报json.decoder.JSONDecodeError通常是模型返回的参数不是合法 JSON。在BaseTool的call方法里加容错import json try: args json.loads(params) if isinstance(params, str) else params except json.JSONDecodeError: args {query: str(params)}同时在system_message里强调“调用工具时参数必须是合法 JSON”能减少这类问题。6. 长期编码与 Agent 迭代的接入建议跑通上面这套之后你手里就有了一个可运行的企业级 Agent 骨架。接下来要做的不是继续堆功能而是把迭代路径理顺。如果你打算长期做 Agent 开发建议把模型通道固定下来用 Coding Plan 管理调用额度入口在https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan。它适合需要频繁调试 Agent 逻辑、反复跑工具调用链的场景比按次调用更可控。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc里面除了 OpenAI 协议对接还有 Claude Code、Cline 等编码工具的配置示例。如果你用 Claude Code 做 Agent 代码开发可以参考文档里的 Anthropic 兼容配置把 Base URL 指向 TaoToken 通道这样编码助手和 Agent 运行时走同一个 Key排查问题不用来回切。API Keys 管理页面在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys建议给不同环境建不同 Key测试环境的 Key 设低额度避免调试时误刷生产额度。最后说一个实际经验Agent 项目最容易失控的地方不是模型能力而是工具边界。MCP 工具注册得越多模型选错工具的概率越高。我的做法是每个工具的描述里写清楚“什么时候用、什么时候不用”并且在system_message里给出明确的路由规则。比如订单工具的描述里加一句“仅当用户提供订单号时调用”能明显减少无效调用。这套骨架你跑通后先别急着加工具把现有工具的描述打磨到位效果比堆数量好得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑