AI Agent系统架构设计:从Command not found到Agent-Skill-Command三层分工实践
1. 从“Command not found”到“Agent Skill”分工:一个开发者的认知跃迁
最近在折腾几个AI项目时,我频繁地在终端里遇到各种“Command not found”的报错。从 git 到 mysql ,再到 psql ,这些看似基础的环境配置问题,背后其实指向了一个更深层次的议题:在构建复杂的、由多个智能体(Agent)协作的系统时,我们如何清晰地定义和划分每个组件的职责与能力(Skill)?这不仅仅是解决一个环境变量的问题,而是关乎整个系统架构的健壮性与可维护性。今天,我想结合 Claude Code、Hermes Agent 等具体工具,以及我踩过的无数坑,来聊聊“Command、Agent、Skill 的正确分工”这个核心命题。无论你是正在搭建第一个 AI Agent 的开发者,还是被各种“Skill”、“Codex”概念搞得晕头转向的探索者,这篇文章或许能帮你理清思路,少走弯路。
我们常常陷入一个误区:看到一个强大的工具(比如 Claude Code),就希望它能包办一切,从代码生成、环境配置到系统部署。但结果往往是,当它在执行一个需要调用本地 git 命令的 Skill 时,因为环境问题而报错“command not found”,整个流程戛然而止。这恰恰说明了“分工”的重要性。一个设计良好的 Agent 系统,应该像一支专业的团队,每个成员(Agent)各司其职,每个成员所掌握的技能(Skill)边界清晰,而具体的执行动作(Command)则被妥善地封装和管理。接下来,我将从问题表象入手,逐步拆解其背后的架构逻辑,并分享一套可落地的分工实践方案。
2. 问题根源:为什么“Command not found”是分工失败的信号?
当你看到 zsh: command not found: mysql 或 -bash: zip: command not found 这样的错误时,第一反应可能是去安装对应的软件包。这没错,但这只是治标。在 Agent 的语境下,这个错误是一个强烈的架构警讯:它表明执行某个 Skill 的 Agent,其运行环境(Context)与执行该 Skill 所需的能力(Capability)不匹配。
2.1 环境隔离与上下文边界
每个 Agent 都应该有自己明确的运行上下文。这个上下文包括但不限于:
- 系统环境变量(PATH) :决定了哪些命令行工具(Command)可以被直接调用。
- 编程语言运行时 :例如 Python 解释器、Node.js 环境及其包依赖。
- 访问权限 :对文件系统、网络端口、特定 API 的访问权限。
- 知识范围 :Agent 被预设拥有的领域知识或数据集。
一个常见的反模式是 :让一个负责“高级代码生成与架构设计”的 Agent(比如 Claude Code),同时去执行“依赖安装与系统配置”这类需要特定本地环境权限的 Command。Claude Code 可能擅长理解 pip install -r requirements.txt 这行代码的意图,但它自身并不具备在目标机器上执行这条命令的“手”和“脚”。强行让它去做,就会因为环境隔离而失败。
注意 :这里的环境隔离不仅是技术上的,也是职责上的。就像你不会让建筑设计师同时去拌水泥,虽然他们都为盖房子服务。
2.2 Skill 的粒度与 Command 的封装
Skill(技能)是 Agent 能够完成的一个相对独立的任务单元。而 Command(命令)是完成这个任务所调用的最细粒度操作。分工不清晰往往体现在 Skill 设计得过“重”或过“泛”。
- 过重的 Skill :一个名为“SetupDatabase”的 Skill,内部可能依次包含了“检查 Docker 是否安装”、“拉取 MySQL 镜像”、“创建并运行容器”、“执行初始化 SQL 脚本”等多个 Command。这个 Skill 的成功执行依赖于一长串外部环境(Docker CLI、网络、磁盘空间),任何一个环节的 Command 失败都会导致整个 Skill 失败,且难以定位和恢复。
- 过泛的 Skill :一个名为“ExecuteShell”的 Skill,它接收任意字符串并尝试在 shell 中执行。这赋予了 Agent 过大的、不可控的权力,并且完全模糊了分工。Agent 可能执行
rm -rf /(当然有保护机制,但原理危险),也可能因为一个简单的git status而因环境问题失败。
正确的做法是,将 Skill 设计得足够原子化,每个 Skill 专注于一个明确的、上下文自洽的目标。同时,将调用外部 Command 的风险和依赖进行封装与管理。
3. 架构蓝图:构建层次清晰的 Agent-Skill-Command 体系
基于上述问题,我总结并实践了一套三层分工体系。这套体系的核心思想是: 让专业的 Agent 做专业的事,通过清晰的接口(Skill)进行协作,而具体的脏活累活(Command)被隔离在安全的沙箱或特定的执行环境中。
3.1 第一层:Orchestrator Agent(协调者代理)
这是系统的“大脑”或“项目经理”。它的核心职责是 任务分解与调度 ,而不是具体执行。它通常由最强大的 LLM(如 Claude 3.5 Sonnet、GPT-4)驱动。
- 典型代表 :基于 LangChain、LlamaIndex 或自定义框架构建的“主控”Agent。Hermes Agent 在某种程度上也可以承担这个角色,如果将其配置为决策中心。
- 核心 Skill :
- Plan :理解用户终极目标(如“搭建一个带用户系统的博客”),并将其分解为一系列有序的子任务(设计数据库Schema -> 编写后端API -> 实现前端页面 -> 部署上线)。
- Delegate :为每个子任务分配合适的 Specialist Agent。它需要知道每个 Specialist Agent 具备哪些 Skill。
- Validate & Integrate :验收 Specialist Agent 的工作成果,并将它们整合成最终交付物。
- 关键特点 :它 不直接执行任何系统 Command 。它的输出是“计划”和“指令”,而不是
bash命令。它运行在一个纯净的、只有思考能力的环境中。
3.2 第二层:Specialist Agent(专家代理)
这是系统的“双手”和“专业工具”。每个 Specialist Agent 专精于一个特定领域,并拥有执行该领域任务所需的 安全、可控的执行环境 。
- 典型代表 :
- Code Agent(代码专家) :如 Claude Code 。它的专长是理解、生成、解释和重构代码。它的环境可能是一个带有特定语言工具链(如
python,node,gcc)的容器,但权限被严格限制在代码文件操作内。 - Shell Agent(运维专家) :专门负责执行安全的系统命令。它的环境拥有更广泛的
PATH(包含git,docker,kubectl等),但行为受到严格策略控制(例如,禁止执行rm、chmod等危险命令,或只允许执行预定义白名单内的命令)。 - Database Agent(数据库专家) :专门与数据库交互。它的环境配置了
mysql、psql等客户端,并且有特定数据库的连接凭证。
- Code Agent(代码专家) :如 Claude Code 。它的专长是理解、生成、解释和重构代码。它的环境可能是一个带有特定语言工具链(如
- 核心 Skill :每个 Specialist Agent 暴露一组定义良好的 Skill。
- Code Agent 的 Skill:
GeneratePythonClass,RefactorCode,WriteUnitTest。 - Shell Agent 的 Skill:
SafeGitClone,InstallPipPackage,RestartService。 - Database Agent 的 Skill:
RunQuery,CreateTable,MigrateSchema。
- Code Agent 的 Skill:
- 关键特点 : Skill 的实现内部封装了具体的 Command 。例如,
SafeGitClone这个 Skill 的内部逻辑是:1) 检查目标目录是否存在且安全;2) 组装git clone <url> --depth 1命令;3) 在 Shell Agent 的沙箱环境中执行该命令;4) 捕获输出和错误,格式化为结构化结果返回。用户和 Orchestrator 只关心SafeGitClone这个 Skill,而不需要知道背后用的是git命令。
3.3 第三层:Safe Execution Environment(安全执行环境)与 Command
这是系统的“物理层”。Command 在这里被实际执行。关键在于,执行环境与 Agent 的逻辑是解耦的。
- 实现方式 :
- Docker 容器 :为每个需要执行 Command 的 Specialist Agent 启动一个轻量级、一次性使用的 Docker 容器。容器内预装好所有需要的工具。任务完成后,容器销毁。这彻底解决了“Command not found”和环境污染问题。
- 受限的系统沙箱 :通过
chroot、nsjail、gVisor等技术,在主机上创建一个高度受限的执行环境。 - 云函数/无服务器函数 :将需要执行 Command 的 Skill 包装成云函数。例如,一个“压缩文件”的 Skill 背后触发一个云函数,该函数在云端的标准环境中调用
zip命令。
- Command 管理 :在这一层,可以维护一个 允许执行的命令白名单 及其参数模板。任何 Skill 试图执行的 Command 都必须先匹配白名单,防止任意命令执行带来的安全风险。
通过这三层架构,我们实现了清晰的分工:
- Orchestrator 负责“想” :任务规划和决策。
- Specialist 负责“做” :通过定义清晰的 Skill 接口来执行领域任务。
- Environment 负责“跑” :在安全、可控、依赖完备的环境中执行具体的 Command。
当 Shell Agent 的 InstallPipPackage Skill 被调用时,它会在一个预装了 python3 和 pip 的 Docker 容器中运行 pip install 命令。即使主机上没有 Python,这个 Skill 也能成功。这就是分工带来的鲁棒性。
4. 实战:以“搭建一个数据可视化项目”为例
假设用户目标是:“帮我创建一个用 Flask 做后端,React 做前端,能连接 PostgreSQL 并展示图表的数据可视化项目。”
4.1 错误的分工方式(单 Agent 尝试)
我们只有一个“全能”的 Claude Code Agent。用户提出需求后,它开始生成一个庞大的脚本:
# 假设这是Claude Code生成的“一站式”脚本
git clone https://github.com/example/boilerplate.git my-project
cd my-project
pip install -r backend/requirements.txt # 可能失败:python/pip not found
npm install --prefix frontend # 可能失败:node/npm not found
sudo systemctl start postgresql # 可能失败:权限不足或命令不存在
psql -U postgres -c "CREATE DATABASE vizdb;" # 可能失败:psql not found 或认证失败
flask run & # 可能失败:环境变量未设置
cd frontend && npm start &
这个脚本几乎会在每一个外部 Command 调用处失败,因为 Claude Code Agent 的运行环境不具备这些条件。开发者需要手动介入,逐个解决环境问题,Agent 的自动化价值荡然无存。
4.2 正确的分工方式(多 Agent 协作)
步骤一:Orchestrator Agent 规划 Orchestrator 分析需求,制定计划:
- 任务A :创建项目脚手架代码结构。 -> 委托给 Code Agent 。
- 任务B :安装后端 Python 依赖。 -> 委托给 Shell Agent (执行安全安装命令)。
- 任务C :安装前端 Node.js 依赖。 -> 委托给 Shell Agent 。
- 任务D :准备 PostgreSQL 数据库。 -> 委托给 Database Agent 。
- 任务E :编写核心数据接口和图表组件代码。 -> 委托给 Code Agent 。
- 任务F :启动开发服务器。 -> 委托给 Shell Agent (执行安全启动命令)。
步骤二:Specialist Agents 各司其职
- Code Agent (Claude Code) :接收到任务A和E。它在自己的代码上下文中,生成
app.py,requirements.txt,package.json,src/App.jsx等文件的内容。它 只输出代码文本 ,不执行git或npm init。 - Shell Agent :
- 接收到任务B:它调用自己的
CreateProjectFromScaffoldSkill。该 Skill 内部:在一个干净的 Docker 容器(镜像为python:3.11-slim)中,执行git clone(白名单命令)和pip install -r requirements.txt。成功后,将代码目录打包返回。 - 接收到任务C:在另一个容器(镜像为
node:18-alpine)中,执行npm install。 - 接收到任务F:在组合了前后端代码的容器中,安全地执行
flask run和npm start。
- 接收到任务B:它调用自己的
- Database Agent :接收到任务D。它使用预配置的 PostgreSQL 连接信息,调用
RunQuerySkill 执行CREATE DATABASE语句。
步骤三:Orchestrator 整合与交付 Orchestrator 接收所有 Specialist Agent 返回的结果(代码文件、安装成功的确认、数据库创建成功的确认、服务访问地址),整理成一份最终报告给用户:“项目已创建在 ./my-project 目录,后端依赖已安装,数据库‘vizdb’已就绪,前端服务运行在 http://localhost:3000 ,后端 API 运行在 http://localhost:5000 。”
在整个过程中,任何一个 Specialist Agent 的失败(例如,网络问题导致 pip install 超时)都不会导致整个系统崩溃。Orchestrator 可以捕获这个错误,决定重试、换源或者向用户请求帮助。每个环节的职责和边界都非常清晰。
5. 核心工具链的定位与选型思考
理解了分工架构,我们再回头看那些热门工具,就能更清楚地知道把它们放在哪里。
- Claude Code / Codex :它们是顶级的 Code Specialist Agent 。它们的核心价值在于 代码智能 。你应该将它们用在“生成模块代码”、“重构复杂函数”、“解释代码逻辑”、“编写测试用例”等纯代码任务上。试图让它们去执行
git命令或修改系统配置,是将其置于不擅长的领域,违背了分工原则。- 安装与配置 :所谓的“安装Claude Code”,通常是指将其 API 或 SDK 集成到你的 Agent 系统中,作为 Code Agent 的“大脑”。例如在 VSCode 中安装扩展,或通过 API 调用。重点是为其配置好代码库的上下文(当前文件、项目结构),而不是系统环境。
- Hermes Agent :它是一个功能丰富的 Agent 框架/平台 。它可以被配置为 Orchestrator ,也可以内置或连接各种 Specialist (如代码解释器、网络搜索工具)。它的价值在于提供了构建多技能 Agent 所需的基础设施(记忆、工具调用、规划能力)。你需要在其框架内,按照分工思想去设计和注册不同的工具(Skill)。
- Shell Agent(自定义) :这是你需要重点构建或严格挑选的组件。你可以基于
subprocess+Docker SDK自己实现一个,也可以使用像piston(一个开源的代码执行引擎)或E2B(云端安全沙箱)这类专业服务。关键是要有 命令过滤 、 资源限制 和 环境隔离 。 - Database Agent(自定义) :通常基于特定数据库的客户端库(如
psycopg2for PostgreSQL,pymysqlfor MySQL)封装而成,暴露安全的查询和操作接口,永远不要直接传递拼接的 SQL 字符串给 LLM 执行。
6. 避坑指南与进阶技巧
在实践这套分工体系时,我积累了一些血泪教训和实用技巧。
6.1 常见陷阱与解决方案
-
Skill 接口设计过载 :
- 陷阱 :设计一个
RunProject的 Skill,期望它完成从代码检查、依赖安装、编译到运行的所有事情。 - 解决方案 :拆分为原子 Skill:
LintCode,InstallDependencies,BuildArtifact,StartService。每个 Skill 职责单一,易于测试和复用。
- 陷阱 :设计一个
-
环境状态污染与不一致 :
- 陷阱 :多个任务共享同一个持久化 Shell Agent 环境,任务A安装了旧版本的包,影响了任务B。
- 解决方案 : 坚持无状态和一次性环境 。每个任务的执行都从一个干净的基础镜像开始。可以使用 Docker 镜像层缓存来加速依赖安装(如预装常用包),但任务本身不保留状态。状态(如生成的文件、数据库数据)应保存在专门的存储卷或数据库中。
-
错误处理与重试逻辑缺失 :
- 陷阱 :Agent 执行 Skill 失败后,直接向上抛出晦涩的错误信息(如
Command ‘git’ failed with code 128),导致 Orchestrator 无法理解并进行决策。 - 解决方案 :Skill 的实现必须包含 结构化的错误处理 。返回结果应该是一个标准格式,例如:
{“success”: bool, “data”: any, “error”: {“type”: “NetworkError”|“DependencyMissing”|“PermissionDenied”, “message”: str, “recoverable”: bool}}。这样,Orchestrator 可以根据error.type和error.recoverable决定是自动重试、切换方法还是请求人工干预。
- 陷阱 :Agent 执行 Skill 失败后,直接向上抛出晦涩的错误信息(如
-
安全白名单的维护难题 :
- 陷阱 :为了灵活性,不断扩充 Shell Agent 的命令白名单,最终形同虚设。
- 解决方案 :采用 “参数化命令模板” 而非完全开放的命令字符串。例如,允许
git clone <url>,但<url>必须经过 SSH 密钥认证或 HTTPS 令牌验证的仓库地址;允许pip install <package_name>,但<package_name>必须来自一个受信任的内部 PyPI 镜像源。这样既保证了安全,又提供了必要的灵活性。
6.2 性能与成本优化
- 容器冷启动延迟 :为每个任务启动新容器开销很大。可以采用 容器池 技术,预先启动一批空闲容器,任务来时直接分配。或者,对于非常轻量、快速的任务,在严格隔离的进程沙箱中执行。
- LLM 调用成本 :Orchestrator 和 Code Agent 频繁调用 Claude/GPT API 费用不菲。可以通过以下方式优化:
- 缓存 :对常见的、确定性的任务规划结果进行缓存。
- 小模型接力 :让大模型(如 Claude 3.5 Sonnet)做复杂的任务分解和设计,然后让更小、更快的模型(如 Claude Haiku 或本地模型)来执行具体的、模式化的代码生成或工具调用。
- 清晰的系统提示词 :精心设计给每个 Agent 的提示词(System Prompt),明确其角色、职责和输出格式,可以大幅减少无效的 token 消耗和来回纠错。
6.3 调试与监控
当你的系统由多个 Agent 协作时,传统的 print 调试法不再适用。你需要建立一套观测体系。
- 结构化日志 :每个 Agent、每个 Skill 的调用都需要记录带有唯一追踪 ID(Trace ID)的日志。日志内容应包括:输入参数、调用的工具/Command、返回结果、耗时、错误信息。
- 可视化追踪 :使用像 LangSmith、Weights & Biases 或自定义的看板,可视化展示一个用户请求的完整生命周期:经过了哪些 Agent,调用了哪些 Skill,状态如何。这对于排查“哪个环节慢了”或“为什么卡住了”至关重要。
- Skill 的健康检查 :定期测试每个 Specialist Agent 的 Skill 是否可用。例如,定时用一条简单的查询测试 Database Agent,用
echo hello测试 Shell Agent 的环境。这能提前发现环境依赖缺失等问题。
回到最初的那个 command not found 错误,在分工清晰的体系里,它应该被这样处理:Shell Agent 在执行某个 Skill 的预定义 Command 模板时,在其专属的、预配置好的 Docker 容器中仍然失败了(比如因为镜像内该命令确实未安装)。这时,Skill 会返回一个结构化的错误 {“type”: “DependencyMissing”, “message”: “Required command ‘xx’ not found in execution environment”, “recoverable”: true} 。Orchestrator 接收到这个错误后,可以触发一个“修复环境”的流程,或者直接选择另一个具备此能力的 Specialist Agent。整个系统优雅地应对了失败,而不是崩溃。
构建 AI Agent 系统,尤其是涉及多技能协作的系统,本质上是在设计一套精密的自动化工作流。清晰的分工——让思考者、执行者、运行环境各归其位——是这套工作流稳定、高效、安全运转的基石。它迫使我们从“让一个 AI 做什么”的简单思维,转向“如何设计一组 AI 以及它们之间的协作机制来达成目标”的系统工程思维。这虽然增加了前期的设计复杂度,但换来的是后期维护成本的显著降低和系统能力的指数级增长。下次当你再看到 command not found ,不妨把它看作一个重新审视和优化你系统分工的好机会。
更多推荐



所有评论(0)