1. 从零理解 LLM/Prompt/RAG/MCP:小白程序员做 Agent 开发到底卡在哪
很多刚转到大模型方向的朋友,第一个卡点不是写代码,而是概念对不上。面试官问「你这个 Agent 的 tool call 是怎么触发的」,脑子里只有「我调了个接口它就回了」;同事说「这段走 RAG,那段走 MCP」,你点头如捣蒜,回去偷偷搜。我试过最笨的办法——把 LLM、Prompt、RAG、MCP、Agent 这几个词抄在便签上贴显示器,结果一周后还是说不清它们之间的边界。
问题的根源在于:这些概念不是并列关系,而是一条从底层能力到上层编排的链路。LLM 是发动机,Prompt 是你踩油门的姿势,RAG 是给它临时加的外挂油箱,MCP 是标准化的接口插座,Agent 则是把上面这些组装成一辆能自己找路开的车。你如果只记住名词,不跑通一次真实调用,永远会觉得它们是散的。
这篇就按这条链路走一遍,目标很明确:让你在本地用一个统一的 Key 和 Base URL,依次跑通一次 Prompt 调用、一次 RAG 检索、一次 MCP 工具调用,最后拼成一个最小 Agent 闭环。适合谁?适合会一点 Python、能看懂 JSON、但被各种「协议」「框架」绕晕的小白程序员。全程不需要你分别去注册五六个平台的账号,TaoToken 在这里的作用就是把 LLM 调用这一层的入口统一掉,你只管把注意力放在链路上。
先说清楚 LLM 到底在干什么。你给它一段自然语言,它内部用 Transformer 把文本切成 token,然后一个 token 一个 token 地预测下一个最可能出现的 token,最后再拼回自然语言。所谓「大」指的是参数量,DeepSeek R1 是 671B,这个量级决定了它的泛化能力。理解这一点很关键:LLM 本身不会查天气、不会读你的数据库、不会买门票,它只会根据你给的上下文续写。所有后面要讲的 RAG、Tool call、MCP,本质都是在「想办法把正确的上下文塞给它」或者「让它能触发外部动作」。
Prompt 就是塞给它的那段自然语言,分 system prompt 和 user prompt。system prompt 一般内置在 Agent 里,定义角色和规则;user prompt 是用户输入。很多人以为 Prompt 就是「会说话就行」,其实它是你控制 LLM 行为最直接的手段。RAG 则是当 LLM 不知道答案时,你先去检索一段相关资料,和问题一起发过去,让它基于资料回答。注意一个常见混淆:RAG 不等于向量数据库,向量库只是检索的一种实现,你完全可以用普通文本或 JSON 做检索。
再往上就是 Tool call 和 MCP。Tool call 让 LLM 能「告诉你的代码去执行某个函数」,比如查天气、买门票。但每个 Agent 都内置一堆 tool 不现实,于是有了 MCP(Model Context Protocol,模型上下文协议),它定义了一套标准,让 MCP Server 声明自己能提供哪些 tool,MCP Client 去拉取列表并告诉 LLM。这里要纠正一个高频误用:MCP 本身是协议,不是工具集,说「MCP 协议」等于说「协议协议」。Agent 则是把这些能力编排起来,用 Re-Act 循环(reasoning-action-observation)动态决定下一步做什么。
2. TaoToken 统一 Key 前置准备:Base URL 与 API Key 怎么配才不报 401
在跑通链路之前,得先把「入口」统一掉。小白最容易踩的坑是:LLM 用一个平台的 Key,Embedding 用另一个,工具调用又换一个,结果环境变量满天飞,一出 401 就不知道是哪个 Key 失效了。TaoToken 在这里的价值就是提供一个统一的 API 通道,你只需要维护一套 Base URL 和 Key,后面 Prompt、RAG、MCP 里涉及模型调用的部分都走它。
先明确两个地址,别搞混:
- 官网入口(注册、看文档、进控制台):
https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= - API 调用地址(代码里填的 Base URL):
https://taotoken.net/api,注意这个不加任何 UTM 参数,直接作为 base_url 用。
第一步,去控制台创建 API Key。路径是 console 页面,登录后进 API Keys 管理,新建一个 Key,复制出来。这个 Key 就是后面所有调用的凭证,别硬编码进代码,用环境变量。
第二步,配置环境变量。Linux/macOS 在~/.zshrc或~/.bashrc里加,Windows 用系统环境变量或.env文件。推荐用.env配合 python-dotenv,方便管理:
# .env 文件,放在项目根目录 TAOTOKEN_API_KEY=sk-你的实际key粘贴在这里 TAOTOKEN_BASE_URL=https://taotoken.net/api然后在 Python 里这样读:
import os from dotenv import load_dotenv load_dotenv() api_key = os.getenv("TAOTOKEN_API_KEY") base_url = os.getenv("TAOTOKEN_BASE_URL") print("Key 前缀:", api_key[:8] if api_key else "未读取到") print("Base URL:", base_url)跑一下,能打印出 Key 前缀和 Base URL 就说明环境变量生效了。如果打印「未读取到」,八成是.env没放在执行目录,或者 load_dotenv 没调用。
第三步,确认你要用的 Model ID。不同模型 ID 不一样,比如对话模型、Embedding 模型是分开的。你可以在模型对话页面先手动试一句,确认这个模型 ID 可用,再写进代码。这一步别省,很多人 401 和 404 混在一起,其实是 Model ID 写错了。
这里给一个最容易出错的对照,先记住三件套:Base URL + API Key + Model ID,缺一不可,而且三者要匹配。后面无论你用 OpenAI SDK、LangChain 还是自己写 HTTP 请求,本质都是把这三个值填对。
注意:Base URL 结尾不要多加
/v1或斜杠,除非文档明确要求。很多local proxy failed或 404 就是路径拼错导致的。
配置完先别急着写复杂逻辑,用一段最小代码验证通道是否通:
from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() client = OpenAI( api_key=os.getenv("TAOTOKEN_API_KEY"), base_url=os.getenv("TAOTOKEN_BASE_URL"), ) resp = client.chat.completions.create( model="你确认可用的模型ID", messages=[{"role": "user", "content": "用一句话解释什么是 token"}], ) print(resp.choices[0].message.content)能正常打印出一句话,说明统一 Key 通道已经打通。这一步是整个链路的地基,地基不稳,后面 RAG 和 MCP 的报错你根本分不清是通道问题还是逻辑问题。
3. 可复制配置:Prompt 调用 + RAG 检索 + MCP 工具调用三件套
地基打好后,开始拼链路。这一节给你三段可直接复制的配置和代码,分别对应 Prompt 调用、RAG 检索、MCP 工具调用。每段都独立可跑,最后再合成 Agent。
3.1 Prompt 调用:把 system 和 user 分开写
Prompt 调用是最基础的一环,但小白常犯的错是把所有话塞进一条 user message。正确做法是 system 定义角色,user 提需求:
def ask_llm(system_prompt: str, user_prompt: str) -> str: resp = client.chat.completions.create( model="你确认可用的模型ID", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], temperature=0.3, ) return resp.choices[0].message.content result = ask_llm( system_prompt="你是一个严谨的技术助手,回答不超过三句话。", user_prompt="RAG 和向量数据库是什么关系?", ) print(result)temperature调低一点,回答更稳定。system prompt 里写清楚约束,比在 user 里反复强调有效得多。
3.2 RAG 检索:先检索再拼上下文
RAG 的核心动作是「检索 + 拼接」。这里用一个最简单的本地文本检索演示,不依赖向量库,让你先看清流程:
# 模拟一个知识库 knowledge_base = [ "TaoToken 的 API Base URL 是 https://taotoken.net/api", "MCP 是模型上下文协议,不是工具集", "RAG 的检索部分可以用向量库,也可以用普通文本匹配", ] def simple_retrieve(query: str, top_k: int = 2) -> list: # 极简关键词匹配,生产环境请换成向量检索 scored = [] for doc in knowledge_base: score = sum(1 for ch in query if ch in doc) scored.append((score, doc)) scored.sort(reverse=True) return [doc for _, doc in scored[:top_k]] def rag_answer(query: str) -> str: docs = simple_retrieve(query) context = "\n".join(docs) prompt = f"根据以下资料回答问题,资料没有的信息不要编造。\n资料:\n{context}\n\n问题:{query}" return ask_llm("你是一个基于资料回答的助手。", prompt) print(rag_answer("MCP 是什么?"))跑通后你会看到,模型回答里用到了知识库里的内容。这就是 RAG 的最小闭环:检索 → 拼上下文 → 生成。生产环境把simple_retrieve换成向量检索即可,但流程不变。
3.3 MCP 工具调用:让 LLM 触发外部函数
MCP 涉及 Host、Client、Server 三个角色。小白先理解 Client 和 Server 的交互即可。下面用 OpenAI 的 function calling 形式模拟一次工具调用,帮你理解「LLM 返回 tool call,你的代码执行,再把结果喂回去」这个循环:
import json # 1. 声明工具(相当于 MCP Server 声明的 tool) tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的天气", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名"} }, "required": ["city"], }, }, } ] # 2. 本地实现这个工具 def get_weather(city: str) -> str: fake_db = {"北京": "晴,25度", "上海": "多云,28度"} return fake_db.get(city, "暂无数据") # 3. 第一次调用,让 LLM 决定是否用工具 messages = [{"role": "user", "content": "北京天气怎么样?"}] resp = client.chat.completions.create( model="你确认可用的模型ID", messages=messages, tools=tools, ) msg = resp.choices[0].message if msg.tool_calls: call = msg.tool_calls[0] args = json.loads(call.function.arguments) tool_result = get_weather(args["city"]) # 4. 把工具结果喂回去 messages.append(msg) messages.append({ "role": "tool", "tool_call_id": call.id, "content": tool_result, }) final = client.chat.completions.create( model="你确认可用的模型ID", messages=messages, tools=tools, ) print(final.choices[0].message.content)这段代码就是 Agent 的雏形:LLM 决定调工具 → 代码执行 → 结果回传 → LLM 生成最终回答。MCP 做的事,就是把这个「工具声明和调用」标准化,让不同 Agent 都能复用同一个 Server。
3.4 合成最小 Agent 闭环
把上面三段串起来,就是一个最小 Agent:先 RAG 检索补充上下文,再让 LLM 决定是否调工具,最后输出。你可以把rag_answer的检索结果作为 system 上下文,再走工具调用流程。跑通一次,你对 LLM/Prompt/RAG/MCP/Agent 的关系就再也不会混了。
4. 验证请求与成功结果:一次 Prompt、一次 RAG、一次 MCP 怎么确认跑通
写完代码不等于跑通,得会看结果。这一节给你三个明确的验证动作和预期输出,照着对,能快速判断链路是否正常。
验证一:Prompt 调用。执行 3.1 的代码,预期输出是一句关于 RAG 和向量库关系的简短回答,不超过三句。如果返回空字符串,检查resp.choices是否为空;如果报reading choices相关错误,通常是返回结构和你取值的路径不一致,打印resp整体看结构。
验证二:RAG 检索。执行 3.2,问「MCP 是什么」,预期回答里出现「模型上下文协议,不是工具集」这个信息。如果模型答得和知识库无关,说明检索没命中,打印simple_retrieve的返回看看是不是空列表。这一步能验证「检索 → 拼接 → 生成」是否真的把上下文带进去了。
验证三:MCP 工具调用。执行 3.3,问「北京天气怎么样」,预期先触发get_weather,最终输出包含「晴,25度」。如果模型直接编了个天气而没调工具,说明tools参数没生效或模型不支持 function calling,换一个支持工具调用的 Model ID。
三个都通过后,做一个串联验证:把知识库换成你自己的文档,问一个只有文档里才有的问题,看 RAG 是否生效;再问一个需要调工具的问题,看工具是否触发。两个都正常,最小 Agent 闭环就算跑通了。
成功结果的判断标准很简单:输出内容里出现了你知识库的独有信息,且工具调用返回了真实执行结果。只要这两点满足,说明 LLM、Prompt、RAG、MCP 四层都通了。
提示:验证阶段把每一步的中间结果都打印出来,别只看最终输出。Agent 出问题时,定位靠的是中间态,不是最终那句话。
5. 本篇常见报错排查:401、local proxy failed、reading choices、OAuth 对照解决
链路跑不通,九成是下面这几类报错。逐个对照,基本能自救。
401 Unauthorized。最常见,Key 错了或没读到。先确认.env里的 Key 没有多余空格,再确认load_dotenv()在读取前调用。如果 Key 是从控制台复制的,注意别把前后引号也复制进去。还有一种情况是 Key 被禁用或额度用尽,去 console 的 API Keys 页面看状态。
local proxy failed / connection error。这类多半是 Base URL 写错或网络层问题。确认base_url是https://taotoken.net/api,结尾没有多余斜杠,也没有自己加/v1。如果你在代码里同时设了系统代理环境变量,可能干扰请求,检查HTTP_PROXY、HTTPS_PROXY是否被意外设置。
reading choices / KeyError: 'choices'。这是取值路径错误,不是请求失败。先print(resp)看真实返回结构。有些兼容接口返回的字段层级和 OpenAI 不完全一致,或者返回的是错误对象。确认resp.choices[0].message.content这条路径和实际结构匹配。
OAuth 相关报错。如果你用的是 Claude Code 这类工具,出现 OAuth 报错通常是登录态失效或配置的认证方式不对。检查配置文件里的认证字段,确认用的是 API Key 方式而不是过期的 OAuth token。涉及 Claude Code 时,把三件套写全:Base URL 填https://taotoken.net/api,Key 填你的 TaoToken Key,Model ID 填确认可用的模型。
Model not found / 404。Model ID 写错,或者这个模型在你的账号下不可用。去模型对话页面手动发一句,确认模型 ID 拼写,再回代码里改。
工具调用不触发。检查tools参数格式,确认模型支持 function calling。有些模型对工具调用的支持有限,换模型试。
排查顺序建议:先确认通道(401/连接类)→ 再确认取值(choices 类)→ 最后确认业务逻辑(工具不触发)。别一上来就改业务代码,先把通道和取值排干净。
6. 语义一致 CTA:把统一 Key 用进你的长期 Agent 项目
跑通最小闭环后,下一步就是把它用进真实项目。如果你只是偶尔验证模型效果,直接在模型对话页面手动试最省事;如果你要长期写代码、搭 Agent,建议把 TaoToken 的 Key 固定到项目环境里,配合 Coding Plan 做持续开发,省得每次换项目都重新配一遍。
具体入口按你的场景选:
- 需要创建和管理 Key:进 API Keys 页面,路径是 console 下的 api-keys。
- 需要查接入细节和参数:看接入文档,路径是 doc。
- 想先手动验证模型再写代码:用模型对话页面。
- 长期编码、搭 Agent 工作流:了解 Coding Plan。
- 用 Claude Code 接入:参考 ClaudeCodeAnthropic 相关配置说明。
把这篇里的三段代码存成一个agent_demo.py,把知识库换成你自己的文档,把get_weather换成你真实的业务函数,你就有了一个能跑的最小 Agent。后面再学 Memory、Sub-agents、Context Compaction 这些进阶概念时,你至少有一个能动手改的基线,而不是对着一堆名词空想。链路这东西,跑通一次,比看十篇概念文都管用。