☰
LangChain实战进阶:检索生成(RAG)+Agent+MCP工具全解析|TaoToken统一Key接入指南
2026/10/2 6:40:26 网站建设 项目流程

1. 从一次 RAG 问答翻车说起:检索生成链路到底卡在哪

如果你正在用 LangChain 搭 RAG 问答,大概率遇到过这种场景:向量库检索出来的片段明明是对的,但大模型回答时开始"自由发挥",甚至编造出上下文里根本没有的条款。我试过把 temperature 调到 0.1、把提示词写死"只根据上下文回答",效果依然不稳定。排查一圈才发现,问题往往不在检索,也不在提示词,而在模型调用这一层——Base URL 指向的通道不稳定、Key 额度被限流、不同模型适配器各写一套环境变量,导致你以为在调 GPT-4o,实际请求早就超时降级了。

检索增强生成(RAG)解决的是大模型知识过时和幻觉问题,Agent 智能体解决的是"只会说不会做"的问题,MCP 工具协议解决的是工具跨平台复用的问题。这三件事单独看都不难,难的是把它们串成一条能稳定跑起来的工程链路。而这条链路的底座,是模型调用通道。本文聚焦 LangChain RAG + Agent + MCP 工具链的工程化落地,用 TaoToken 统一 Key 和 API 通道打通模型调用环节,交付可复制的环境变量与 Base URL 配置片段、MCP 工具注册示例,以及一次端到端 RAG 问答的验证动作与预期输出。

适合谁看:已经跑通过 LangChain 基础 Demo、想把手上的 RAG 原型往生产环境推一步的开发者;正在纠结 Agent 工具怎么封装、MCP 怎么接进 LangChain 的同学;以及被多套 API Key 管理折磨过、想统一模型入口的人。全文代码可直接运行,配置片段可直接复制,验证步骤有明确的预期输出。

先说清楚本文的技术栈边界:向量检索用 Milvus 的 HNSW 近似搜索,嵌入模型用 bge-base-zh-v1.5,生成层用 LangChain 的 init_chat_model 统一接口,Agent 用 create_agent 构建,工具层同时演示本地 @tool 封装和 MCP 协议工具集成,记忆用 LangGraph 的 Checkpointer。模型调用全部走 TaoToken 的 OpenAI 兼容通道,这样无论底层换哪个模型,代码里的 base_url 和 api_key 都不用动。

2. TaoToken 前置准备:统一 Key 与 Base URL 配置

在写任何 LangChain 代码之前,先把模型调用通道固定下来。这一步做扎实,后面 RAG、Agent、MCP 三条链路才能共用同一套凭证,不用每换一个模型就改一遍代码。

TaoToken 提供的是 OpenAI 兼容的 API 通道,官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 根地址是 https://taotoken.net/api 。注意这个 /api 后缀,很多同学第一次配的时候只填了域名,结果 LangChain 报 404,后面排障章节会专门讲这个坑。

第一步,去控制台创建 API Key。打开 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,在 API Keys 页面新建一个 Key,复制出来先存到安全的地方。这个 Key 就是后面所有代码里 OPENAI_API_KEY 的值。如果你还没决定用哪个模型,可以先在模型对话页面 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 试几条 prompt,确认通道通畅再进代码环节。

第二步,把凭证写进环境变量。LangChain 的 init_chat_model 和 OpenAI SDK 都认 OPENAI_API_KEY 和 OPENAI_BASE_URL 这两个标准变量,所以最省事的做法是在项目根目录建一个 .env 文件:

# .env OPENAI_API_KEY=sk-你的TaoToken密钥 OPENAI_BASE_URL=https://taotoken.net/api

这里有个细节:OPENAI_BASE_URL 结尾不要带斜杠,也不要带 /v1。LangChain 的 OpenAI 适配器会自动拼接 /chat/completions,如果你写成 https://taotoken.net/api/v1,最终请求路径会变成 /api/v1/chat/completions,虽然部分兼容层能处理,但为了统一,建议就写 https://taotoken.net/api 。

第三步,安装依赖。RAG 链路需要向量库和嵌入模型,Agent 链路需要 LangChain 的 agent 模块,MCP 链路需要适配器:

pip install python-dotenv langchain langchain-openai langchain-huggingface pymilvus langchain-tavily langchain-mcp-adapters mcp

如果你打算用 Coding Plan 做长期编码和 Agent 开发,可以看 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,它更适合需要持续调用、多项目并行的场景。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到参数细节可以对照查。

第四步,验证通道。写一个最小脚本,确认 Key 和 Base URL 能通:

from dotenv import load_dotenv import os from langchain.chat_models import init_chat_model load_dotenv() llm = init_chat_model( model="gpt-4o-mini", model_provider="openai", base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY"), temperature=0.1, ) res = llm.invoke("用一句话说明什么是RAG") print(res.content)

预期输出是一句关于检索增强生成的解释。如果这一步报 401,说明 Key 没读到或者复制时带了空格;如果报连接超时,检查 Base URL 是否写成了 https://taotoken.net/api 。这一步通了,后面的 RAG 和 Agent 才有意义。

3. 可复制配置:RAG 检索生成 + Agent + MCP 工具链

这一节是全文的核心,把三条链路的配置片段一次性给全。所有片段都基于上一节的环境变量,路径和原文保持一致,你可以直接复制到项目里改。

3.1 RAG 检索生成配置

先建向量集合。Milvus 本地部署默认端口 19530,用 MilvusClient 连接:

from pymilvus import MilvusClient from langchain_huggingface.embeddings import HuggingFaceEmbeddings client = MilvusClient(uri="http://127.0.0.1:19530", db_name="default") embed_model = HuggingFaceEmbeddings( model_name=r'.\assets\models\bge-base-zh-v1.5' ) query = "不动产被占有了怎么办?" query_vector = embed_model.embed_query(query) res = client.search( collection_name="demo_collection", data=[query_vector], limit=3, output_fields=["text", "metadata"], ) context = "\n".join([data["entity"]["text"] for data in res[0]])

检索到上下文后,构建消息列表并调用模型。这里的关键是系统提示词要约束模型严格基于上下文回答:

message_list = [ { "role": "system", "content": "你是一个专业的法律问答机器人,请严格根据提供的上下文回答问题,当上下文无法回答问题时,直接回答“根据上下文无法回答该问题”" }, { "role": "user", "content": f"根据以下上下文回答问题:\n{context}\n\n问题:{query}" } ] llm = init_chat_model( model_name="gpt-4o-mini", base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY"), temperature=0.1, ) res = llm.invoke(message_list) print(res.content)

3.2 Agent 本地工具配置

Agent 的核心是"大模型做决策,工具做执行"。用 @tool 装饰器把普通函数转成标准工具:

from langchain.tools import tool from pydantic import BaseModel, Field class AddNumberParams(BaseModel): a: int = Field(description="需要相加的第一个整数") b: int = Field(description="需要相加的第二个整数") @tool( name_or_callable="calc_two_int_sum", description="用于计算两个整数的和,输入为两个整数,输出为求和结果", args_schema=AddNumberParams ) def add_number(a: int, b: int) -> int: return a + b

然后创建 Agent,把工具列表传进去:

from langchain.agents import create_agent from langchain_tavily import TavilySearch tavily_search = TavilySearch( tavily_api_key=os.getenv("TAVILY_API_KEY"), max_results=5 ) tools = [add_number, tavily_search] llm = init_chat_model( model="gpt-4o-mini", model_provider="openai", base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY"), temperature=0.1 ) agent = create_agent( model=llm, tools=tools, system_prompt="你是一个全能助手,会根据用户问题选择合适的工具:计算问题调用add_number,信息查询问题调用TavilySearch,无需工具时直接回答" )

3.3 MCP 工具注册配置

MCP 工具通过 langchain_mcp_adapters 接入,配置用 JSON 结构描述传输方式和地址:

from langchain_mcp_adapters.client import MultiServerMCPClient mcp_client = MultiServerMCPClient( { "12306-mcp": { "transport": "streamable_http", "url": "https://mcp.api-inference.modelscope.net/c30f9b25034446/mcp" } } ) mcp_tools = await mcp_client.get_tools() agent = create_agent(llm, mcp_tools)

如果你要自己搭 MCP 服务器,Stdio 模式的启动配置是:

from mcp.server.fastmcp import FastMCP mcp = FastMCP("DemoMCP-Stdio") @mcp.tool() def add(a: int, b: int) -> int: """两个整数相加""" return a + b if __name__ == "__main__": mcp.run(transport="stdio")

Streamable HTTP 模式只需改传输参数:

if __name__ == "__main__": mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)

3.4 Agent 记忆配置

记忆功能靠 Checkpointer 实现,开发阶段用 InMemorySaver,生产环境换 RedisSaver:

from langgraph.checkpoint.memory import InMemorySaver checkpointer = InMemorySaver() agent = create_agent( model=llm, tools=tools, checkpointer=checkpointer, system_prompt="你是一个智能搜索助手,按需调用搜索工具,记住用户之前的问题" ) THREAD_ID = "session_001" resp = agent.invoke( input={"messages": [{"role": "user", "content": "2026年杭州亚运会的举办时间是什么时候?"}]}, config={"configurable": {"thread_id": THREAD_ID}} )

三件套对照表,方便你检查配置是否齐全:

组件Base URLKeyModel ID
RAG 生成https://taotoken.net/apiOPENAI_API_KEYgpt-4o-mini
Agent 推理https://taotoken.net/apiOPENAI_API_KEYgpt-4o-mini
MCP 工具由 MCP Server 地址决定由 MCP Server 决定不涉及

4. 验证请求:一次端到端 RAG 问答的预期输出

配置写完,必须跑一次完整链路确认。这一节给出验证动作和每一步的预期输出,你对照着看就知道哪一环断了。

验证一:模型通道。运行第 2 节的最小脚本,预期输出一句关于 RAG 的解释。如果返回空字符串,检查 model 名称是否拼错;如果报 401,检查 .env 是否被 load_dotenv 正确加载。

验证二:向量检索。运行 3.1 的检索片段,预期输出三条相似结果,每条包含 distance、text、metadata:

【相似结果1】 相似度:0.8231 文本内容:不动产被他人占有的,权利人可以请求返还原物... 元数据:{'source': 'law_doc_001'}

如果 distance 全是 0 或者结果明显不相关,说明嵌入模型和入库时的模型不一致,检查 bge-base-zh-v1.5 的路径是否指向同一个模型。

验证三:RAG 生成。把检索结果拼成 context 后调用模型,预期输出一段严格基于上下文的回答。如果模型开始编造,说明系统提示词没生效,检查 message_list 里 system 角色是否放在第一位。

验证四:Agent 工具调用。运行 3.2 的 Agent,输入"计算100+200的结果",预期输出 300,并且中间能看到工具调用记录。输入"2026年北京冬奥会的比赛项目有哪些",预期触发 TavilySearch 并返回搜索结果摘要。

验证五:MCP 工具。运行 3.3 的 MCP Agent,输入"帮我查一下明天北京到上海的高铁",预期 Agent 调用 12306 MCP 工具并返回车次信息。如果报连接错误,检查 MCP Server 地址是否可访问。

验证六:记忆功能。运行 3.4 的代码,第一次问"2026年杭州亚运会的举办时间",第二次问"这个赛事的主体育场是什么",预期第二次回答能关联到第一次的问题。第三次问"我刚才问了你什么问题",预期返回历史问题。

流式调用验证,Agent 处理多步任务时用 stream 看中间进度:

for chunk in agent.stream( { "messages": [ {"role": "system", "content": "你是一个全能助手,按需调用工具"}, {"role": "user", "content": "计算999+888的结果,再查一下这个结果的相关数学知识"} ] } ): print(chunk, end="\n\n")

预期能看到工具调用、工具返回、最终回答分块输出。如果 stream 一直卡住不返回,检查模型通道是否支持流式,TaoToken 的 OpenAI 兼容通道默认支持。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

这一节按真实报错来,每个错误给出原因和修复动作。

401 Unauthorized。最常见的原因是 Key 没读到。检查三处:.env 文件是否在项目根目录、load_dotenv() 是否在读取环境变量之前调用、Key 复制时是否带了首尾空格。还有一种情况是 Key 被禁用或额度耗尽,去控制台 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 确认 Key 状态。

local proxy failed / Connection error。这个报错通常出现在 Base URL 配置错误时。如果你把 OPENAI_BASE_URL 写成了 https://taotoken.net 而漏了 /api,LangChain 会请求 https://taotoken.net/chat/completions,返回 404 或连接失败。正确写法是 https://taotoken.net/api 。另外检查本地网络是否能访问该地址,公司内网可能需要配置出口。

Error reading choices / KeyError: 'choices'。这个报错说明返回的 JSON 结构里没有 choices 字段,通常是模型名称写错了。比如你写了 model="gpt-4o" 但通道里没有这个模型,返回的可能是错误信息而不是标准响应。检查 model 名称是否在 TaoToken 支持的模型列表里,可以先用模型对话页面确认。

OAuth / authentication_error。如果你用的是 Claude Code 或 Codex 这类工具,报 OAuth 错误说明认证方式不对。这类工具需要配置 Base URL + Key + Model ID 三件套。以 Codex 的 auth.json 为例:

{ "OPENAI_API_KEY": "sk-你的TaoToken密钥", "OPENAI_BASE_URL": "https://taotoken.net/api" }

Claude Code 的配置在 settings.json 里,同样需要填全 Base URL、Key、Model ID。如果只填了 Key 没填 Base URL,工具会默认走官方通道,导致认证失败。接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里有各工具的完整配置示例。

MCP 工具加载为空。mcp_client.get_tools() 返回空列表,检查 MCP Server 地址是否可访问、transport 类型是否匹配。Streamable HTTP 用 "streamable_http",Stdio 用 "stdio"。如果 MCP Server 需要认证,还要在配置里加 headers。

Agent 不调用工具。模型直接回答而不调工具,通常是 system_prompt 没写清楚工具用途。把每个工具什么时候用写进提示词,比如"计算问题调用 add_number,信息查询调用 TavilySearch"。另外检查工具描述是否准确,模型是根据 description 判断是否调用的。

记忆不生效。多轮对话没有上下文,检查 invoke 时是否传了 config={"configurable": {"thread_id": THREAD_ID}},以及 create_agent 时是否传了 checkpointer。两个条件缺一不可。

6. 把链路跑稳之后:统一 Key 的长期价值

走到这里,你应该已经跑通了一条完整的 LangChain RAG + Agent + MCP 链路。回头看,最省事的决定是把模型调用统一到一套 Base URL 和 Key 上。RAG 的生成层、Agent 的推理层、MCP 工具背后的模型调用,全部走同一个通道,换模型时只改 model 参数,不动 base_url 和 api_key。

如果你打算把这条链路用到长期项目里,Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 比按量调用更适合高频场景。接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里有各语言 SDK 的配置示例,遇到参数问题可以直接对照。API Keys 管理页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 可以创建多个 Key 做项目隔离,避免一个 Key 被限流影响所有服务。

最后留一个实用技巧:把 RAG 的检索结果和 Agent 的工具调用记录都打到日志里,出问题时先看检索片段是否相关、再看模型是否基于上下文回答、最后看工具调用参数是否正确。这三层日志能覆盖 90% 的 RAG + Agent 故障。链路跑通只是开始,把可观测性做起来,才能在生产环境里睡得着觉。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询