RAG与MCP:2026年开发者完整指南
RAG与MCP的实操对比:针对那些希望部署RAG系统且避免静默式部分故障的团队,涵盖合同、校验机制以及可直接插入的代码模块。
以下内容围绕“RAG与MCP:2026年开发者完整指南”梳理出一条实用路径。重点在于契约、校验机制以及可直接插入的代码占位符,而非激励性表述。
简述
在撰写简述时,首先明确契约要求:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续代码修改的规范性。 在功能结果旁记录执行时间以及代币或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。 在调整提示词之前,先使用固定问题集测试召回率。频繁更换提示词往往无法改善较差的检索效果。
第一部分:RAG究竟是什么
在学习第一部分“RAG究竟是什么”时,首先列出相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
帮助理解的类比
在研读《让概念清晰易懂的类比》时,首先需列出相关规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 在调整提示词之前,需先用固定的问题集来衡量检索效果。仅仅更换提示词很难解决检索能力不足的问题。
为何需要向量数据库
在探讨为何需要向量数据库时,首先列出相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤出错时,错误应指向单一责任模块,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难改善较差的检索效果。
代码中的RAG
在用代码实现RAG时,首先要明确契约内容:所需的输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将这一阶段视为输入与验证后输出之间的契约。为相关组件命名,定义成功检测标准,并杜绝无声的半完成状态。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词很难解决检索效果不佳的问题。 在用代码实现RAG时,首先要明确契约内容:所需的输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将配置信息放在应用程序代码之外。环境文件、密钥存储和功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。
from openai import OpenAI
client = OpenAI()
# Your knowledge base, already chunked.
DOCUMENTS = [
"The P/E ratio divides share price by earnings per share. "
"When earnings are negative, P/E is undefined and usually shown as N/A.",
"EV/EBITDA is often preferred over P/E for capital-intensive companies "
"because it is unaffected by capital structure and depreciation policy.",
"The PEG ratio adjusts P/E by the expected earnings growth rate. "
"A PEG below 1.0 is traditionally read as undervalued.",
]
def embed(text: str) -> list[float]:
"""Turn text into a vector."""
response = client.embeddings.create(
model="text-embedding-3-small",
input=text,
)
return response.data[0].embedding
def cosine_similarity(a: list[float], b: list[float]) -> float:
"""How close are two vectors? 1.0 means identical direction."""
dot = sum(x * y for x, y in zip(a, b))
norm_a = sum(x * x for x in a) ** 0.5
norm_b = sum(y * y for y in b) ** 0.5
return dot / (norm_a * norm_b)
# Index once, reuse many times. In production this lives in a vector DB.
INDEX = [(doc, embed(doc)) for doc in DOCUMENTS]
def retrieve(question: str, k: int = 2) -> list[str]:
"""Step 1: find the most relevant chunks."""
q_vector = embed(question)
scored = [
(cosine_similarity(q_vector, vector), doc)
for doc, vector in INDEX
]
scored.sort(reverse=True)
return [doc for _, doc in scored[:k]]
def answer(question: str) -> str:
"""Steps 2 and 3: augment the prompt, then generate."""
context = "\n\n".join(retrieve(question))
prompt = (
f"Answer using only the context below.\n\n"
f"Context:\n{context}\n\n"
f"Question: {question}"
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return response.choices[0].message.content
print(answer("What do I use when a company has negative earnings?"))
第二部分:MCP究竟是什么
第二部分:MCP的真正含义在于将其视为可度量的界面来理解。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。应将分块策略与检索策略分开,当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
类比说明
将其视为可测量的表面时,这种类比最为有效。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。相较于庞大的脚本,应优先选择小型且可测试的单元。当某个步骤失败时,故障应指向单一的责任主体,而非复杂的流程链。应将分块策略与检索策略分开处理;当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
MCP服务器提供的三项功能
MCP服务器提供的三项功能,若将其视为可度量的指标,则能发挥最佳作用。在扩大范围之前,需记录一份理想的处理结果、一个故障案例以及回滚说明。 应将此阶段视为输入与经过验证的输出之间的契约。为相关成果命名,明确成功标准,杜绝默许的半完成状态。 应将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。 MCP服务器提供的三项功能,若将其视为可度量的指标,则能发挥最佳作用。在扩大范围之前,需记录一份理想的处理结果、一个故障案例以及回滚说明。 应将配置置于应用程序代码之外。环境文件、密钥存储及功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
代码中的MCP
在编写代码实现MCP时,应在修改代码之前明确定义输入参数、该步骤的负责人以及终止条件。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 必须引用那些真正作为答案依据的段落。如果没有引用,操作员就无法区分是幻觉内容还是索引缺失导致的错误。
from mcp.server.fastmcp import FastMCP
import httpx
mcp = FastMCP("finance-tools")
@mcp.tool()
def get_current_price(ticker: str) -> dict:
"""Get the latest price for a stock ticker.
The docstring matters more than you'd think. It is what the
model reads to decide whether to call this tool at all.
"""
response = httpx.get(f"https://api.example.com/quote/{ticker}")
return response.json()
@mcp.tool()
def compare_tickers(ticker_a: str, ticker_b: str) -> dict:
"""Compare two tickers on price, market cap and P/E ratio."""
return {
"a": get_current_price(ticker_a),
"b": get_current_price(ticker_b),
}
if __name__ == "__main__":
mcp.run()
claude mcp add finance -- python /path/to/server.py
第三部分:实际差异
对于第三部分:实际差异部分,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比冗长的脚本,更应采用小型、可测试的单元。当某个步骤失败时,故障原因应指向单一责任主体,而非复杂的流程链。需引用实际作为答案依据的段落;没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失所致。
一句话规则
对于“一句话规则”,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 将此阶段视为输入与已验证输出之间的契约。为相关成果命名,定义成功判定标准,并拒绝默许的半完成状态。 需引用实际作为答案依据的段落。没有引用的话,操作员就无法区分是幻觉还是索引缺失导致的错误。 对于“一句话规则”,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个操作员能够审核的位置,无需阅读整个系统结构。
为何“RAG和MCP是一样的吗?”这个问题屡被问及
在探讨“为何‘RAG和MCP是一样的吗?’这个问题屡被问及”时,首先需明确接口规范:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品功能的一部分,而非后续的优化工作。 在调整提示词之前,需先用固定的问题集来衡量召回率。仅仅更换提示词很难解决检索效果不佳的问题。
第四部分:同一助手,两次构建
在完成第4部分“同一助手的两次构建”时,首先列出相关约定:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 建议使用小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词很难改善较差的信息检索效果。
版本A:RAG方法
在采用版本A的RAG方法时,首先需制定明确规范:包括所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,定义成功判定标准,杜绝无声的半完成状态。 在调整提示词之前,先使用固定问题集测试召回率。仅仅更换提示词往往无法改善较差的检索效果。 在采用版本A的RAG方法时,首先需制定明确规范:包括所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 应将配置信息与应用程序代码分开。环境文件、密钥存储及功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
# Building a knowledge base of financial concepts
CORPUS = [
"Market capitalization equals share price multiplied by shares outstanding.",
"The P/E ratio compares share price to earnings per share.",
"Free cash flow is operating cash flow minus capital expenditures.",
"A dividend yield above 6% often signals either a falling share price "
"or an unsustainable payout ratio.",
# ...plus a few thousand more chunks
]
# Index them, then:
answer("Explain what a high dividend yield might indicate")
answer("What is Apple's current dividend yield?")
版本B:MCP方法
版本B:将MCP方法视为可度量的对象来使用效果最佳。在扩大范围之前,先记录一个成功的用例、一个失败案例以及回滚说明。同时文档化正常流程和恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。应将分块策略与检索策略分开,当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
# EODHD publishes two endpoints. v2 uses OAuth, v1 uses an API key.
claude mcp add --transport http eodhd https://mcp.eodhd.com/v2/mcp
版本C:两者兼备,即实际交付的内容
版本C:两者都包含,作为可度量的对象来处理时,实际部署的版本效果最佳。在扩大范围之前,需记录一个成功的案例、一个失败案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
def route(question: str) -> str:
"""Decide which subsystem answers this question."""
# Signals that the question is about live state
live_signals = ["current", "today", "now", "latest", "price", "quote"]
if any(signal in question.lower() for signal in live_signals):
return "mcp" # fetch it
return "rag" # look it up
第5部分:人们常混淆的关联对比
第5部分:人们常混淆的关联对比内容,若将其视为可度量的对象来处理会更为有效。在扩大范围之前,需记录一份最佳范例、一个失败案例以及回滚说明。 将此阶段视为输入与已验证输出之间的契约。为相关成果命名,明确成功标准,杜绝默许的半完成状态。 将分块策略与检索策略分开。当质量指标发生变化时,调整其中一项不应强制重新编写另一项。 第5部分:人们常混淆的关联对比内容,若将其视为可度量的对象来处理会更为有效。在扩大范围之前,需记录一份最佳范例、一个失败案例以及回滚说明。 将配置信息置于应用程序代码之外。环境文件、密钥存储及功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
MCP与API
在比较MCP与API时,应在修改代码之前明确输入参数、各步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 必须引用那些真正作为答案依据的段落。如果没有引用,操作人员就无法区分是虚假信息还是索引缺失导致的问题。
MCP与智能体
在比较MCP与代理模型时,应在修改代码之前明确输入参数、各步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应能指向具体的责任模块,而非复杂的流程链。必须引用实际作为答案依据的段落;没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
RAG与微调
在考虑使用RAG还是微调方案时,应在修改代码之前明确输入内容、各步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需猜测隐藏状态。 应将这一阶段视为输入与经过验证的输出之间的契约。为相关成果命名,设定成功检测标准,并拒绝默许部分完成的情况。 需注明实际作为答案依据的段落。如果没有引用,操作人员就无法区分幻觉内容与索引缺失的问题。 在考虑使用RAG还是微调方案时,应在修改代码之前明确输入内容、各步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需猜测隐藏状态。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个操作人员可以审核的位置,无需查看整个系统结构。
第6部分:选择技术栈
在学习第6部分“选择技术栈”时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品功能的一部分,而非后续需要补充的内容。 在调整提示词之前,先使用固定的问题集来测试检索效果。仅仅更换提示词很难解决检索能力不足的问题。
常见问题
在处理常见问题时,首先写下合同条款:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难解决检索效果不佳的问题。
操作检查清单
对于操作检查清单,应在修改代码之前明确输入内容、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏的状态。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
请引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是幻觉还是索引缺失导致的错误。
需记录每次调用的工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试代理循环会浪费大量时间。
锁定依赖版本,并记录用于运行演示的图像摘要。可重复性比经验知识更重要。
优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤出错时,错误应指向单一责任模块,而非复杂的流程链。
在推广该技术栈之前,先冻结版本,为关键路径保存标准记录,并确认回滚步骤。共享环境需要设置速率限制、租户检查机制,以及明确的密钥轮换负责人。与其展示花哨的一次性演示,不如追求扎实的可靠性。
关于03e5c3844f8b的批处理说明:不要将提供者密钥放入代码仓库,为每个会话设置令牌上限,并将转录内容存储在评估测试用例的旁边,以便后续更换模型时仍能保持可比性。