ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MCP+RAG 技术栈实战:构建服务研发环境的 AI Agent 应用

MCP+RAG 技术栈实战:构建服务研发环境的 AI Agent 应用 写在前面这不是一篇“Hello World”式的概念科普。我们将从零搭建一个真正能用的研发环境 AI Agent它能理解你项目的私有文档、调用本地工具链、并像一位熟悉你技术栈的同事一样回答问题。如果你受够了通用 AI 在“我们内部文档”和“实际构建命令”上的胡言乱语这篇文章适合你。为什么是 MCP RAG大模型有两个根本性缺陷知识冻结和无法行动。RAG 解决前者——把外部知识检索进来让模型“有据可依”MCP 解决后者——给模型装上标准化的“手”让它能真正调用工具。但很多教程只讲其一。单独的 RAG 只能读不能做单独的 MCP 只能做不能“懂”。服务研发环境是一个典型场景你需要 Agent 先理解“我们公司的服务注册规范”然后调用 kubectl 或内部 CLI 执行操作。这是 RAG MCP 的天然协作场景。两者的分工清晰RAG 负责“是什么”项目文档、API 规范、运维手册、历史故障记录MCP 负责“做什么”读文件、查数据库、调 API、执行命令架构设计三层分离text┌─────────────────────────────────────────────┐│ AI Agent (客户端) ││ LLM 决策 · 工具选择 · 多步推理 │└──────────────┬──────────────────────────────┘│ MCP Protocol (JSON-RPC)┌──────────────▼──────────────────────────────┐│ MCP Server Layer ││ ┌─────────────┐ ┌──────────────────────┐ ││ │ RAG Tool │ │ DevTools Tools │ ││ │ search_docs │ │ read_file, run_cmd │ ││ │ get_page │ │ query_db, call_api │ ││ └─────────────┘ └──────────────────────┘ │└──────────────┬──────────────────────────────┘│┌──────────────▼──────────────────────────────┐│ Data Infra Layer ││ Vector DB (Qdrant) · Graph DB (Neo4j) ││ Filesystem · Database · Internal APIs │└─────────────────────────────────────────────┘这个架构的关键决策是RAG 不是独立于 Agent 的外部系统而是作为 MCP Tool 暴露给 Agent。Agent 自己决定“这个问题需要先查文档还是直接调工具”而不是被硬编码的流程约束。实战三步搭建第一步准备 RAG 检索能力服务研发环境的知识库通常包含Markdown 文档、OpenAPI 规范、代码注释、历史 Issue。向量检索是基础但对于研发场景图关系检索往往更关键。考虑一个实际问题“修改 UserService 的接口会影响哪些下游服务”纯向量检索只能找到“相似”的文档无法回答“影响链”问题。GraphRAG 通过实体关系图NEXT_PAGE、RELATED_TO、DEPENDS_ON可以沿关系链遍历。我们采用 混合检索向量召回保证语义覆盖图关系扩展保证上下文完整性。pythonrag_pipeline.pyfrom qdrant_client import QdrantClientfrom neo4j import GraphDatabaseclass DevRAGPipeline:definit(self, qdrant_url, neo4j_uri):self.vector_db QdrantClient(urlqdrant_url)self.graph_db GraphDatabase.driver(neo4j_uri)def hybrid_search(self, query: str, top_k: int 5): # 1. 向量检索 vector_hits self.vector_db.search( collection_namedev_docs, query_vectorself.embed(query), limittop_k ) # 2. 图关系扩展查找关联文档 expanded [] for hit in vector_hits: related self.graph_db.run( MATCH (d:Doc {id: $id})-[:RELATED_TO*1..2]-(r) RETURN r.id, r.content LIMIT 3, idhit.id ) expanded.extend(related) return vector_hits expanded关键设计Chunk 策略要适配研发文档的特点。代码块、命令示例、配置片段不应该被文本分割器切碎。建议按 Markdown 标题层级切分代码块作为不可分割单元处理。第二步封装 MCP ServerMCP 的核心价值是标准化——Agent 不需要知道你的 RAG 是向量还是图不需要知道文件系统是本地还是远程它只需要看到工具描述和参数 schema。我们创建两个 MCP Server一个负责检索RAG Server一个负责操作DevTools Server。分离的好处是权限边界清晰检索服务可以无状态、无副作用地运行而操作服务需要严格的作用域控制和审计。pythonrag_mcp_server.pyfrom mcp.server.fastmcp import FastMCPfrom rag_pipeline import DevRAGPipelinemcp FastMCP(“Dev RAG Server”)pipeline DevRAGPipeline(qdrant_url“http://localhost:6333”,neo4j_uri“bolt://localhost:7687”)mcp.tool()async def search_docs(query: str, top_k: int 5) - str:“”“搜索项目文档、API 规范和运维手册。适用场景需要了解项目约定、接口定义、配置说明时使用。”“”results pipeline.hybrid_search(query, top_k)return format_results(results)mcp.tool()async def get_document_context(doc_id: str, page: int 1) - str:“”“获取指定文档的完整上下文前后页 关联文档。适用场景search_docs 返回的片段不够完整需要展开阅读时使用。”“”return pipeline.get_context(doc_id, page)ifname “main”:mcp.run(transport“stdio”)DevTools Server 需要更严格的约束。参考生产级 MCP 工具集的设计pythondevtools_mcp_server.pyimport subprocessfrom pathlib import Pathfrom mcp.server.fastmcp import FastMCPmcp FastMCP(“DevTools Server”)ALLOWED_ROOT Path(“/workspace/projects”)ALLOWED_COMMANDS {“git”, “kubectl”, “docker”, “make”, “npm”, “go”}mcp.tool()async def read_file(path: str) - str:“”“读取项目文件内容。仅限 /workspace/projects 目录下。”“”resolved (ALLOWED_ROOT / path).resolve()if not str(resolved).startswith(str(ALLOWED_ROOT)):raise PermissionError(“Path outside allowed scope”)return resolved.read_text()mcp.tool()async def run_command(command: str, args: list[str], cwd: str “.”) - str:“”“执行开发命令。仅允许预定义的安全命令。”“”if command not in ALLOWED_COMMANDS:raise PermissionError(fCommand ‘{command}’ not in allowlist)# 使用 spawn无 shell结构化上杜绝注入result subprocess.run([command] args,cwdALLOWED_ROOT / cwd,capture_outputTrue,textTrue,timeout30)return result.stdout or result.stderr这里体现了 MCP 安全设计的核心原则工具代表任意代码执行必须获得用户明确授权。我们的做法是路径作用域 命令白名单 无 shell 调用三者缺一不可。第三步组装 AgentAgent 端的核心逻辑是让 LLM 自主决策调用哪些工具。我们不硬编码“先查文档再执行”的流程而是通过工具描述引导模型。pythonagent.pyimport asynciofrom mcp import ClientSession, StdioServerParametersfrom mcp.client.stdio import stdio_clientfrom langchain_openai import ChatOpenAIfrom langchain.agents import create_tool_calling_agent, AgentExecutorasync def build_agent():# 连接两个 MCP Serverrag_params StdioServerParameters(command“python”, args[“rag_mcp_server.py”])dev_params StdioServerParameters(command“python”, args[“devtools_mcp_server.py”])async with stdio_client(rag_params) as (rag_r, rag_w), \ stdio_client(dev_params) as (dev_r, dev_w): async with ClientSession(rag_r, rag_w) as rag_session, \ ClientSession(dev_r, dev_w) as dev_session: await rag_session.initialize() await dev_session.initialize() # 统一获取工具 rag_tools await rag_session.list_tools() dev_tools await dev_session.list_tools() all_tools convert_to_langchain_tools( rag_tools.tools dev_tools.tools, [rag_session, dev_session] ) llm ChatOpenAI(modelgpt-4o, temperature0) agent create_tool_calling_agent( llm, all_tools, promptSYSTEM_PROMPT ) return AgentExecutor( agentagent, toolsall_tools, verboseTrue, max_iterations10 )SYSTEM_PROMPT “”你是服务研发环境助手。工作原则回答项目相关问题时优先使用 search_docs 检索文档不要凭训练数据猜测。需要执行操作时先确认操作内容与文档规范一致再调用工具。如果文档检索结果不完整使用 get_document_context 展开上下文。执行修改性操作前向用户确认操作范围。工具使用优先级检索 → 理解 → 执行。“”关键设计决策temperature0。研发场景对确定性要求极高同样的查询不应该产生不同的工具调用决策。踩坑与调优坑一MCP 工具的“过度调用”。Agent 看到 run_command 就想执行即使问题只需要检索。解法在系统 prompt 中强调“检索优先”并在工具描述中明确适用场景“仅当用户明确要求执行操作时使用”。坑二RAG 检索结果的格式。向量检索返回的是 chunk但 Agent 需要的是可读的上下文。我们的做法MCP Tool 返回时做一层格式化包含来源文档、页码、相关性分数让 Agent 能判断“够不够用”。坑三图数据库的查询性能。RELATED_TO*1…2 在大型项目图上可能爆炸。限制遍历深度为 2 跳并对高频查询做缓存。坑四多 MCP Server 的连接管理。生产环境建议使用 HTTP transport 而非 stdio便于集中管理和认证。我们在开发阶段用 stdio 简化调试部署时切换到 HTTP OAuth。效果评估在一个中等规模的微服务项目~50 个服务、~200 份文档上部署后我们观察到检索准确率混合检索比纯向量检索在“依赖关系”类查询上提升约 40%工具调用正确率通过 system prompt 引导后误用 run_command 的情况从 15% 降至 3%响应延迟RAG 检索 Agent 推理的中位数约 4.2s可接受结语MCP RAG 的组合之所以强大在于它们解决了不同层面的问题RAG 让 Agent 的“知识”可更新、可追溯MCP 让 Agent 的“能力”可扩展、可约束。两者都是协议层面的标准化——RAG 标准化了“知识注入”的流程MCP 标准化了“工具调用”的接口。对于服务研发环境这个场景这套架构的价值不在于“炫技”而在于让 AI 真正进入研发工作流。当一个 Agent 能理解你的项目规范、调用你的工具链、并且在权限边界内安全运行它才从一个“聪明的聊天机器人”变成一个可用的工程工具。
返回列表