为什么 MCP、Skill、RAG 能工作?从 Conversation Loop 看现代 Agent 的底层架构

为什么 MCP、Skill、RAG 能工作?从 Conversation Loop 看现代 Agent 的底层架构 前言很多文章介绍 Agent 时都会分别讲MCP、Skill、Function Calling、RAG却很少回答一个更关键的问题MCP、Skill、RAG 为什么能够协同工作它们究竟是如何融入 Agent 的答案其实都藏在 Agent 的执行主线——Conversation Loop中。本文将结合Hermes与OpenClaw的真实源码从Conversation Loop出发逐步串联Tool Calling、Tool Registry、MCP、Skill、MemoryRAG等核心模块完整解析现代 Agent 的底层架构解释一个 Agent 为什么能够不断思考、调用工具、检索知识并最终完成复杂任务。MCP、Skill、MemoryRAG并不是独立工作的能力它们都是 Conversation Loop 中可被 LLM 调度的组成部分。Conversation Loop负责持续执行「LLM 决策 → Tool 调用 → 结果反馈 → 再决策」Tool Registry提供工具目录MCP接入外部能力Skill封装可复用的执行流程MemoryRAG提供长期记忆与知识检索。它们共同构成了现代 Agent 的工具生态而 Conversation Loop 则将这些能力串联起来驱动整个 Agent 持续运行。理解了这条执行主线也就理解了 MCP、Skill、RAG 为什么能够真正融入 Agent。一、整体架构总览先看全局建立坐标感。从这张图可以直接看出所有的箭头最终都回到 Conversation Loop。消息网关是入口工具生态是手臂LLM 是外脑但 Loop 才是心跳。二、Conversation LoopAgent 心脏2.1 一句话讲清楚Agent 本质上就是一个会自己循环思考的程序。每一轮都让 LLM 判断「我是直接回答还是调用工具」如果调用工具就把执行结果放回上下文再让 LLM 思考下一步。代码层面就是while 预算没花光: LLM 看一遍历史消息和所有工具列表 → 决定下一步做什么 如果 LLM 说「回答完毕」 → 退出循环返回用户 如果 LLM 说「调用工具 X参数 Y」 → 执行工具 X → 结果贴回对话 → 继续循环这就是现代 Agent 的核心执行模型。本质上它只是一个不断进行「决策 → 执行 → 反馈 → 再决策」的循环。2.2 循环流程2.3 简化版实现示意以下是conversation_loop.py约 5300 行生产代码的核心逻辑简化示意真实实现有更多的重试、回退、压缩、安全检查等处理# 简化版示意 — 源自 Hermes: agent/conversation_loop.py def run_conversation(agent, user_message): 一个用户 Turn 的完整处理流程 # 1. 构建 Turn 上下文system prompt 历史 用户消息 messages build_turn_context(agent, user_message) # 2. 从 Tool Registry 获取所有可用工具的定义JSON Schema tools, checks agent.tool_registry.get_all_visible_tools() # 3. 迭代预算控制默认最多 60 轮 tool call → API call budget IterationBudget(max_turnsagent.max_turns) while not budget.is_exhausted(): # 4. 上下文太长就压缩 messages compress_if_needed(agent, messages) # 5. 调用 LLM API带重试/fallback/provider 切换 response call_llm_with_retry(agent, messages, tools, budget) # 6. 解析 LLM 返回 if response.finish_reason stop and not response.tool_calls: break # 纯文本 → 完成任务 if response.tool_calls: for tool_call in response.tool_calls: result execute_tool(agent, tool_call) messages.append({ role: tool, tool_call_id: tool_call.id, content: result, }) continue # ← 回到循环顶部LLM 重新审视最新状态 # 7. Turn 结束持久化 session save_session(agent, messages) # ⚠️ 以上是简化示意不是可直接运行的源码。 # 真实文件 ~5300 行额外包含 # - 多层重试API 错误 / 限流 / 超时 # - Provider 自动切换fallback # - 消息压缩/截断/修复 # - 工具参数消毒 安全检查 # - 上下文长度估算 动态调整 # - 异常恢复 审计日志关键点每次 LLM 调用时所有可用工具的定义都以 Function Calling JSON Schema 形式传给 API。LLM 不是「查询数据库」选工具而是根据工具描述做语义匹配工具结果原样追加到 messages 数组。LLM 下一轮能「看到」之前的工具执行结果这形成了情境感知链预算耗尽60 轮是硬上限防止死循环烧 Token2.4 源码中的注释印证以下注释直接来自agent/conversation_loop.py文件头部非虚构 Hermes agent/conversation_loop.py 的架构注释真实文档字符串 核心处理流程 1. build_turn_context() - 构建 System Prompt 历史消息 2. conversation_compression - 超长上下文压缩 3. 调用 LLM API带重试/fallback/provider 切换 4. 解析 response: text → 结束 / tool_calls → 执行 5. tool_executor 执行工具调用分发到 Registry / MCP / Skill 6. 结果追加到 messages回到第 3 步 7. 预算耗尽或完成任务 → save post_hooks 现在你理解了心脏怎么跳。接下来看三个问题LLM 怎么知道有哪些工具可以调→ System Prompt第三章这些工具从哪来的→ Tool Registry第四章外部工具和技能包怎么接进来→ MCP第五章和 Skill第六章说得直接一点——后面介绍的所有模块System Prompt、Tool Registry、MCP、Skill、Memory本质上都在做同一件事让这个 Conversation Loop 更聪明、更安全、更高效地运行。三、System PromptLLM 怎么知道有哪些工具3.1 构建流程Agent 并不是「知道」有什么工具而是把所有的能力写成一个开放式菜单让 LLM 去理解。注意这个构建过程不是在循环内部每次都做的。静态部分人格、工具定义、Skill 目录在 Agent 启动时构建好每次 API 调用时直接引用动态部分Memory 检索结果、Skill 完整指令在 LLM 输出对应的 function_call 后才加载并注入3.2 Hermes工具定义如何传给 LLM# Hermes: agent/conversation_loop.py — 每次 API 调用前简化版 def _build_api_request(agent, messages, tools_entries): api_tools [] for entry in tools_entries: api_tools.append({ type: function, function: { name: entry.name, description: entry.description, # ← LLM 就是靠这个字段做语义匹配 parameters: entry.parameters, # JSON Schema } }) return client.chat.completions.create( modelagent.model, messagesmessages, toolsapi_tools, # ← 所有可用工具的菜单一次性传给 LLM )3.3 OpenClawSkill 目录注入!-- OpenClaw System Prompt 中注入的 Skill 目录 -- available_skills skill nameweather/name descriptionCurrent weather and forecasts with web_fetch, falling back to wttr.in.../description location/opt/homebrew/lib/node_modules/openclaw/skills/weather/SKILL.md/location /skill skill namegithub/name descriptionGitHub CLI for issues, PRs, CI/check logs, comments, reviews, releases.../description location/opt/homebrew/lib/node_modules/openclaw/skills/github/SKILL.md/location /skill skill namehackernews/name descriptionHacker News API for stories and comments. Use when user mentions HN.../description location~/.agents/skills/hackernews/SKILL.md/location /skill /available_skillsLLM 看到hackernews的 description 里有「Hacker News API for stories」当用户问「HN 今天有什么热门」时LLM 做语义匹配 → 输出read(skills/hackernews/SKILL.md)→ Agent 加载完指令后再继续循环。核心原理LLM 不「知道」该用什么工具它只是看到工具的description字段和用户的意图相似就决定调用。所以description写得越好Agent 越「聪明」。四、Tool Registry工具的「货源」4.1 工具的来源与注册4.2 真实代码Hermes 的 Tool Registry# Hermes: tools/registry.py简化版 class ToolRegistry: def __init__(self): self._tools: Dict[str, ToolEntry] {} self._toolset_checks: Dict[str, callable] {} def register(self, name, func, description, parameters, toolset): 注册一个工具到全局注册表 self._tools[name] ToolEntry( namename, funcfunc, descriptiondescription, # ← LLM 做语义匹配的核心字段 parametersparameters, # JSON Schema toolsettoolset, ) def get_all_visible_tools(self): 返回当前上下文下所有可见工具。 只返回 toolset check 通过的工具否则不注入到 System Prompt。 visible [] for name, entry in self._tools.items(): check self._toolset_checks.get(entry.toolset) if check is None or check(): visible.append(entry) return visible def lookup(self, name: str) - Optional[ToolEntry]: 按名称查找工具 return self._tools.get(name) # 工具自动发现扫描 tools/ 目录下所有 Python 模块 def discover_builtin_tools(tools_dir: Path) - List[str]: discovered [] for path in tools_dir.glob(*.py): if _module_registers_tools(path): discovered.append(path.stem) return discovered4.3 工具可用性检查环境感知并非所有工具在所有上下文中都可用。每个 toolset 可以注册一个check_fn# 示例只有当 DISCORD_BOT_TOKEN 存在时discord 工具才可见 tool_registry.register_toolset_check( discord, lambda: bool(os.getenv(DISCORD_BOT_TOKEN)) )在errors.log中的实际日志WARNING tools.registry: check_fn check_discord_tool_requirements returned False WARNING tools.registry: check_fn _browser_cdp_check returned False设计含义不可用的工具不会出现在 System Prompt 的 tools 数组中LLM 根本看不到它也就不会调用它。这是最干净的工具屏蔽方式——不需要 LLM 知道什么「不该用」它压根感知不到。五、MCPModel Context Protocol外部工具的标准化接入MCP 解决的核心问题Agent 不可能为每一个业务系统单独开发 Tool因此需要一种统一的协议来接入外部能力。5.1 架构5.2 配置示例# ~/.hermes/config.yaml mcp_servers: filesystem: command: npx args: [-y, modelcontextprotocol/server-filesystem, /tmp] timeout: 120 github: command: npx args: [-y, modelcontextprotocol/server-github] env: GITHUB_PERSONAL_ACCESS_TOKEN: ghp_... supports_parallel_tool_calls: true remote_api: url: https://my-mcp-server.example.com/mcp headers: Authorization: Bearer sk-... timeout: 1805.3 真实代码Hermes 的 MCP 工具模块# Hermes: tools/mcp_tool.py约 5500 行的生产级实现 MCP (Model Context Protocol) Client Support Architecture: A dedicated background event loop runs in a daemon thread. Each MCP server runs as a long-lived asyncio Task on this loop. Tool call coroutines are scheduled via run_coroutine_threadsafe(). Transport modes: - Stdio: command args → 启动子进程stdin/stdout 通信 - HTTP: url → Streamable HTTP POST - SSE: url transport: sse → Server-Sent Events Features: - Auto-reconnect with exponential backoff最多 5 次 - Environment variable filtering安全过滤敏感 env - Credential stripping in error messages不把 token 泄露给 LLM - Parallel tool call opt-in per server 5.4 OpenClaw 的 MCP 实现// OpenClaw: agent-bundle-mcp-runtime-BcscePMD.js import { Client } from modelcontextprotocol/sdk/client/index.js; import { StreamableHTTPClientTransport } from modelcontextprotocol/sdk/client/streamableHttp.js; import { SSEClientTransport } from modelcontextprotocol/sdk/client/sse.js; function loadEmbeddedAgentMcpConfig(params) { const bundleMcp loadMergedBundleMcpConfig({ workspaceDir: params.workspaceDir, cfg: params.cfg, manifestRegistry: params.manifestRegistry, }); return { mcpServers: bundleMcp.config.mcpServers, diagnostics: bundleMcp.diagnostics, }; } // 启动流程connect → listTools() → 注册到 Tool Catalog → LLM 可调用5.5 MCP 调用完整时序六、Skill 系统可复用的工具组合指令与 MCP提供单个函数调用接口不同Skill 提供的是执行指令和上下文。它告诉 LLM「遇到某类任务时按这个步骤组合调用多个工具」。6.1 Skill 的两种形态形态说明示例目录式 SkillSKILL.md 可执行脚本/配置文件weather— 有 wttr.in 调用逻辑的完整技能包内联指令纯 SKILL.md 文本注入 promptbrowser-automation— 浏览器操作最佳实践指南6.2 加载与触发流程6.3 真实代码Hermes 的 Skill 预处理引擎# Hermes: agent/skill_preprocessing.py # 模板变量替换\{(HERMES_SKILL_DIR|HERMES_SESSION_ID)\}) # 内联 Shell!date %Y-%m-%d → 可在 prompt 中直接执行命令并注入结果 _INLINE_SHELL_RE re.compile(r!([^\n])) def substitute_template_vars(content, skill_dir, session_id): 替换 SKILL.md 中的模板变量 def _replace(match): token match.group(1) if token HERMES_SKILL_DIR and skill_dir: return str(skill_dir) return match.group(0) return _SKILL_TEMPLATE_RE.sub(_replace, content) def run_inline_shell(command, cwd, timeout): 执行 SKILL.md 中的内联 shell 命令。 例如 !date %Y-%m-%d → 注入 2026-07-14 失败不抛异常返回 [inline-shell error: ...] 标记 completed subprocess.run( [bash, -c, command], capture_outputTrue, textTrue, timeoutmax(1, int(timeout)), ) return (completed.stdout or ).rstrip(\n)6.4 Skill 安全扫描安装前防线# Hermes: tools/skills_guard.py Skills Guard — 外部 Skill 的安全扫描器 Trust levels: - builtin: 随 Hermes 发布永不扫描始终信任 - trusted: 来自 openai/skills、anthropics/skills、NVIDIA/skills - community: 其他来源。有发现即阻止除非 --force TRUSTED_REPOS { openai/skills, anthropics/skills, NVIDIA/skills, } # 正则威胁检测模式 THREAT_PATTERNS [ (curl.*\\|.*bash, remote-pipe, critical, exfiltration), (crontab\\s-, crontab-edit, high, persistence), (rm\\s-rf\\s/, rm-root, critical, destructive), (nc\\s.*-e, netcat-shell, critical, network), ]6.5 OpenClaw 的 Skill 选择策略!-- OpenClaw System Prompt 中的 Skill 目录 -- available_skills skill nameweather/name descriptionCurrent weather and forecasts with web_fetch, falling back to wttr.in.../description /skill /available_skills触发流程用户说「今天天气怎么样」→ LLM 匹配 weather skill → Agent 执行 read(skills/weather/SKILL.md) → 按指令调用 web_fetch(wttr.in) → 返回结果七、Memory / RAG长期记忆与知识检索7.1 记忆的完整生命周期RAG 不只是「检索」完整的记忆系统包含写入和检索两个方向关键设计写入和检索是解耦的——Agent 不直接在对话中「写记忆」而是在每次 Turn 结束后通过 post_turn_hook 持久化到文件。后续对话中LLM 通过memory_search工具或自动注入 context block检索这些记忆。7.2 知识库检索架构7.3 真实代码Hermes 的 Memory Manager# Hermes: agent/memory_manager.py def build_memory_context_block(agent, user_message: str, max_chars8000) - str: 检索相关记忆构建上下文块注入到对话中 results agent.memory_store.search(queryuser_message, top_k10) if not results: return context_lines [memory_context] for result in results: if len(\n.join(context_lines)) max_chars: break context_lines.append( fmemory score{result.score:.2f}{result.text}/memory ) context_lines.append(/memory_context) return \n.join(context_lines)7.4 RAG 在 Conversation Loop 中的位置关键设计memory_search本身也是 Tool Registry 中的一个工具LLM 在循环中自主决定「我需要先查一下历史记忆」然后调用它。检索结果作为上下文追加到 messages下一轮 LLM 就能基于记忆生成回答。7.5 OpenClaw 的 Memory Search 工具定义八、全链路端到端一条消息的完整旅程以「帮我查一下 GitHub 上 openclaw 项目的最近 3 个 Issue」为例展示完整的 Conversation Loop 流转代码路径对照1. 消息到达 → hermes_cli/tui_gateway/server.py 2. 创建 Session 启动 Loop → agent/conversation_loop.py::run_conversation() 3. 构建上下文 → agent/turn_context.py agent/memory_manager.py 4. 调用 LLM → agent/conversation_loop.py::call_llm_with_retry() 5. 解析 function_call → tools/registry.py::lookup() → Built-in: 直接执行函数 → MCP: tools/mcp_tool.py → 转发到 MCP Server → Skill: agent/skill_utils.py → 加载 SKILL.md 6. 追加结果 回到步骤 4最多 60 轮九、核心速查对比总结 关键洞察9.1 Hermes vs OpenClaw对比维度HermesOpenClaw定位大而全的 Agent 平台桌面 GUI 网关 多平台消息轻量 Agent 框架命令行 可嵌入语言Python 3.11TypeScript (Node.js)Conversation Loopagent/conversation_loop.py(~5300 行)embedded-agent-BgF2MOkH.js(dist 打包)Tool 系统tools/registry.py— 类继承 装饰器自动注册agent-tools-XUrUI5bQ.js— Tool Catalog CompactionTool 发现自动扫描tools/*.py MCP listTools Skill 元数据显式注册 MCP listTools Skill 清单MCP 支持原生支持stdio / HTTP / SSE守护线程原生支持stdio / HTTP / SSESkill 系统SKILL.md 模板变量 内联 Shell 安全扫描 信任分级SKILL.md description 注入Memory / RAGagent/memory_manager.py— 向量检索 上下文注入memory_searchTool — 语义搜索 MEMORY.md消息平台微信 / Discord / Telegram / Slack / Signal / QQ 等WebChat / Discord / Telegram / Signal 等安全Skill 来源信任分级 MCP 凭证脱敏 危险命令拦截 可用性检查Skill 可用性检查 命令审批配置复杂度高~/.hermes/config.yaml 的完整生态配置低Gateway config 工作区文件适用场景个人全能助理、多平台部署嵌入式 Agent、轻量部署、API 集成9.2 关键洞察速查问题答案Agent 的本质是什么一个带工具的白盒 while 循环「LLM 决策 → Tool 调用 → 结果反馈 → LLM 再决策」Agent 怎么知道该调哪个工具不「知道」。LLM 做语义匹配——工具 description 和用户意图越接近越容易被调用MCP 和 Skill 有什么区别MCP 标准化外部函数接口一个工具一件事Skill 指令包多个工具如何组合RAG 什么时候触发在 Conversation Loop 内部LLM 自主决定调用memory_search工具 → 检索 → 结果注入上下文 → 继续循环记忆从哪来每次 Turn 结束后 Agent 自动写入memory/YYYY-MM-DD.md周期性提炼到MEMORY.md再通过 Embedding 建立向量索引一个 Turn 最多调多少次 LLMHermes 默认max_turns60即最多 60 轮 tool call ↔ API call工具不可用时怎么办check_fn 返回 False → 工具不注入到 tools 数组 → LLM 看不到 → 根本不会调用Hermes 和 OpenClaw 最大区别Hermes 是「大而全的平台」桌面 网关 N 平台OpenClaw 是「轻量可嵌入 Agent」十、核心设计模式总结十一、一张图看懂 Agent核心公式Conversation Loop Tool Calling Memory 现代 Agent 的全部秘密从上往下读用户提问进入 Loop → Loop 调用 Prompt菜单、Memory记忆、Tools工具→ 工具分为 Built-in / MCP / Skill → 结果回到 Loop → 完成业务目标。整篇文章本质上就是这张图从上到下的逐层展开。十二、写在最后无论是 Hermes、OpenClaw还是 Claude Code、Codex、Gemini CLI、Cursor Agent它们底层几乎都遵循同一种架构Conversation Loop Tool Calling Memory不同产品真正的差异不在于有没有 MCP而在于——Loop 如何组织单轮 vs 多轮、同步 vs 异步、预算策略是什么Tool 如何管理装饰器自动注册 vs 显式注册、可用性检查粒度多细Memory 如何利用文件级检索 vs 向量数据库、注入时机在哪一环以及围绕这些能力构建出的工程体系安全扫描、平台适配、会话持久化、多 Agent 协作理解了 Conversation Loop、Tool Calling 和 Memory就理解了现代 Agent 的核心设计其余能力如 Planning、多 Agent 协作、Workflow 等大多是建立在这一基础之上的。结语现代 Agent 看起来能力越来越多MCP、Skill、Memory、Planning、Workflow……但当真正读完源码之后会发现它们并不是彼此独立的能力而都是围绕Conversation Loop这一条执行主线构建出来的。理解了 Conversation Loop也就理解了 MCP、Skill、RAG 为什么能够真正融入 Agent理解了 Tool Registry、Tool Calling 与 Memory 的协作方式也就理解了现代 Agent 为什么能够持续思考、持续调用工具并最终完成复杂任务。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】