# Structuring Agents, Skills, and MCPs: Best Practices from the Field
**作者**: Carlos E. Perez
**日期**: 2026-05-05T18:43:08.000Z
**来源**: [https://x.com/IntuitMachine/status/2051734456453738871](https://x.com/IntuitMachine/status/2051734456453738871)
---

# Introduction
Building a single AI agent that does one thing well is straightforward. Building a system of agents — composable, secure, and maintainable across an organization — is an architectural problem. The challenge is not making the model smarter but designing the scaffolding around it: what knowledge lives where, who can touch what, and how work flows between components without collapsing into a monolith or fragmenting into chaos.
This essay examines a three-layer architecture for agentic systems — skills, agents, and MCP connectors — and distills the design principles that make it work. The examples are drawn from a financial-services reference implementation, but the patterns generalize to any domain where agents handle sensitive data, compose domain expertise, and produce work product that humans must ultimately approve.
## The Three Layers
The core insight is a clean separation of concerns into three distinct layers, each with a different owner, lifecycle, and trust level:
Skills are units of reusable domain expertise. A skill teaches Claude how to do something — how to build a DCF model, how to trace a GL break, how to draft an IC memo. Skills are passive: they don't decide when to fire or in what order. They are authored once by domain experts, stored in a canonical location, and syndicated to any agent that needs them.
Agents are workflow orchestrators with identity. An agent knows what to do, in what order, and with what constraints. It has a persona ("You are the GL Reconciler"), a defined set of deliverables, a numbered workflow, and guardrails that constrain its behavior. Agents consume skills the way a project manager consumes the expertise of specialists on the team.
MCP connectors are the data layer — standardized integrations that wire agents to external systems (market data terminals, document stores, internal ledgers) without embedding connection logic in the agent or skill itself.
The power of this separation is that each layer evolves independently. A domain expert can improve a skill without touching any agent. An architect can restructure an agent's workflow without rewriting the skills it uses. An IT team can swap a data provider by changing an MCP URL without either the agent or the skills knowing about it.
## Skill Design: Author Once, Syndicate Everywhere
Single-source authorship
The most important rule in skill design is that every skill has exactly one canonical source. In practice, this means skills are authored in a domain-organized library — grouped by vertical (investment banking, equity research, fund administration) — and copied into each agent that uses them via an automated sync process.
This matters because the alternative — letting each agent maintain its own version of a skill — guarantees drift. Two agents that both do comps analysis will, within weeks, develop subtly different conventions for how they handle outliers or format output. A sync script that propagates changes from the canonical source into every agent bundle, combined with a linter that fails the build if any copy has drifted, eliminates this class of problem mechanically.
Skills are passive, not agentic
A well-designed skill does not contain workflow logic. It does not say "first do X, then do Y." It says "when you are doing X, here is how to do it well." The skill for comparable company analysis describes metric definitions, outlier treatment, and formatting conventions — it does not decide when in a pitch workflow comps should be run. That decision belongs to the agent.
This passivity is what makes skills composable. The same comps-analysis skill can be invoked at step 4 of a pitch workflow, step 2 of an earnings review, or on demand via a /comps slash command. If the skill contained sequencing logic, it would be coupled to a single workflow and unusable elsewhere.
Slash commands as skill entry points
Skills can optionally expose slash commands (/comps, /dcf, /earnings) that let users invoke them directly. This is the "toolkit" mode — install the vertical plugin, get the commands, use them ad hoc without any agent orchestration. It's a useful on-ramp: users who aren't ready for full agent workflows can still benefit from structured domain expertise.
## Agent Design: Identity, Workflow, Guardrails
The agent prompt template
A well-structured agent prompt has five sections, always in the same order:
1. Frontmatter — machine-readable metadata: name, description, tool allowlist
2. Identity — who the agent is and what it owns
3. Deliverables — the exact artifacts the agent produces (not vague goals — concrete outputs)
4. Workflow — numbered steps, each referencing specific skills by name
5. Guardrails — hard constraints on what the agent must not do
This consistency matters for maintainability. When every agent follows the same template, a new team member can read any agent prompt and immediately understand its scope, its process, and its limits. It also makes it possible to lint and validate agent prompts programmatically.
Explicit deliverables over vague mandates
The difference between a useful agent and a dangerous one often comes down to how precisely its outputs are defined. Compare "help with GL reconciliation" to:
> Given a trade date and list of asset classes, you deliver:Break list — every GL/subledger variance over threshold, with account, balances, variance, suspected cause.
> Root-cause trace — for each break, the transaction-level evidence and classification.
> Exception report — formatted for controller sign-off, with recommended resolution per break.
The first framing invites scope creep and hallucination. The second gives the agent — and the human reviewing its output — a concrete checklist to evaluate against. When deliverables are explicit, the agent knows when it's done, and the reviewer knows what to check.
Workflow as skill composition
The workflow section is where agents earn their keep. It transforms a bag of skills into an ordered process with dependencies, handoffs, and quality gates. Each step typically maps to one skill invocation:
> Scope the ask. Confirm target, sector, and situation.
> Write the situation overview. Invoke the sector-overview skill.
> Pull data. Use the CapIQ MCP for trading multiples and filings.
> Spread the peer set. Invoke the comps-analysis skill.
> Build the model. Invoke dcf-model and 3-statement-model.
Notice that the workflow references skills and data sources by name. This makes the dependencies explicit and auditable. It also means the workflow can be understood without reading the skill files — the agent prompt is a self-contained specification of the process.
Guardrails: what the agent must never do
Every agent should declare its negative space — the things it will not do under any circumstances. These fall into recurring categories:
No system-of-record writes. An agent that reconciles a ledger produces a report; it does not post journal entries. An agent that screens KYC documents recommends a risk rating; it does not approve onboarding. The line between "draft" and "execute" is the most important guardrail in any financial workflow.
No external communications. Agents that produce client-facing work (pitch decks, research notes) have no email or messaging tools. Distribution is a human decision.
Source everything. When a number cannot be traced to a data source, the agent flags it as [UNSOURCED] rather than estimating. This turns hallucination from a silent failure into a visible one.
Human approval gates. The agent stops and surfaces work for review at defined checkpoints — after the model is built, after the deck is generated — rather than running to completion unsupervised. This is especially important for multi-artifact workflows where an error in an early stage compounds downstream.
## Security Through Tiered Isolation
The untrusted-content problem
In many real workflows, the agent must process documents authored by outsiders — counterparty statements, onboarding packets, custodian reports. These documents may contain adversarial instructions designed to manipulate the agent (prompt injection). The architectural question is: how do you let the agent read untrusted content without letting that content reach your tools or systems?
Subagent tiers
The answer is to split the agent into tiered subagents with different trust levels and tool access. The pattern has three tiers:
Reader tier — touches untrusted documents. Has Read and Grep only. No MCP access, no write tools, no bash. Its output is schema-validated with length caps and character-class restrictions, so injected instructions cannot survive intact into downstream tiers. This is the quarantine zone.
Orchestrator tier — never touches untrusted documents directly. Dispatches readers, aggregates their (validated) output, and coordinates the workflow. Has read tools plus MCP access to trusted internal systems. Cannot write.
Resolver tier — the only tier with write access. Receives verified, critic-checked data and produces the final output artifacts. Never opens outsider files, never runs bash, never connects to external systems. Its attack surface is minimal because it only sees data that has already been validated by two upstream tiers.
A fourth role, the critic, adds an independent verification step: it re-checks each finding against trusted sources before the resolver writes anything. This catch layer is particularly valuable in reconciliation and audit workflows where false positives are costly.
Deny-by-default tooling
The mechanical enforcement of this tiering is deny-by-default tool configuration. Every subagent starts with all tools disabled and explicitly enables only the ones it needs:
yamltools:- type: agent_toolset_20260401default_config:enabled: false # everything offconfigs:- name: readenabled: true # explicitly granted- name: grepenabled: true # explicitly granted
This is the principle of least privilege applied to agentic systems. An agent that doesn't need write access doesn't get write access — not as a prompt instruction that can be overridden, but as a mechanical config that the model cannot change at runtime.
## MCP Connectors: Centralized Data Access
One source, many consumers
MCP (Model Context Protocol) connectors should be defined once in a shared location and consumed by any agent or skill that needs them. In practice, this means a single .mcp.json file in a core plugin that lists every data provider, and all other plugins inherit from it.
This centralization prevents the proliferation of connection configs across agents. When a data provider changes its URL or authentication scheme, you update one file, not ten. It also makes it easy to audit what external systems your agents can reach — the answer is always in one place.
Connector access as a security boundary
MCP access is a meaningful security boundary. In the tiered subagent model, connector access is granted selectively:
- The reader (which touches untrusted content) gets no MCP access — it cannot reach any firm system.
- The orchestrator gets read-only MCP access to trusted internal systems.
- The resolver (which can write files) gets no MCP access — it cannot exfiltrate data.
This creates a separation where the agent that can read external data cannot write to the filesystem, and the agent that can write to the filesystem cannot read external data. A compromised reader cannot use MCP to reach firm systems; a compromised resolver cannot use MCP to send data anywhere.
## Composition Patterns
Agent-to-agent handoffs
Complex workflows often span multiple agents. A GL reconciliation may discover breaks that need to be addressed by a month-end close process. Rather than expanding the reconciler's scope, the agent emits a structured handoff_request that an orchestration layer routes to the appropriate downstream agent.
This handoff pattern preserves each agent's single responsibility while enabling multi-agent pipelines. The key constraint is that handoffs must go through a validated allowlist — an agent cannot arbitrarily invoke any other agent. The orchestration layer (whether a Python script, Temporal workflow, or Airflow DAG) validates the handoff target and payload before routing.
Dual deployment from one source
A well-structured agent should deploy identically to interactive environments (where a human is in the loop) and headless environments (where the agent runs autonomously via API). This is achieved by keeping the agent's core definition — system prompt and skills — in the plugin directory, and adding a thin deployment wrapper (an agent.yaml with environment-specific config) for the headless path.
The headless wrapper adds things like MCP server URLs (which are environment-specific), subagent manifests (which are deployment-specific), and a one-line append to the system prompt ("You are running headless. Produce files in ./out/; do not assume an open Office document."). The core identity, workflow, and guardrails remain identical.
## Summary of Principles
1. Separate knowledge from orchestration. Skills teach how; agents decide what, when, and with what constraints.
2. Author skills once, syndicate mechanically. A sync script and drift linter prevent divergence.
3. Make skills passive. No sequencing logic in skills — that belongs to the agent.
4. Define deliverables, not goals. Concrete output specs prevent scope creep and enable review.
5. Declare negative space. Every agent should state what it will never do.
6. Deny tools by default. Grant the minimum toolset each tier needs, mechanically.
7. Isolate untrusted content structurally. The reader that opens outsider documents cannot reach your tools or systems.
8. Validate at boundaries. Schema-validate and length-cap every output that crosses a trust tier.
9. Centralize data access. One MCP config, consumed by many — auditable and swappable.
10. Deploy from one source. The same prompt and skills should power both interactive and headless modes.
These are not theoretical principles — they are patterns extracted from a working system that handles financial data, processes untrusted documents, and produces work product that humans sign off on. The common thread is that good agent architecture is less about making the model more capable and more about making the system around it more predictable, auditable, and safe.

## 相关链接
- [Carlos E. Perez](https://x.com/IntuitMachine)
- [@IntuitMachine](https://x.com/IntuitMachine)
- [3.1K](https://x.com/IntuitMachine/status/2051734456453738871/analytics)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [2:43 AM · May 6, 2026](https://x.com/IntuitMachine/status/2051734456453738871)
- [3,163 Views](https://x.com/IntuitMachine/status/2051734456453738871/analytics)
---
*导出时间: 2026/5/6 09:14:36*
---
## 中文翻译

# 简介
构建一个能把一件事做好的单一 AI 代理很简单。但构建一个代理系统——要在整个组织内部实现可组合、安全且可维护——则是一个架构问题。挑战不在于让模型变得更聪明,而在于设计围绕它的支架:知识存放在哪里,谁能访问什么,以及工作如何在组件之间流转,既不坍塌成单体,也不碎片化成混乱。
本文探讨了一种用于代理系统的三层架构——技能、代理和 MCP 连接器——并提炼了使其有效运作的设计原则。这些示例取自一个金融服务的参考实现,但这些模式也适用于任何代理处理敏感数据、组合领域专业知识并生成最终必须由人类批准的工作产品的领域。
## 三层架构
核心的洞察是将关注点清晰地分离到三个不同的层,每一层都有不同的所有者、生命周期和信任级别:
技能 是可复用的领域专业知识的单元。技能教 Claude 如何做某事——如何构建 DCF 模型、如何追溯 GL(总账)差异、如何起草 IC 备忘录。技能是被动的:它们不决定何时触发或以何种顺序触发。它们由领域专家编写一次,存储在规范位置,并分发给任何需要它们的代理。
代理 是具有身份的工作流编排器。代理知道做什么、按什么顺序做、以及有什么约束。它具有一个人设(“你是 GL 对账员”),一组定义的交付物,一个编号的工作流,以及约束其行为的护栏。代理消费技能的方式,就像项目经理消费团队中专家的专长一样。
MCP 连接器 是数据层——标准化的集成,将代理连接到外部系统(市场数据终端、文档存储、内部账簿),而无需将连接逻辑嵌入到代理或技能本身。
这种分离的力量在于每一层都可以独立演进。领域专家可以改进一个技能,而无需触碰任何代理。架构师可以重构代理的工作流,而无需重写它使用的技能。IT 团队可以通过更改 MCP URL 来更换数据提供商,而无需代理或技能知情。
## 技能设计:一次编写,随处分发
单一来源的编写
技能设计中最重要的规则是,每个技能只有一个规范来源。在实践中,这意味着技能是按领域分组的库(按垂直行业编写,如投资银行、股票研究、基金管理),并通过自动同步过程复制到每个使用它们的代理中。
这很重要,因为替代方案——让每个代理维护自己的技能版本——必然会导致分化。两个都进行 comps 分析的代理,在几周内就会对如何处理异常值或格式化输出产生细微的差异不同的约定。一个将更改从规范来源传播到每个代理包的同步脚本,再加上一个在有任何副本发生分化时导致构建失败的 linter,可以从机制上消除这类问题。
技能是被动的,而非代理化的
一个设计良好的技能不包含工作流逻辑。它不说“先做 X,再做 Y”。它说“当你做 X 时,这是做好它的方法”。可比公司分析技能描述了指标定义、异常值处理和格式约定——它不决定在推介工作流中何时运行 comps。这个决定属于代理。
这种被动性正是使技能可组合的原因。同一个 comps 分析技能可以在推介工作流的第 4 步、收益审查的第 2 步被调用,或者通过 /comps 斜杠命令按需调用。如果技能包含排序逻辑,它将耦合到单一工作流,无法在其他地方使用。
斜杠命令作为技能入口点
技能可以选择性地公开斜杠命令(/comps, /dcf, /earnings),让用户直接调用它们。这是“工具包”模式——安装垂直插件,获取命令,无需任何代理编排即可临时使用。这是一个有用的入口:尚未准备好完整代理工作流的用户仍然可以从结构化的领域专业知识中受益。
## 代理设计:身份、工作流、护栏
代理提示模板
一个结构良好的代理提示有五个部分,且总是相同的顺序:
1. Frontmatter(前言)——机器可读的元数据:名称、描述、工具允许列表。
2. Identity(身份)——代理是什么以及它拥有什么。
3. Deliverables(交付物)——代理产生的确切工件(不是模糊的目标——而是具体的输出)。
4. Workflow(工作流)——编号的步骤,每一步都通过名称引用特定的技能。
5. Guardrails(护栏)——对代理绝不能做的事情的硬性约束。
这种一致性对于可维护性很重要。当每个代理都遵循相同的模板时,新团队成员可以阅读任何代理提示,并立即理解其范围、流程和限制。这也使得通过程序对代理提示进行检查和验证成为可能。
明确的交付物胜过模糊的指令
一个有用的代理和一个危险的代理之间的区别,往往取决于其输出的定义有多精确。比较“协助 GL 对账”与:
> 给定一个交易日期和资产类别列表,你需要交付:差异列表——每个超过阈值的 GL/子分类账差异,包含科目、余额、差异、疑似原因。根本原因追溯——对于每个差异,提供交易级别的证据和分类。异常报告——格式化以供控制员签字,包含针对每个差异的建议解决方案。
第一种表述会助长范围蔓延和幻觉。第二种表述为代理——以及审查其输出的人类——提供了一个具体的清单来进行评估。当交付物明确时,代理知道何时完成,审查者知道要检查什么。
工作流即技能组合
工作流部分是代理体现价值的地方。它将一堆技能转化为一个有序的过程,具有依赖关系、交接和质量关卡。每个步骤通常映射到一个技能调用:
> 界定需求。确认目标、领域和情境。撰写情境概览。调用 sector-overview 技能。拉取数据。使用 CapIQ MCP 获取交易倍数和文件。展开同行公司集。调用 comps-analysis 技能。构建模型。调用 dcf-model 和 3-statement-model。
请注意,工作流通过名称引用技能和数据源。这使得依赖关系明确且可审计。这也意味着无需阅读技能文件即可理解工作流——代理提示是流程的一个自包含规范。
护栏:代理绝不能做的事
每个代理都应该声明其负面空间——即它在任何情况下都不会做的事情。这些属于反复出现的类别:
不写入系统记录。对账分类账的代理生成报告;它不生成日记账分录。筛选 KYC 文档的代理推荐风险评级;它不批准入职。“起草”和“执行”之间的界限是任何金融工作流中最重要的护栏。
不进行外部通信。生成面向客户的工作(推介演示文稿、研究笔记)的代理没有电子邮件或消息工具。分发是一个人的决定。
一切皆需溯源。当一个数字无法追溯到数据源时,代理会将其标记为 [UNSOURCED](未溯源),而不是进行估算。这将幻觉从无声的失败转变为可见的失败。
人工批准关卡。代理会在定义的检查点停止并展示工作以供审查——在模型构建之后、在演示文稿生成之后——而不是在无人监督的情况下运行到完成。这对于多工件的工作流尤其重要,因为早期的错误会在下游放大。
## 通过分层隔离实现安全
不受信任内容的问题
在许多实际工作流中,代理必须处理由外人编写的文档——交易对手对账单、入职数据包、托管报告。这些文档可能包含旨在操纵代理的对抗性指令(提示注入)。架构问题是:如何让代理读取不受信任的内容,而不让该内容触及你的工具或系统?
子代理分层
答案是将代理拆分为具有不同信任级别和工具访问权限的分层子代理。该模式有三个层级:
读取层——接触不受信任的文档。只有 Read(读取)和 Grep(搜索)权限。无 MCP 访问权限,无写入工具,无 bash。其输出经过模式验证,具有长度限制和字符类别限制,因此注入的指令无法完整地流入下游层。这是隔离区。
编排层——从不直接接触不受信任的文档。调度读取器,聚合其(已验证的)输出,并协调工作流。拥有读取工具加上对可信内部系统的 MCP 访问权限。无法写入。
解析层——唯一具有写入权限的层级。接收经过验证的、经过批评者检查的数据,并生成最终的输出工件。从不打开外人文件,从不运行 bash,从不连接到外部系统。其攻击面最小,因为它只看到已经过上游两层验证的数据。
第四个角色,批评者,增加了一个独立的验证步骤:它在解析器写入任何内容之前,针对可信来源重新检查每个发现。这个捕获层在 reconcile 和审计工作流中特别有价值,因为误报的代价很高。
默认拒绝的工具配置
这种分层的机制强制执行是默认拒绝的工具配置。每个子代理在默认情况下禁用所有工具,并仅显式启用它需要的工具:
yamltools:- type: agent_toolset_20260401default_config:enabled: false # everything offconfigs:- name: readenabled: true # explicitly granted- name: grepenabled: true # explicitly granted
这是应用于代理系统的最小权限原则。不需要写入访问权限的代理就不会获得写入权限——不是作为可以被覆盖的提示指令,而是作为模型在运行时无法更改的机械配置。
## MCP 连接器:集中式数据访问
一个来源,多个消费者
MCP(模型上下文协议)连接器应该在共享位置定义一次,并由任何需要它们的代理或技能使用。在实践中,这意味着在核心插件中有一个单一的 .mcp.json 文件,列出每个数据提供商,所有其他插件都继承它。
这种集中化防止了连接配置在代理之间的扩散。当数据提供商更改其 URL 或身份验证方案时,你更新一个文件,而不是十个。这也使得审查代理可以访问哪些外部系统变得容易——答案总是在一个地方。
连接器访问作为安全边界
MCP 访问是一个有意义的安全边界。在分层子代理模型中,连接器访问是有选择性地授予的:
- 读取器(接触不受信任的内容)没有 MCP 访问权限——它无法到达任何公司系统。
- 编排者拥有对可信内部系统的只读 MCP 访问权限。
- 解析器(可以写入文件)没有 MCP 访问权限——它无法外泄数据。
这创建了一种分离,即可以读取外部数据的代理无法写入文件系统,而可以写入文件系统的代理无法读取外部数据。受损的读取器无法使用 MCP 到达公司系统;受损的解析器无法使用 MCP 将数据发送到任何地方。
## 组合模式
代理到代理的交接
复杂的工作流通常跨越多个代理。GL 对账可能会发现需要由月末结账流程解决的差异。代理不应扩大其范围,而是发出一个结构化的 handoff_request(交接请求),由编排层路由到适当的下游代理。
这种交接模式保留了每个代理的单一职责,同时实现了多代理管道。关键约束是交接必须经过验证的允许列表——代理不能随意调用任何其他代理。编排层(无论是 Python 脚本、Temporal 工作流还是 Airflow DAG)在路由之前验证交接目标和有效载荷。
从一个来源双重部署
一个结构良好的代理应该在交互式环境(人类参与其中)和无头环境(代理通过 API 自主运行)中相同地部署。这是通过将代理的核心定义——系统提示和技能——保留在插件目录中,并为无头路径添加一个薄部署包装器(一个带有环境特定配置的 agent.yaml)来实现的。
无头包装器添加了诸如 MCP 服务器 URL(特定于环境)、子代理清单(特定于部署)以及对系统提示的单行追加(“你正在无头运行。在 ./out/ 中生成文件;不要假设有一个打开的 Office 文档”)。核心身份、工作流和护栏保持不变。
## 原则总结
1. 将知识与编排分离。技能教“如何做”;代理决定“做什么”、“何时做”以及“有什么约束”。
2. 一次编写技能,机械地分发。同步脚本和分化 linter 防止分歧。
3. 使技能保持被动。技能中没有排序逻辑——这属于代理。
4. 定义交付物,而不是目标。具体的输出规范防止范围蔓延并启用审查。
5. 声明负面空间。每个代理都应该说明它绝不会做什么。
6. 默认拒绝工具。机械地授予每一层所需的最小工具集。
7. 在结构上隔离不受信任的内容。打开外人文件的读取器无法触及你的工具或系统。
8. 在边界进行验证。对跨越信任层的每个输出进行模式验证和长度限制。
9. 集中数据访问。一个 MCP 配置,多个消费者——可审计且可更换。
10. 从一个来源部署。相同的提示和技能应同时支持交互式和无头模式。
这些不是理论原则——它们是从一个处理金融数据、处理不受信任文档并生成人类批准的工作产品的实际系统中提取的模式。共同的主线是,良好的代理架构与其说是让模型更有能力,不如说是让围绕它的系统更具可预测性、可审计性和安全性。

## 相关链接
- [Carlos E. Perez](https://x.com/IntuitMachine)
- [@IntuitMachine](https://x.com/IntuitMachine)
- [3.1K](https://x.com/IntuitMachine/status/2051734456453738871/analytics)
- [升级到高级版](https://x.com/i/premium_sign_up)
- [2026年5月6日 凌晨2:43](https://x.com/IntuitMachine/status/2051734456453738871)
- [3,163 次观看](https://x.com/IntuitMachine/status/2051734456453738871/analytics)
---
*导出时间: 2026/5/6 09:14:36*