
1. 从一次“概念打架”说起embedding、RAG、function calling 到底谁管谁刚接触大模型应用开发时最容易犯的错不是代码写不出来而是把几个名词混成一锅粥。我见过不少朋友在群里问“RAG 是不是就是 embedding”“function calling 和 mcpserver 是不是一回事”“我用了向量数据库为什么模型还是答非所问”这些问题背后其实是对五个基础概念的定位没理清。这篇学习笔记就干一件事把 embedding、嵌入模型、RAG、function calling、mcpserver 这五个词放回它们各自该待的位置再用 TaoToken 的统一 Key 把它们串成一条能跑通的链路。你不需要先成为算法专家只要会写 Python、会改配置文件就能跟着走完。先给一个最简版的关系图后面再逐个拆embedding是一种“把文字变成数字向量”的动作或结果。嵌入模型是执行这个动作的模型比如 text-embedding-3-small、BGE-M3。RAG是一套“先查资料再回答”的流程它依赖 embedding 和向量数据库。function calling是大模型“决定调用哪个外部函数”的协议。mcpserver是把函数按统一协议暴露出来的服务端让客户端能发现并调用。适合谁看适合已经能跑通一次大模型对话、但一提到“知识库”“工具调用”就卡壳的开发者。下面从场景问题开始一步步把配置和验证动作补上。2. 五个概念的定位别再把 RAG 和 function calling 混着用2.1 embedding 与嵌入模型把语义压进向量里传统中文编码像一本死字典每个字对应一个固定编号换个语境意思就丢了。embedding 不一样它把词、句、段投射到高维空间语义越近的点距离越近。嵌入模型就是干这个投射的模型。你可以这样理解嵌入模型是“翻译官”把人类语言翻译成机器能算距离的坐标。OpenAI 的 text-embedding-3-small 支持 8192 tokens适合快速验证BGE-M3 支持密集、稀疏、多向量混合检索中文场景表现稳。选哪个取决于你的数据语言和部署条件。关键动作拿到一段文本调用嵌入模型得到一个固定维度的浮点数组。这个数组就是后续检索的“钥匙”。2.2 RAG检索增强生成的完整流水线RAG 不是某个模型而是一条流水线。它把知识先切分、再向量化、存进向量库用户提问时把问题也向量化去库里找最相似的分片再把分片和问题一起发给大模型。这里有个容易忽略的点切分策略直接影响召回质量。按行分、按句号分、按固定字数分效果差别很大。我一般先用固定字数加重叠窗口做第一版跑通后再调。Rerank 是 RAG 的可选精排环节。初筛返回 Top N 后用重排模型再算一次相关性把最相关的推到前面。Qwen3-Reranker 和 BGE-Reranker-v2-m3 都是常见选择。2.3 function calling让模型“决定调哪个函数”function calling 解决的是“模型不知道实时信息”的问题。比如问明天天气模型本身没有这个数据但它可以根据你提供的函数描述输出一个结构化的调用请求告诉你“该调 get_weather参数是城市名”。注意function calling 是模型侧的能力需要模型或 API 层支持。它不负责真正执行函数只负责“决定调什么、传什么参数”。2.4 mcpserver把函数按协议暴露出来mcpserver 可以理解成一个“函数仓库”。它按 MCP 协议对外描述自己有哪些工具、每个工具的参数和调用方式。客户端比如 Cline启动时先和 mcpserver 通信拿到工具清单再把清单塞进 system prompt 发给大模型。大模型返回调用请求后客户端解析并真正执行 mcpserver 里的函数拿到结果再回传给模型。这一整套下来就是一个典型的 AI Agent 循环。2.5 五者串联关系把上面四个串起来嵌入模型产出 embeddingembedding 支撑 RAG 的检索function calling 让模型能触发外部动作mcpserver 是这些动作的标准化容器。TaoToken 在这里的角色是提供统一的 API Key 和接入地址让你不用为每个模型单独配一套鉴权。3. TaoToken 前置统一 Key 与 config.toml 骨架在动手写代码前先把 TaoToken 的接入信息准备好。你需要一个统一 Key后面所有模型调用都走它。访问控制台创建 Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite创建完成后在 API Keys 页面复制你的 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档在这里遇到参数问题先查它https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite下面是一份可复制的 config.toml 骨架。我把它分成三段模型接入、RAG 相关、MCP 相关。你按自己的环境改路径和 Key 即可。# config.toml - TaoToken 统一接入骨架 [taotoken] base_url https://taotoken.net/api api_key sk-你的统一Key # 注意base_url 不带 UTM保持干净 [models] # 对话模型用于 RAG 生成和 function calling chat_model gpt-4o-mini # 嵌入模型用于把文本转向量 embedding_model text-embedding-3-small # 重排模型可选 rerank_model bge-reranker-v2-m3 [rag] chunk_size 500 chunk_overlap 50 top_k 5 vector_store qdrant qdrant_url http://localhost:6333 collection_name my_knowledge [mcp] # mcpserver 启动命令示例按实际脚本路径改 server_command uv server_args [run, weather_server.py] transport stdio这份骨架的重点是所有模型调用都指向同一个 base_url 和 api_key。你不需要为嵌入模型、对话模型、重排模型分别配三套鉴权。4. 可复制配置从嵌入到 MCP 的逐项落地4.1 嵌入模型调用配置先验证嵌入模型能不能通。用 Python 写一个最小调用import os from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keyos.environ[TAOTOKEN_API_KEY] ) resp client.embeddings.create( modeltext-embedding-3-small, inputRAG 的第一步是把文本变成向量 ) vec resp.data[0].embedding print(维度:, len(vec)) print(前5个值:, vec[:5])跑通后你会看到类似维度: 1536的输出。这说明嵌入模型已经可用。4.2 RAG 检索链路配置把嵌入结果存进 Qdrant再查出来。这里用 HTTP API 演示避免装额外 SDK# 创建集合向量维度要和嵌入模型一致 curl -X POST http://localhost:6333/collections \ -H Content-Type: application/json \ -d { name: my_knowledge, vector_size: 1536, distance: Cosine }插入一条数据curl -X POST http://localhost:6333/collections/my_knowledge/points \ -H Content-Type: application/json \ -d { points: [ { id: 1, vector: [0.01, 0.02, ...省略..., 0.03], payload: {text: RAG 是检索增强生成} } ] }查询相似向量curl -X POST http://localhost:6333/collections/my_knowledge/points/search \ -H Content-Type: application/json \ -d { vector: [0.01, 0.02, ...省略..., 0.03], limit: 3, with_payload: true }4.3 function calling 配置定义一个天气函数让模型决定是否调用tools [ { type: function, function: { name: get_weather, description: 获取指定城市天气, parameters: { type: object, properties: { city: {type: string, description: 城市名} }, required: [city] } } } ] resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 北京明天天气怎么样}], toolstools, tool_choiceauto ) print(resp.choices[0].message.tool_calls)如果模型返回了tool_calls说明 function calling 生效。4.4 mcpserver 配置mcpserver 的配置核心是“声明工具清单”。一个最小 Python 示例# weather_server.py from mcp.server import Server from mcp.types import Tool, TextContent server Server(weather) server.list_tools() async def list_tools(): return [ Tool( nameget_weather, description获取城市天气, inputSchema{ type: object, properties: {city: {type: string}}, required: [city] } ) ] server.call_tool() async def call_tool(name, arguments): if name get_weather: city arguments[city] return [TextContent(typetext, textf{city} 明天晴25度)] if __name__ __main__: server.run(transportstdio)启动方式在 config.toml 里已经写了uv run weather_server.py。5. 验证请求怎么确认每一环真的生效配置写完不代表链路通了。我习惯逐项验证每步都有明确的成功信号。第一步验证嵌入模型。跑 4.1 的代码看到维度数字就是成功。如果报 401检查 Key如果报 404检查模型名。第二步验证向量库。访问http://localhost:6333/healthz返回healthz check passed说明 Qdrant 活着。再执行 4.2 的查询返回带payload的结果说明检索通。第三步验证 function calling。跑 4.3 的代码如果tool_calls不为空说明模型正确识别了函数调用意图。如果为空检查tool_choice和函数描述是否清晰。第四步验证 mcpserver。在客户端里启动 mcpserver看是否能列出工具清单。Cline 这类客户端会在启动时打印发现的工具。第五步端到端验证。把 RAG 检索到的分片和用户问题拼成 prompt发给对话模型看回答是否引用了分片内容。这一步成功说明整条链路打通。如果你想先单独验证模型对话是否正常可以用模型对话页面快速测一下https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite6. 本篇常见错排查从 401 到检索为空6.1 401 Unauthorized最常见的原因是 Key 没传对。检查三点环境变量是否设置、base_url 是否写成https://taotoken.net/api、请求头是否带了Authorization: Bearer sk-xxx。注意 base_url 不要带 UTM 参数。6.2 嵌入维度不匹配Qdrant 创建集合时指定的vector_size必须和嵌入模型输出维度一致。text-embedding-3-small 是 1536BGE-M3 是 1024。如果你换了嵌入模型但没重建集合插入时会报维度错误。解决办法是删掉集合重建。6.3 检索结果为空先确认集合里有数据。用curl http://localhost:6333/collections/my_knowledge看points_count。如果为 0说明插入失败。如果数据有但查询为空检查查询向量的维度是否和集合一致以及limit是否设得太小。6.4 function calling 不触发模型不调用函数通常是描述不够清楚。把description写具体比如“获取指定城市的当前天气和温度”比“获取天气”更容易触发。另外确认模型本身支持 function calling部分轻量模型不支持。6.5 mcpserver 启动失败先单独在终端跑uv run weather_server.py看有没有报错。常见问题是依赖没装、路径不对、stdio 传输被其他输出干扰。确保脚本里没有多余的 print 语句否则会污染协议通信。6.6 RAG 回答不引用分片如果模型回答完全忽略检索内容检查 prompt 拼接方式。分片内容要明确标注为“参考资料”并指示模型优先基于参考资料回答。另外确认 top_k 不要太小太小可能召回不到相关内容。7. 下一步把链路跑顺后再谈优化概念理清、链路跑通之后优化才有意义。你可以先调 chunk_size 和 top_k观察召回质量变化再考虑加 Rerank 精排最后把 mcpserver 的工具数量控制住工具太多会稀释模型的注意力。如果你准备长期做编码类或 Agent 类项目可以了解 Coding Plan 的接入方式https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteClaude Code 相关接入参考https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite我自己的习惯是每加一个新概念就先写一个最小验证脚本跑通了再往主链路里塞。这样出问题时你能快速定位是哪一环断了而不是对着一整块代码猜。