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

作者:吴佳浩Alben日期:2026/7/15

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


作 者:吴佳浩Alben

撰稿时间:2026.7.10

更新时间:2026.7.13


前言

很多文章介绍 Agent 时,都会分别讲 MCP、Skill、Function Calling、RAG,却很少回答一个更关键的问题:

MCP、Skill、RAG 为什么能够协同工作?它们究竟是如何融入 Agent 的?

答案,其实都藏在 Agent 的执行主线——Conversation Loop 中。

本文将结合 HermesOpenClaw 的真实源码,从 Conversation Loop 出发,逐步串联 Tool Calling、Tool Registry、MCP、Skill、Memory(RAG) 等核心模块,完整解析现代 Agent 的底层架构,解释一个 Agent 为什么能够不断思考、调用工具、检索知识,并最终完成复杂任务。

MCP、Skill、Memory(RAG)并不是独立工作的能力,它们都是 Conversation Loop 中可被 LLM 调度的组成部分。

Conversation Loop 负责持续执行 「LLM 决策 → Tool 调用 → 结果反馈 → 再决策」Tool Registry 提供工具目录;MCP 接入外部能力;Skill 封装可复用的执行流程;Memory(RAG) 提供长期记忆与知识检索。

它们共同构成了现代 Agent 的工具生态,而 Conversation Loop 则将这些能力串联起来,驱动整个 Agent 持续运行。理解了这条执行主线,也就理解了 MCP、Skill、RAG 为什么能够真正融入 Agent。


一、整体架构总览

先看全局,建立坐标感。

从这张图可以直接看出:所有的箭头最终都回到 Conversation Loop。消息网关是入口,工具生态是手臂,LLM 是外脑,但 Loop 才是心跳。


二、Conversation Loop:Agent 心脏

2.1 一句话讲清楚

Agent 本质上就是一个会自己循环思考的程序。每一轮都让 LLM 判断:「我是直接回答,还是调用工具?」如果调用工具,就把执行结果放回上下文,再让 LLM 思考下一步。

代码层面就是:

1    while 预算没花光:
2        LLM 看一遍历史消息和所有工具列表  决定下一步做什么
3        如果 LLM 说「回答完毕」  退出循环,返回用户
4        如果 LLM 说「调用工具 X(参数 Y)」  执行工具 X  结果贴回对话  继续循环
5

这就是现代 Agent 的核心执行模型。本质上,它只是一个不断进行「决策 → 执行 → 反馈 → 再决策」的循环。

2.2 循环流程

2.3 简化版实现示意

以下是 conversation_loop.py(约 5300 行生产代码)的核心逻辑简化示意,真实实现有更多的重试、回退、压缩、安全检查等处理:

1# 简化版示意  源自 Hermes: agent/conversation_loop.py
2def run_conversation(agent, user_message):
3    """一个用户 Turn 的完整处理流程"""
4    
5    # 1. 构建 Turn 上下文(system prompt + 历史 + 用户消息)
6    messages = build_turn_context(agent, user_message)
7    
8    # 2.  Tool Registry 获取所有可用工具的定义(JSON Schema)
9    tools, checks = agent.tool_registry.get_all_visible_tools()
10    
11    # 3. 迭代预算控制(默认最多 60  tool call  API call)
12    budget = IterationBudget(max_turns=agent.max_turns)
13    
14    while not budget.is_exhausted():
15        # 4. 上下文太长就压缩
16        messages = compress_if_needed(agent, messages)
17        
18        # 5. 调用 LLM API(带重试/fallback/provider 切换)
19        response = call_llm_with_retry(agent, messages, tools, budget)
20        
21        # 6. 解析 LLM 返回
22        if response.finish_reason == "stop" and not response.tool_calls:
23            break  # 纯文本  完成任务
24        
25        if response.tool_calls:
26            for tool_call in response.tool_calls:
27                result = execute_tool(agent, tool_call)
28                messages.append({
29                    "role": "tool",
30                    "tool_call_id": tool_call.id,
31                    "content": result,
32                })
33            continue  #  回到循环顶部,LLM 重新审视最新状态
34    
35    # 7. Turn 结束:持久化 session
36    save_session(agent, messages)
37
38# ⚠️ 以上是简化示意,不是可直接运行的源码。
39# 真实文件 ~5300 行,额外包含:
40#   - 多层重试(API 错误 / 限流 / 超时)
41#   - Provider 自动切换(fallback)
42#   - 消息压缩/截断/修复
43#   - 工具参数消毒 & 安全检查
44#   - 上下文长度估算 & 动态调整
45#   - 异常恢复 & 审计日志
46

关键点

  • 每次 LLM 调用时,所有可用工具的定义都以 Function Calling JSON Schema 形式传给 API。LLM 不是「查询数据库」选工具,而是根据工具描述做语义匹配
  • 工具结果原样追加到 messages 数组。LLM 下一轮能「看到」之前的工具执行结果,这形成了情境感知链
  • 预算耗尽(60 轮)是硬上限,防止死循环烧 Token

2.4 源码中的注释印证

以下注释直接来自 agent/conversation_loop.py 文件头部(非虚构):

1"""
2Hermes agent/conversation_loop.py 的架构注释(真实文档字符串)
3
4核心处理流程:
51. build_turn_context()      - 构建 System Prompt + 历史消息
62. conversation_compression   - 超长上下文压缩
73. 调用 LLM API(带重试/fallback/provider 切换)
84. 解析 response: text  结束 / tool_calls  执行
95. tool_executor 执行工具调用(分发到 Registry / MCP / Skill)
106. 结果追加到 messages,回到第 3 
117. 预算耗尽或完成任务  save + post_hooks
12"""
13

现在你理解了心脏怎么跳。接下来看三个问题:

  1. LLM 怎么知道有哪些工具可以调? → System Prompt(第三章)
  2. 这些工具从哪来的? → Tool Registry(第四章)
  3. 外部工具和技能包怎么接进来? → MCP(第五章)和 Skill(第六章)

说得直接一点——后面介绍的所有模块(System Prompt、Tool Registry、MCP、Skill、Memory),本质上都在做同一件事:让这个 Conversation Loop 更聪明、更安全、更高效地运行。


三、System Prompt:LLM 怎么知道有哪些工具?

3.1 构建流程

Agent 并不是「知道」有什么工具,而是把所有的能力写成一个开放式菜单让 LLM 去理解。

1sequenceDiagram
2    participant SP as System Prompt Builder
3    participant CFG as Config & 人格
4    participant REG as Tool Registry
5    participant MCP as MCP Manager
6    participant SKILL as Skill Loader
7    participant MEM as Memory Manager
8    participant LLM
9
10    SP->>CFG: 读取人格 (SOUL.md) + 行为规则 (AGENTS.md)
11    SP->>REG: 获取所有内置工具的定义
12    SP->>MCP: 获取已连接 MCP Server 的工具列表
13    SP->>SKILL: 扫描已安装 Skill  name + description
14    SP->>MEM: 构建记忆上下文块(RAG 检索结果)
15    SP->>LLM: 组合完整的 System Prompt + 历史消息
16

注意:这个构建过程不是在循环内部每次都做的。

  • 静态部分(人格、工具定义、Skill 目录)在 Agent 启动时构建好,每次 API 调用时直接引用
  • 动态部分(Memory 检索结果、Skill 完整指令)在 LLM 输出对应的 function_call 后才加载并注入

3.2 Hermes:工具定义如何传给 LLM

1# Hermes: agent/conversation_loop.py  每次 API 调用前(简化版)
2def _build_api_request(agent, messages, tools_entries):
3    api_tools = []
4    for entry in tools_entries:
5        api_tools.append({
6            "type": "function",
7            "function": {
8                "name": entry.name,
9                "description": entry.description,  #  LLM 就是靠这个字段做语义匹配
10                "parameters": entry.parameters,    # JSON Schema
11            }
12        })
13
14    return client.chat.completions.create(
15        model=agent.model,
16        messages=messages,
17        tools=api_tools,  #  所有可用工具的菜单,一次性传给 LLM
18    )
19

3.3 OpenClaw:Skill 目录注入

1<!-- OpenClaw System Prompt 中注入的 Skill 目录 -->
2<available_skills>
3  <skill>
4    <name>weather</name>
5    <description>Current weather and forecasts with web_fetch, falling back to wttr.in...</description>
6    <location>/opt/homebrew/lib/node_modules/openclaw/skills/weather/SKILL.md</location>
7  </skill>
8  <skill>
9    <name>github</name>
10    <description>GitHub CLI for issues, PRs, CI/check logs, comments, reviews, releases...</description>
11    <location>/opt/homebrew/lib/node_modules/openclaw/skills/github/SKILL.md</location>
12  </skill>
13  <skill>
14    <name>hackernews</name>
15    <description>Hacker News API for stories and comments. Use when user mentions HN...</description>
16    <location>~/.agents/skills/hackernews/SKILL.md</location>
17  </skill>
18</available_skills>
19

LLM 看到 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

1# Hermes: tools/registry.py(简化版)
2class ToolRegistry:
3    def __init__(self):
4        self._tools: Dict[str, ToolEntry] = {}
5        self._toolset_checks: Dict[str, callable] = {}
6
7    def register(self, name, func, description, parameters, toolset):
8        """注册一个工具到全局注册表"""
9        self._tools[name] = ToolEntry(
10            name=name,
11            func=func,
12            description=description,  #  LLM 做语义匹配的核心字段
13            parameters=parameters,    # JSON Schema
14            toolset=toolset,
15        )
16
17    def get_all_visible_tools(self):
18        """
19        返回当前上下文下所有可见工具。
20        只返回 toolset check 通过的工具(否则不注入到 System Prompt)。
21        """
22        visible = []
23        for name, entry in self._tools.items():
24            check = self._toolset_checks.get(entry.toolset)
25            if check is None or check():
26                visible.append(entry)
27        return visible
28
29    def lookup(self, name: str) -> Optional[ToolEntry]:
30        """按名称查找工具"""
31        return self._tools.get(name)
32
33
34# 工具自动发现:扫描 tools/ 目录下所有 Python 模块
35def discover_builtin_tools(tools_dir: Path) -> List[str]:
36    discovered = []
37    for path in tools_dir.glob("*.py"):
38        if _module_registers_tools(path):
39            discovered.append(path.stem)
40    return discovered
41

4.3 工具可用性检查(环境感知)

并非所有工具在所有上下文中都可用。每个 toolset 可以注册一个 check_fn

1# 示例:只有当 DISCORD_BOT_TOKEN 存在时,discord 工具才可见
2tool_registry.register_toolset_check(
3    "discord",
4    lambda: bool(os.getenv("DISCORD_BOT_TOKEN"))
5)
6

errors.log 中的实际日志:

1    WARNING tools.registry: check_fn check_discord_tool_requirements returned False
2    WARNING tools.registry: check_fn _browser_cdp_check returned False
3

设计含义:不可用的工具不会出现在 System Prompt 的 tools 数组中,LLM 根本看不到它,也就不会调用它。这是最干净的工具屏蔽方式——不需要 LLM 知道什么「不该用」,它压根感知不到。


五、MCP(Model Context Protocol):外部工具的标准化接入

MCP 解决的核心问题:Agent 不可能为每一个业务系统单独开发 Tool,因此需要一种统一的协议来接入外部能力。

5.1 架构

5.2 配置示例

1# ~/.hermes/config.yaml
2mcp_servers:
3  filesystem:
4    command: "npx"
5    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
6    timeout: 120
7
8  github:
9    command: "npx"
10    args: ["-y", "@modelcontextprotocol/server-github"]
11    env:
12      GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..."
13    supports_parallel_tool_calls: true
14
15  remote_api:
16    url: "https://my-mcp-server.example.com/mcp"
17    headers:
18      Authorization: "Bearer sk-..."
19    timeout: 180
20

5.3 真实代码:Hermes 的 MCP 工具模块

1# Hermes: tools/mcp_tool.py(约 5500 行的生产级实现)
2"""
3MCP (Model Context Protocol) Client Support
4
5Architecture:
6    A dedicated background event loop runs in a daemon thread.
7    Each MCP server runs as a long-lived asyncio Task on this loop.
8    Tool call coroutines are scheduled via `run_coroutine_threadsafe()`.
9
10Transport modes:
11    - Stdio:    command + args  启动子进程,stdin/stdout 通信
12    - HTTP:     url  Streamable HTTP POST
13    - SSE:      url + transport: sse  Server-Sent Events
14
15Features:
16    - Auto-reconnect with exponential backoff(最多 5 次)
17    - Environment variable filtering(安全过滤敏感 env)
18    - Credential stripping in error messages(不把 token 泄露给 LLM)
19    - Parallel tool call opt-in per server
20"""
21

5.4 OpenClaw 的 MCP 实现

1// OpenClaw: agent-bundle-mcp-runtime-BcscePMD.js
2import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
5
6function loadEmbeddedAgentMcpConfig(params) {
7    const bundleMcp = loadMergedBundleMcpConfig({
8        workspaceDir: params.workspaceDir,
9        cfg: params.cfg,
10        manifestRegistry: params.manifestRegistry,
11    });
12    return {
13        mcpServers: bundleMcp.config.mcpServers,
14        diagnostics: bundleMcp.diagnostics,
15    };
16}
17
18// 启动流程:connect  listTools()  注册到 Tool Catalog  LLM 可调用
19

5.5 MCP 调用完整时序

1sequenceDiagram
2    participant U as 用户
3    participant A as Agent
4    participant MC as MCP Client
5    participant MS as MCP Server
6    participant LLM
7
8    Note over MC,MS: 启动阶段  建立连接 & 发现工具
9    MC->>MS: connect(stdio / http)
10    MC->>MS: listTools()
11    MS-->>MC: [{name:&#34;list_files&#34;, description:&#34;List files in dir&#34;}, ...]
12    MC->>A: 注册 MCP 工具到 Tool Registry
13
14    Note over U,LLM: 运行时  用户提问促发调用
15    U->>A: &#34;帮我读一下 /tmp/config.json&#34;
16    A->>LLM: messages + tools(含 mcp__filesystem__read_file)
17    LLM-->>A: function_call: mcp__filesystem__read_file(path=&#34;/tmp/config.json&#34;)
18    A->>MC: callTool(&#34;filesystem&#34;, &#34;read_file&#34;, {path:&#34;/tmp/config.json&#34;})
19    MC->>MS: tools/call (JSON-RPC)
20    MS-->>MC: {content: [{&#34;type&#34;:&#34;text&#34;,&#34;text&#34;:&#34;{'key':'value'}&#34;}]}
21    MC-->>A: 工具执行结果
22    A->>LLM: 追加 tool result  生成回答
23    LLM-->>A: &#34;/tmp/config.json 的内容是...&#34;
24    A-->>U: 最终回答
25

六、Skill 系统:可复用的工具组合指令

与 MCP(提供单个函数调用接口)不同,Skill 提供的是执行指令和上下文。它告诉 LLM「遇到某类任务时,按这个步骤组合调用多个工具」。

6.1 Skill 的两种形态

形态说明示例
目录式 SkillSKILL.md + 可执行脚本/配置文件weather — 有 wttr.in 调用逻辑的完整技能包
内联指令纯 SKILL.md 文本注入 promptbrowser-automation — 浏览器操作最佳实践指南

6.2 加载与触发流程

6.3 真实代码:Hermes 的 Skill 预处理引擎

1# Hermes: agent/skill_preprocessing.py
2
3# 模板变量替换:${HERMES_SKILL_DIR}  实际路径
4_SKILL_TEMPLATE_RE = re.compile(r"\$\{(HERMES_SKILL_DIR|HERMES_SESSION_ID)\}")
5
6# 内联 Shell:![`date +%Y-%m-%d`](https://xplanc.org/primers/document/zh/10.Bash/90.%E5%B8%AE%E5%8A%A9%E6%89%8B%E5%86%8C/EX.date.md)  可在 prompt 中直接执行命令并注入结果
7_INLINE_SHELL_RE = re.compile(r"!`([^`\n]+)`")
8
9def substitute_template_vars(content, skill_dir, session_id):
10    """替换 SKILL.md 中的模板变量"""
11    def _replace(match):
12        token = match.group(1)
13        if token == "HERMES_SKILL_DIR" and skill_dir:
14            return str(skill_dir)
15        return match.group(0)
16    return _SKILL_TEMPLATE_RE.sub(_replace, content)
17
18def run_inline_shell(command, cwd, timeout):
19    """
20    执行 SKILL.md 中的内联 shell 命令。
21    例如 `!`date +%Y-%m-%d``  注入 "2026-07-14"
22    失败不抛异常,返回 [inline-shell error: ...] 标记
23    """
24    completed = subprocess.run(
25        ["bash", "-c", command],
26        capture_output=True, text=True,
27        timeout=max(1, int(timeout)),
28    )
29    return (completed.stdout or "").rstrip("\n")
30

6.4 Skill 安全扫描(安装前防线)

1# Hermes: tools/skills_guard.py
2"""
3Skills Guard  外部 Skill 的安全扫描器
4
5Trust levels:
6  - builtin:    Hermes 发布,永不扫描,始终信任
7  - trusted:   来自 openai/skills、anthropics/skills、NVIDIA/skills
8  - community: 其他来源。有发现即阻止,除非 --force
9"""
10
11TRUSTED_REPOS = {
12    "openai/skills", "anthropics/skills", "NVIDIA/skills",
13}
14
15# 正则威胁检测模式
16THREAT_PATTERNS = [
17    ("curl.*\\|.*bash",     "remote-pipe",   "critical", "exfiltration"),
18    ("crontab\\s+-",        "crontab-edit",  "high",     "persistence"),
19    ("rm\\s+-rf\\s+/",      "rm-root",       "critical", "destructive"),
20    ("nc\\s+.*-e",          "netcat-shell",  "critical", "network"),
21]
22

6.5 OpenClaw 的 Skill 选择策略

1<!-- OpenClaw System Prompt 中的 Skill 目录 -->
2<available_skills>
3  <skill>
4    <name>weather</name>
5    <description>Current weather and forecasts with web_fetch, falling back to wttr.in...</description>
6  </skill>
7</available_skills>
8

触发流程:用户说「今天天气怎么样」→ 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)检索这些记忆。

1flowchart TB
2    subgraph 离线索引
3        DOCS[文档 / 记忆文件] --> CHUNK[文本分块]
4        CHUNK --> EMBED[Embedding 向量化]
5        EMBED --> STORE[(向量数据库<br/>Chroma / FAISS / local)]
6    end
7
8    subgraph 运行时检索
9        Q[用户提问] --> QEMBED[问题向量化]
10        QEMBED --> SEARCH[相似度检索]
11        STORE --> SEARCH
12        SEARCH --> RERANK[结果重排]
13        RERANK --> CONTEXT[注入上下文]
14        CONTEXT --> LLM
15    end
16

7.2 知识库检索架构

1flowchart TB
2    subgraph 离线索引
3        DOCS[文档 / 记忆文件] --> CHUNK[文本分块]
4        CHUNK --> EMBED[Embedding 向量化]
5        EMBED --> STORE[(向量数据库)]
6    end
7
8    subgraph 运行时检索
9        Q[用户提问] --> QEMBED[Question 向量化]
10        QEMBED --> SEARCH[相似度检索]
11        STORE --> SEARCH
12        SEARCH --> RERANK[结果重排]
13        RERANK --> CONTEXT[注入上下文]
14        CONTEXT --> LLM
15    end
16

7.3 真实代码:Hermes 的 Memory Manager

1# Hermes: agent/memory_manager.py
2def build_memory_context_block(agent, user_message: str, max_chars=8000) -> str:
3    """检索相关记忆,构建上下文块注入到对话中"""
4    results = agent.memory_store.search(query=user_message, top_k=10)
5
6    if not results:
7        return ""
8
9    context_lines = ["<memory_context>"]
10    for result in results:
11        if len("\n".join(context_lines)) > max_chars:
12            break
13        context_lines.append(
14            f"<memory score={result.score:.2f}>{result.text}</memory>"
15        )
16    context_lines.append("</memory_context>")
17    return "\n".join(context_lines)
18

7.4 RAG 在 Conversation Loop 中的位置

1sequenceDiagram
2    participant U as 用户
3    participant A as Agent
4    participant MEM as Memory Manager
5    participant EMB as Embedding 服务
6    participant STORE as 向量存储
7    participant LLM as LLM
8
9    U->>A: &#34;上次我们讨论的那个 bug 修复了吗?&#34;
10
11    Note over A,LLM: Loop  1 轮:LLM 判断需要搜索记忆
12    A->>LLM: messages + tools(含 memory_search)
13    LLM-->>A: function_call: memory_search(query=&#34;bug 修复&#34;)
14
15    A->>MEM: memory_search(query=&#34;bug 修复&#34;)
16    MEM->>EMB: query 向量化
17    EMB-->>MEM: embedding vector
18    MEM->>STORE: 相似度检索
19    STORE-->>MEM: top-k 相关片段
20    MEM-->>A: 返回语义相关记忆
21
22    Note over A,LLM: Loop  2 轮:记忆注入后继续对话
23    A->>LLM: messages + 检索到的记忆片段 + 原问题
24    LLM-->>A: &#34;根据之前讨论的 #42 bug,已在上周通过 PR #58 修复&#34;
25    A-->>U: 最终回答
26

关键设计memory_search 本身也是 Tool Registry 中的一个工具!LLM 在循环中自主决定「我需要先查一下历史记忆」,然后调用它。检索结果作为上下文追加到 messages,下一轮 LLM 就能基于记忆生成回答。

7.5 OpenClaw 的 Memory Search 工具定义


八、全链路端到端:一条消息的完整旅程

以「帮我查一下 GitHub 上 openclaw 项目的最近 3 个 Issue」为例,展示完整的 Conversation Loop 流转:

1flowchart LR
2    U[用户提问] --> GW[Gateway]
3    GW --> L1[Loop R1: 加载 github SKILL]
4    L1 --> L2[Loop R2: 调用 MCP gh issue list]
5    L2 --> L3[Loop R3: 格式化回答]
6    L3 --> U2[返回]
7

代码路径对照

1    1. 消息到达  hermes_cli/tui_gateway/server.py
2    2. 创建 Session + 启动 Loop  agent/conversation_loop.py::run_conversation()
3    3. 构建上下文  agent/turn_context.py + agent/memory_manager.py
4    4. 调用 LLM  agent/conversation_loop.py::call_llm_with_retry()
5    5. 解析 function_call  tools/registry.py::lookup()
6        Built-in: 直接执行函数
7        MCP:      tools/mcp_tool.py  转发到 MCP Server
8        Skill:    agent/skill_utils.py  加载 SKILL.md
9    6. 追加结果 + 回到步骤 4(最多 60 轮)
10

九、核心速查:对比总结 + 关键洞察

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 + Compaction
Tool 发现自动扫描 tools/*.py + MCP listTools + Skill 元数据显式注册 + MCP listTools + Skill 清单
MCP 支持原生支持(stdio / HTTP / SSE,守护线程)原生支持(stdio / HTTP / SSE)
Skill 系统SKILL.md + 模板变量 + 内联 Shell + 安全扫描 + 信任分级SKILL.md + description 注入
Memory / RAGagent/memory_manager.py — 向量检索 + 上下文注入memory_search Tool — 语义搜索 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 最多调多少次 LLM?Hermes 默认 max_turns=60,即最多 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 为什么能够持续思考、持续调用工具,并最终完成复杂任务。

源码会不断演进,但底层设计思想往往比代码更加稳定。

希望这篇文章,能够帮助你真正建立现代 Agent 的整体认知。


本文基于 Hermes v0.18.2 与 OpenClaw 当前版本源码分析,部分代码为简化示意,旨在说明整体设计思路。

作者:吴佳浩(Alben)


为什么 MCP、Skill、RAG 能工作?从 Conversation Loop 看现代 Agent 的底层架构》 是转载文章,点击查看原文


相关推荐


当 Linux 成为“空气”:容器、Agent 与不再重要的“桌面之争” -- 肘子的 Swift 周报 #143
东坡肘子2026/7/7

当 Linux 成为“空气”:容器、Agent 与不再重要的“桌面之争” 一周前,微软推出了无需 Docker 的 Windows 11 原生容器支持的公开预览;再结合苹果不久前发布的容器管理器(container)1.0 正式版,一时间,两大主流桌面操作系统都将 Linux 容器深度集成为了系统的一等公民。 这件事引发了一场有趣的讨论。有人认为,这是 Linux 的最终胜利:虽然它始终没能真正赢下桌面市场,但它已经无处不在;也有人提出反问:当 Windows 和 macOS 都能相对顺畅、轻量


让 AI Agent 系统自己发现 bug、自己提修复 PR:自我进化的 Harness
谭sir2026/6/29

本文介绍怎么让 AI Agent 的工程代码(Harness)具备自我进化能力——自动记录运行数据、自动识别错误模式、自动生成修复 PR(Pull Request,合并请求)。内容覆盖监控、错误模式识别、自动修复、行为分析和生产落地方案,每一章都会配合 demo 项目 evo-agent-demo 的代码和运行结果来讲解。 从一个 bug 说起 假设你做了一个 AI Agent 产品,它可以搜索资料、查数据库、执行代码。上线前也在内部进行了反复测试,并且没发现什么问题,于是就正式上线了。 但产品


【节点】[Rectangle节点]原理解析与实际应用
SmalBox2026/6/20

【Unity Shader Graph 使用与特效实现】专栏-直达 Rectangle 节点是 Unity URP Shader Graph 中一个功能强大的形状生成工具,专门用于在着色器中创建矩形图案。该节点基于输入的 UV 坐标生成矩形形状,通过精确的参数控制可以实现从简单的方形到复杂矩形图案的创建。在游戏开发中,矩形形状有着广泛的应用场景,包括创建 UI 元素、制作平铺纹理、构建几何图案、实现遮罩效果等。 该节点的核心工作原理是通过数学计算在 UV 空间中定义矩形区域。UV 空间是一个标


LangChain上手 MCP:从用别人工具到自己写工具
颜酱2026/6/12

LangChain上手 MCP:从用别人工具到自己写工具 读完这篇文章,你将能:用别人的 MCP Server(比如百度地图)、自己写一个 MCP Server(比如计算器)、用 Agent 自动调度多个工具。 先看效果 用别人的:百度地图 MCP 十几行代码,让 AI 变成地图助手: import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents imp


女程序媛多肉的 AI 小绿书,短短 3 天 220 粉
threerocks2026/6/5

微信公众号近 1~2 年,主推贴图类型作品,并且对这类内容有比较明显的流量倾斜。再叠加这两年 AI 生图的成熟,Nano Banana Pro 和 GPT-Image-2 先后出世,既然图片生产不再是卡点,那很多人会很自然地想到一个项目:用 OpenClaw、Codex、Claude Code 这类 Agent 工具,把公众号贴图自动化做起来。 理论上,这听起来像一个很好且成本不高的生意。AI 负责生图,Agent 负责写文案,公众号负责推荐流。人只要选图、点发布,甚至再往后一点,连选图都可以交


AI 大模型核心五:从 Transformer、RAG 到 Agent 架构
zhangxingchao2026/5/29

一、如果去掉多头只用单头,Transformer 会出现什么问题? 一句话概括: 单头注意力会把所有关系都压到一个注意力分布里,导致模型很难同时关注语法、语义、位置、指代、长程依赖等多种信息,表达能力会明显下降。 这里要注意,单头不是完全不能用,而是会形成明显的信息瓶颈。 1. 多头注意力到底解决什么问题? Multi-Head Attention 的关键价值,不只是“多算几次 attention”,而是让不同的 head 在不同子空间里学习不同类型的关系。 一段文本里,模型可能同时需要关注


深度学习(13)PyTorch神经网络基础
β添砖java2026/5/7

1. 层和块 ① nn.Sequential 定义了一种特殊的Module。 # 回顾一下多层感知机 import torch #基础计算(类似 numpy) from torch import nn #神经网络工具(层、模型) from torch.nn import functional as F #一些函数(比如激活函数) #搭建神经网络结构 net = nn.Sequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))


Claude Code 从零上手:国内用户保姆级安装教程
易安说AI2026/4/27

Claude Code 是目前公认最强的 AI  编程 Agent 框架。很多人以为它必须配合 Claude 官方模型才能用,但实际上,Claude Code 本质是一个 Agent 框架,搭配任何模型都能运行。本文手把手教你从零安装 Claude Code,并用国产模型 GLM-5.1 接入,全程不需要海外手机号、Visa 卡,甚至不需要代理。  操作系统:macOS 或 Windows 均可 网络:有代理最好,没有也能用(本文两种方案都覆盖) 模型选择:推荐 GLM-5.1(国内效果最接近


js的深拷贝和浅拷贝?啥情况讲解下??底层堆栈空间??object.prototype.toString.call(),还有bind,的具体使用?
神の愛2026/4/19

js的深拷贝和浅拷贝?啥情况讲解下??底层堆栈空间??object.prototype.toString.call(),还有bind,的具体使用?还有instanceof对象的实例,还有哪个方法可以直接获取到我定义的数据是什么类型的。哟哪几种数据类型?包括哪些? 1. 堆(Heap)与 栈(Stack):内存的真相 在 JS 里,内存被分为两块: 栈(Stack):空间小、速度快。存放基本数据类型(String, Number, Boolean, Null, Undefined, Sy


如何实现分布式锁
哈里谢顿2026/4/10

分布式锁是分布式系统中协调多个节点对共享资源访问的关键机制。我来从原理到实现,系统性地讲解。 核心要求 一个可靠的分布式锁必须满足: 特性说明互斥性同一时间只有一个客户端能持有锁防死锁锁必须有过期机制,避免客户端崩溃后锁永远不被释放可重入性(可选)同一客户端可以多次获取同一把锁容错性大部分节点存活时,锁服务仍能正常工作 方案一:基于 Redis(最常用) 1. 基础版(SETNX + EXPIRE) SETNX lock:resource "

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读