三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Claude Code五层架构:从单体智能体到协同智能系统的工程实践

Claude Code五层架构:从单体智能体到协同智能系统的工程实践

1. 项目概述:从单体智能到协同作战的范式演进

最近在折腾AI应用开发,特别是围绕Claude系列模型构建复杂系统时,发现一个核心痛点:当任务复杂度超出单个AI智能体的能力边界时,我们该怎么办?是把所有指令都塞进一个越来越臃肿的提示词里,还是另辟蹊径?Claude Code提出的五层架构——MCP、Skills、Agent、Subagents、Agent Teams——正是为了解决这个“智能体协同”的难题。这不仅仅是几个新名词的堆砌,它代表了一种从“单体智能”向“组织化、专业化协同智能”的工程范式转变。

简单来说,这套架构试图回答:如何像管理一个高效的技术团队一样,去设计和调度多个AI智能体?每个智能体不再是一个全能的“超人”,而是成为拥有特定专长(Skills)、能通过标准协议(MCP)调用外部工具、并能在更高层级智能体(Agent)指挥下,与同级智能体(Subagents)组成临时项目组(Agent Teams)来完成复杂任务的“专家”。对于任何想要超越简单问答,构建能处理多步骤、跨领域、需长期记忆和规划的真实世界应用的开发者而言,理解这套协作机制至关重要。它直接决定了你系统的天花板在哪里,是停留在玩具阶段,还是能真正投入生产环境解决实际问题。

2. 架构核心思想与设计哲学拆解

2.1 为什么需要五层?—— 解耦与复用的必然选择

在早期AI应用开发中,常见的模式是“一个提示词走天下”。这种模式在简单任务上可行,但一旦涉及需要检索知识、执行代码、调用API、进行多轮决策的复杂流程,提示词就会变得极其冗长且难以维护。更致命的是,这种紧耦合的设计让能力复用和系统扩展举步维艰。Claude Code的五层架构,其根本思想源于软件工程中经典的“关注点分离”和“模块化”原则。

MCP层相当于定义了智能体的“手”和“眼睛”的接口标准。它让智能体不必关心工具的具体实现,只需知道如何调用。Skills层则是对这些基础工具调用的封装和组合,形成可复用的“业务能力”,比如“数据可视化”或“SQL查询分析”。Agent层是拥有自主规划和决策能力的“个体专家”,它掌握一系列Skills,并能根据目标制定计划。当单个Agent的任务过于庞大时,它可以将子任务分解,创建或协调Subagents去执行,这类似于项目主管将工作分派给组员。最后,Agent Teams层管理的是多个独立Agent之间的协作,它们可能地位平等,为了一个共同目标而临时组队,各自贡献不同的核心专长。

这种分层设计的好处是显而易见的:每一层都可以独立开发、测试和优化。你可以像搭积木一样,用不同的Skills组合出新的Agent,也可以用不同的Agent组建应对不同场景的Team。系统的复杂度和能力,因此获得了线性的、而非指数级的增长路径。

2.2 各层角色定位与职责边界

为了避免在实际开发中出现“该谁干”的混乱,明确每一层的职责至关重要。这里用一个开发运维(DevOps)场景来类比:

  • MCP (Model Context Protocol)基础设施管理员。它不直接参与业务逻辑,而是负责提供标准化的“工具箱”访问方式。比如,它定义了如何安全地连接服务器(SSH)、如何执行一个Shell命令、如何读取一个远程文件的统一协议。无论哪个Agent需要操作服务器,都通过同一套MCP协议来调用,保证了安全性和一致性。
  • Skills掌握了特定工具技能的工程师。例如,一位工程师掌握了“使用Ansible进行批量部署”的技能(Skill)。这个Skill内部可能调用了多个MCP工具(执行命令、上传文件)。Skill是可复用的,另一个需要部署任务的Agent也可以调用这个Skill。
  • Agent负责某个专项的团队主管。比如,一个“部署Agent”,它的核心职责是完成代码从仓库到生产环境的全流程。它自身拥有“代码检出”、“执行测试”、“调用部署Skill”等一系列能力。它理解部署的完整上下文和目标,并做出决策(例如,测试失败则停止部署)。
  • Subagents主管临时委派任务的组员。当“部署Agent”发现需要先进行一轮性能测试时,它可能动态创建一个“性能测试Subagent”,并将这个子任务连同必要的上下文(代码版本、环境信息)交给它。Subagent执行完毕后,将结果(测试报告)返回给主Agent。Subagent通常是主Agent能力的延伸或特化。
  • Agent Teams跨部门项目组。为了上线一个大型功能,可能需要“前端部署Agent”、“后端部署Agent”、“数据库迁移Agent”和“监控配置Agent”组成一个临时团队。它们之间需要协商顺序、传递数据(如新服务的端口号)、同步状态。一个“团队协调者”(可能是另一个更上层的Agent,或一个简单的协调逻辑)负责确保它们有序协作,达成“功能成功上线”的总体目标。

清晰的边界使得系统调试和维护变得简单。如果部署失败,你可以很快定位是某个Skill的Ansible脚本问题,还是Agent的决策逻辑问题,亦或是Team中多个Agent的协作时序问题。

3. 核心组件深度解析与实操要点

3.1 MCP:智能体的标准化“武器库”

MCP不是某个具体的工具,而是一套协议规范。你可以把它理解为智能体世界的“USB标准”或“RESTful API规范”。它的核心价值在于标准化安全性

实操要点一:如何为你的智能体装备MCP工具?通常,你需要运行一个MCP服务器(Server),这个服务器实现了与具体工具(如文件系统、数据库、Git仓库)的交互。然后,在你的AI应用(客户端)中配置连接到此服务器。以连接一个“文件系统”工具为例,伪代码逻辑如下:

# MCP 客户端配置示例(概念性代码) import mcp_client # 1. 连接到本地运行的 filesystem MCP 服务器 client = mcp_client.connect(server_command="npx -y @modelcontextprotocol/server-filesystem /path/to/allow/dir") # 2. 获取服务器提供的工具列表 tools = client.list_tools() # 可能返回:["read_file", "write_file", "list_directory"] # 3. 智能体(Agent)在需要时可以调用这些工具 # 当Agent决定要读取一个文件时,它会构造一个标准的调用请求 result = client.call_tool("read_file", arguments={"path": "/project/config.json"})

关键注意事项:

  • 权限控制是生命线:在配置MCP服务器时,必须严格限定其可访问的范围(如仅允许访问项目目录/project)。绝对不要授予其根目录或敏感目录的访问权限,防止智能体被诱导执行危险操作。
  • 工具描述要精准:MCP服务器在向客户端注册工具时,必须提供清晰、准确的名称和参数描述。模糊的描述会导致智能体无法正确理解和使用工具。
  • 网络与性能:对于远程工具,要考虑网络延迟和稳定性。对于高频操作,可能需要本地缓存或连接池优化。

3.2 Skills:构建可复用的能力模块

Skill是对一个或多个MCP工具调用的封装和编排,并附加了领域知识。它比单纯调用工具更高一层,包含了“为什么”和“怎么样”的逻辑。

实操要点二:设计一个高质量的Skill假设我们要创建一个“Fetch and Summarize Webpage” Skill。

  1. 定义输入输出:输入是一个URL字符串,输出是网页内容的摘要。
  2. 内部编排
    • 调用MCP工具fetch_url获取网页HTML。
    • 调用MCP工具extract_main_text去除广告、导航栏等噪音,提取正文。
    • 调用AI模型(Claude)本身,提示其“请用三段话总结以下文章内容”。
  3. 错误处理:处理网络超时、HTML解析失败、内容过长等异常情况。
  4. 提供元信息:为Skill提供清晰的描述,如“此Skill用于获取并总结英文新闻类网页内容,对于视频页或登录页可能无效”。这能帮助Agent更好地选择何时使用它。

一个Skill的伪代码结构可能如下:

class WebpageSummarizeSkill: description = "Fetch a webpage and generate a concise summary." def __init__(self, mcp_client, llm_client): self.mcp = mcp_client self.llm = llm_client async def execute(self, url: str) -> str: try: # 步骤1: 获取网页 html = await self.mcp.call_tool("fetch_url", {"url": url}) # 步骤2: 提取正文 main_text = await self.mcp.call_tool("extract_text", {"html": html}) # 步骤3: 调用LLM总结 prompt = f"请总结以下文本:\n{main_text[:3000]}" # 限制长度 summary = await self.llm.complete(prompt) return summary except NetworkError: return "错误:无法访问该网址。" except Exception as e: return f"处理过程中发生错误:{str(e)}"

经验心得:Skill应该保持“单一职责”。一个做总结的Skill,就不要同时去翻译。小而专的Skill更容易被复用和组合。同时,为Skill编写单元测试至关重要,确保其在不同输入下的稳定性和可靠性。

3.3 Agent:具备自主规划能力的决策中心

Agent是架构中的“大脑”。它不仅仅是一组Skill的集合,更关键的是它拥有目标理解、任务分解和规划能力。它通过与大语言模型(LLM)的深度集成来实现这些能力。

实操要点三:实现一个Agent的决策循环一个典型的Agent工作循环遵循“感知-思考-行动”模式:

  1. 感知:接收用户目标或上级任务(如“为本项目搭建CI/CD流水线”)。
  2. 思考:利用LLM分析目标,结合自身掌握的Skills列表和当前上下文(项目类型、已有文件),制定一个分步计划。
    • 计划示例:① 检查项目根目录是否有package.jsonpom.xml以确定技术栈。② 检查是否有现有的.github/workflows配置。③ 如果没有,则根据技术栈创建对应的CI配置文件。④ 向用户确认或直接提交到仓库。
  3. 行动:根据计划,按顺序调用相应的Skill来执行每一步。例如,调用“文件查找Skill”执行步骤①和②,调用“代码生成Skill”执行步骤③。
  4. 观察与调整:执行每个行动后,观察结果(成功、失败、返回了某些数据)。将这些结果作为新的上下文,反馈给“思考”步骤,决定是继续下一步,还是调整计划。

关键设计考量:

  • 短期记忆(上下文):Agent需要记住之前的步骤、结果和用户反馈。这通常通过维护一个不断增长的对话历史或状态变量来实现。
  • 长期记忆(向量数据库):对于需要跨会话记忆的知识(如项目规范、用户偏好),Agent可能需要将关键信息存入向量数据库,供后续检索。
  • 规划与反思:高级的Agent会在行动前进行“思维链”推理,在行动后进行“反思”,评估结果是否达到预期,并从中学习。

4. 多层协作机制与工作流实战

4.1 Subagents:动态任务分解与委派

当主Agent遇到一个庞大或专业性子任务时,创建Subagent是高效的选择。Subagent通常继承或部分继承主Agent的上下文、权限和可用Skills,但被赋予一个更聚焦的目标。

实战场景:数据分析报告生成主Agent“数据分析师”接到任务:“分析本月销售数据,并生成一份可视化报告。”

  1. 任务分解:主Agent决定将任务分解为:a) 数据清洗与预处理, b) 关键指标计算, c) 图表生成。
  2. 创建Subagent:主Agent为任务a创建“数据清洗Subagent”,并将原始销售数据CSV文件的路径和清洗规则(如处理空值、格式化日期)作为初始指令传递给它。
  3. Subagent执行:“数据清洗Subagent”调用“Pandas数据处理Skill”,完成清洗后,将处理好的数据帧(或保存路径)返回给主Agent。
  4. 结果整合:主Agent收到清洗后的数据,再创建或亲自执行任务b和c。Subagent在任务完成后通常会被销毁以释放资源。

协作模式解析:

  • 指令传递:主Agent通过清晰的指令初始化Subagent,指令中应包含目标、输入数据、约束条件(如时间限制)。
  • 上下文共享:Subagent可能需要访问主Agent的某些上下文(如项目配置)。可以通过共享内存、传递引用或受限的MCP权限来实现。
  • 结果返回:Subagent应以结构化的格式(JSON、特定对象)返回结果,方便主Agent解析和集成。

4.2 Agent Teams:多智能体协同攻坚

Team解决的是多个独立对等的Agent之间如何协作的问题。它们通常没有一个绝对的上下级关系,而是通过共享工作空间、通信协议和协调机制来合作。

实战场景:智能软件开发团队一个“软件开发Team”由以下Agent组成:

  • 产品经理Agent:理解用户需求,编写用户故事和功能描述。
  • 架构师Agent:根据功能描述,设计系统架构和API接口。
  • 后端开发Agent:根据架构设计,实现API和业务逻辑代码。
  • 前端开发Agent:根据产品原型和API文档,实现用户界面。
  • 测试Agent:编写并执行测试用例。

协作流程与核心技术点:

  1. 共享工作空间:通常是一个虚拟的“项目文件夹”或项目管理工具(如模拟的Jira)。所有Agent都能向其中读写文件、更新任务状态。
    • 实现方式:可以是一个共享的MCP文件服务器,或一个在内存中维护的项目状态管理器。
  2. 通信与触发:当一个Agent完成其工作后,如何通知下一个Agent?
    • 发布-订阅模式:Agent订阅自己关心的事件。例如,测试Agent订阅“代码提交”事件。当后端开发Agent提交代码后,触发事件,测试Agent被自动唤醒开始工作。
    • 工作流引擎驱动:使用一个中心化的协调器(Orchestrator)来定义工作流(如BPMN)。协调器严格按流程控制每个Agent的激活时机和输入输出。
  3. 冲突解决:如果前端和后端Agent对同一个API接口的数据格式理解不一致怎么办?
    • 协商机制:引入一个“仲裁者”角色(可以是一个简单的规则,或另一个LLM驱动的协调Agent)。当检测到不一致时,召集相关Agent“开会”,基于共享的架构文档进行协商,达成一致后更新共享文档。
  4. 状态同步:团队的整体进度如何感知?
    • 共享状态看板:在共享工作空间中维护一个project_status.json文件,每个Agent完成任务后更新自己的状态。所有Agent都可以读取此文件来了解全局进度。

一个简化的团队协调伪代码示例:

class DevelopmentTeam: def __init__(self, agents: Dict[str, Agent], shared_workspace): self.agents = agents self.workspace = shared_workspace self.coordinator = WorkflowCoordinator() # 一个简单的协调逻辑 async def run_project(self, requirement: str): # 1. 产品经理Agent工作 await self.workspace.write("requirement.txt", requirement) await self.agents["product_manager"].activate(self.workspace) # 2. 协调器检查产品文档是否就绪,就绪则触发架构师 if await self.workspace.exists("user_stories.md"): await self.agents["architect"].activate(self.workspace) # 3. 类似地,驱动后端、前端、测试Agent... # 协调器需要处理依赖和等待条件

5. 实施路径、常见陷阱与效能优化

5.1 从零到一的五层架构搭建指南

构建一个完整的五层架构系统不必一步到位。建议采用迭代式开发:

阶段一:工具层(MCP)建设

  1. 从最迫切的需求出发,选择1-2个核心工具(如文件操作、网络请求)。
  2. 部署或开发对应的MCP服务器,并进行严格的本地测试,确保其稳定性和安全性。
  3. 目标:让你的AI应用能通过标准协议可靠地读写文件、访问网页。

阶段二:技能层(Skills)封装

  1. 围绕已部署的MCP工具,封装2-3个高频使用的Skills。例如,将“读取文件->解析JSON->提取特定字段”封装成一个“读取配置Skill”。
  2. 为每个Skill编写清晰的文档和示例。
  3. 目标:形成一个小型、可复用的能力库。

阶段三:智能体层(Agent)实现

  1. 设计一个解决具体问题的Agent,例如“代码审查Agent”。
  2. 为其配备相关的Skills(如“读取代码Skill”、“代码分析Skill”、“生成评论Skill”)。
  3. 实现其核心规划逻辑:如何理解PR描述,如何按文件进行审查,如何汇总问题。
  4. 目标:得到一个能独立完成端到端任务的单一智能体。

阶段四:引入子代理(Subagents)

  1. 当你的Agent任务逻辑变得复杂时,识别出可以独立出来的子模块。例如,代码审查Agent中,“安全检查”和“风格检查”可以分离。
  2. 将这些模块重构为Subagent,让主Agent负责调度和结果整合。
  3. 目标:提升复杂Agent的内部模块化和可维护性。

阶段五:组建团队(Agent Teams)

  1. 当你拥有多个成熟的、功能各异的Agent时,尝试为一项综合任务让它们协作。例如,让“需求分析Agent”、“原型图生成Agent”、“代码生成Agent”接力完成一个简单应用的设计与实现。
  2. 设计它们之间的通信协议和数据交接格式。
  3. 目标:实现超越单个Agent能力的复杂系统级自动化。

5.2 典型问题排查与调试技巧

在开发过程中,你一定会遇到智能体“不按套路出牌”的情况。以下是几个常见问题及排查思路:

问题一:Agent陷入死循环或无效行动。

  • 现象:Agent反复执行同一个或一组无意义的操作。
  • 排查
    1. 检查规划步骤:查看LLM生成的计划是否合理。可能是提示词中缺乏足够的约束或示例。
    2. 检查上下文:Agent的短期记忆是否已满载?过长的上下文可能导致模型忽略关键信息。尝试清空或总结历史。
    3. 检查工具/Skill反馈:工具返回的结果是否清晰、结构化?一个模糊的错误信息可能导致Agent无法理解而重试。确保工具反馈对AI友好。
  • 解决:在Agent的决策循环中加入“反思”步骤,强制其评估当前进展;或设置最大步数限制。

问题二:多Agent协作时数据不一致或任务丢失。

  • 现象:Team中某个Agent读取了过时的数据,或者某个任务没人处理。
  • 排查
    1. 检查共享工作空间:数据更新是否是原子的?是否存在读写冲突?考虑使用简单的锁机制或版本控制。
    2. 检查事件/触发机制:发布的事件是否被正确订阅?工作流引擎的状态机是否处于正确节点?
    3. 检查Agent状态:某个Agent是否因为异常而崩溃,导致任务链中断?需要实现Agent的健康检查和重启机制。
  • 解决:引入更健壮的状态管理,如使用一个轻量级数据库(SQLite)来跟踪任务状态和数据版本;为关键操作实现重试和补偿逻辑。

问题三:系统性能瓶颈,响应缓慢。

  • 现象:执行一个任务需要很长时间,特别是涉及多个LLM调用时。
  • 排查
    1. 分析耗时环节:是LLM生成速度慢,还是工具调用(如网络请求)慢?使用日志记录每个步骤的时间戳。
    2. 检查是否可并行:Subagent之间的任务是否独立?如果独立,可以尝试并行执行,而非串行。
    3. 检查上下文长度:是否每次调用LLM都携带了过长的、不必要的历史上下文?尝试只保留最近的关键对话。
  • 解决:对非严格顺序依赖的任务实现并行化;优化提示词,减少不必要的思考链;对于已知的、固定的子任务,可以考虑将其固化为一个无需LLM决策的脚本或Skill。

5.3 高级优化与最佳实践

当系统基本跑通后,可以考虑以下优化来提升稳定性和效率:

1. 为Agent设计“工具箱”与“知识库”

  • 动态工具选择:不要让Agent一次性知道所有Skills,而是根据任务类型,动态加载最相关的Skills子集。这可以减少干扰,提高决策准确性。
  • 集成向量检索:为Agent配备一个向量化的知识库(如项目文档、API手册)。当遇到未知概念时,Agent可以先进行检索,将相关信息注入上下文,再做出决策。

2. 实现分层级的错误处理与降级策略

  • Skill级重试:对于网络波动等临时错误,在Skill内部实现指数退避重试。
  • Agent级备选方案:当首选Skill或计划失败时,Agent应能启动备选方案。例如,生成图表的Skill失败后,可以降级为用文字描述数据趋势。
  • Team级熔断:如果Team中某个关键Agent频繁失败,协调器应能暂时将其隔离,并尝试用其他方式绕过,或直接向上级报告失败。

3. 建立监控与可观测性体系

  • 日志记录:详细记录每个Agent的决策、调用的工具、输入输出。这是调试的黄金标准。
  • 关键指标:统计任务成功率、平均完成时间、LLM调用次数与Token消耗、工具调用耗时等。
  • 可视化跟踪:对于复杂的Team协作,可以生成可视化的任务流程图,实时显示每个Agent的状态和数据流向,这对于理解系统行为和排查阻塞问题至关重要。

构建Claude Code这样的五层架构系统,本质上是在进行“AI软件工程”。它要求开发者不仅要有提示词工程的能力,更要有系统架构设计、模块解耦、状态管理和故障排查的思维。这套架构目前仍在快速演进中,但其所倡导的模块化、标准化和协同化的思想,无疑是构建下一代复杂AI应用的坚实基石。从我自己的实践来看,初期投入在架构设计上的时间,会在后期的功能扩展、问题调试和系统维护中十倍地回报回来。

← 返回列表