Agent-native 架构:代码终结之后,应用该如何构建

Agent-native 架构:代码终结之后,应用该如何构建

原文Agent-native Architectures: How to Build Apps After Code Ends
作者:Dan Shipper(Every) & Claude
说明:以下为原文的忠实中文翻译,仅做语言转换与必要的技术术语规范,不引入任何原文之外的观点或补充说明。


为什么是现在(Why now)

软件代理(Agents)现在终于可以可靠运行了。

Claude Code 证明了一件事:当一个大型语言模型(LLM)可以访问 bash 和文件系统,并在一个循环中持续运行直到目标完成时,它可以自主完成复杂的多步骤任务。

一个出人意料的发现是:一个真正优秀的编码代理,本质上也是一个优秀的通用型代理。

同一套架构,既可以让 Claude Code 重构代码库,也可以让代理整理文件、管理阅读清单,或自动化工作流。

Claude Code SDK 让这种模式变得可构建。你可以构建一种应用:功能不再是你写在代码里的逻辑,而是你描述一个结果,由代理使用工具,在循环中不断判断和调整,直到结果达成。

这开启了一个新的软件领域:将 Claude Code 的工作方式,应用到编程以外的所有软件类别。


核心原则(Core principles)

1. 对等性(Parity)

用户通过 UI 能做到的任何事情,代理也必须能通过工具完成。

这是最基础的原则。如果没有对等性,其它一切都不成立。必须确保代理拥有能够实现 UI 所有能力的工具。

测试方法:任选一个 UI 操作,代理是否能完成?


2. 粒度(Granularity)

工具应当是原子能力。功能是代理在循环中实现的结果。

工具是一种原始能力。功能是通过 prompt 描述的结果,由代理使用工具,在循环中不断执行,直到结果达成。

测试方法:当你想改变行为时,是修改 prompt,还是重构代码?


3. 可组合性(Composability)

在原子化工具和对等性的前提下,你可以仅通过编写新的 prompt 来创建新功能。

例如,一个“每周回顾”功能,只是一个 prompt:

1
2
回顾本周修改过的文件,总结关键变化。
根据未完成事项和即将到期的截止时间,给出下周的三个优先事项。

代理会使用诸如 list_files、read_file 等工具,并依靠自身判断,直到结果完成。你描述的是结果,而不是过程。


4. 涌现能力(Emergent capability)

代理可以完成你没有明确设计过的事情。

循环过程如下:

  1. 构建原子化工具并保证对等性
  2. 用户提出你未预料到的请求
  3. 代理组合工具尝试完成(或失败)
  4. 你观察用户真实提出的需求
  5. 为常见模式添加领域工具或 prompt
  6. 重复这一过程

测试方法:代理是否能处理你这个领域中的开放式请求?


5. 随时间改进(Improvement over time)

Agent-native 应用可以通过上下文积累和 prompt 的不断调整而持续改进,而无需发布新的代码。

改进来自三个层面:

  • 上下文积累:通过文件在会话之间保留状态
  • 开发者级别的 prompt 更新
  • 用户级别的 prompt 定制

原则的实践(Principles in practice)

以下细节使上述五项原则真正可操作。


对等性(Parity)

设想一个笔记应用,用户可以通过界面创建、组织和标记笔记。如果用户对代理说:“创建一条会议总结并标记为紧急”,而代理无法完成这一操作,那么代理就会被卡住。

解决方法是:确保代理拥有可以完成 UI 所有结果的工具。这不是要求 UI 按钮与工具一一对应,而是要求结果层面的能力对等。

纪律要求:每当添加一个 UI 能力,都要问:代理是否也能实现这一结果?如果不能,就补充相应的工具或原语。


粒度(Granularity)

关键转变在于:代理是在追求一个结果,而不是执行一个预先编排的步骤序列。它可以遇到意外情况、调整策略或提出澄清问题,循环会持续,直到结果达成。

工具越原子,代理的灵活性越强。如果你把判断逻辑写进工具中,实际上是把决策权又放回了代码。


可组合性(Composability)

这种方式既适用于开发者,也适用于用户。你可以通过添加 prompt 来发布新功能,用户也可以通过修改 prompt 或创建自己的 prompt 来定制行为。

前提是:工具足够原子,并且代理与用户具备对等能力。如果工具中封装了过多逻辑,可组合性就会被破坏。


涌现能力(Emergent capability)

示例:用户请求“将我的会议记录与任务列表交叉对照,告诉我有哪些已经承诺但尚未安排时间的事项”。即使你从未构建过承诺追踪功能,只要代理可以读取会议记录和任务,它就能完成。

这揭示了潜在需求。你不需要预先猜测用户需要什么,而是通过观察他们让代理做什么来发现需求。


随时间改进(Improvement over time)

代理可以维护跨会话状态,记录已存在的内容、用户行为以及哪些方法有效。

Prompt 的优化可以发生在多个层级:开发者级更新、用户级定制,以及更高级的代理自我调整(需要安全机制)。


工具:从原语到领域工具(From primitives to domain tools)

应当从最基础的原语开始,例如 bash、文件操作和基础存储。这可以验证架构是否成立,并揭示代理真正需要的能力。

当模式逐渐清晰时,可以有意识地添加领域工具,用于:

  • 统一术语
  • 添加必要的校验
  • 提升效率

领域工具应当代表用户视角中的一个概念性动作,而不是封装判断逻辑。判断是否执行某事,应当由 prompt 决定。


文件作为通用接口(Files as the universal interface)

代理天生擅长处理文件。Claude Code 能成功的原因之一,是 bash 加文件系统构成了最成熟、最通用的代理接口。

文件具有以下特性:

  • 代理天然理解
  • 对用户可检查、可编辑
  • 易于导出和备份
  • 可在设备之间同步
  • 具有自解释性

一个总体原则是:如果一个人类能够理解你的结构,代理大概率也能理解。


Agent 执行模式(Agent execution patterns)

完成信号(Completion signals)

代理需要一种显式的方式来表示“我已经完成”。不要通过启发式规则来判断完成状态。

1
2
3
4
5
6
7
8
9
struct ToolResult {
let success: Bool
let output: String
let shouldContinue: Bool
}

.success("Result") // 继续循环
.error("Message") // 继续(用于重试或恢复)
.complete("Done") // 停止循环

完成(completion)与成功 / 失败是两个正交的概念:

  • 一个工具可以成功并停止循环
  • 一个工具也可以失败,但仍然指示继续循环以进行恢复

目前仍未标准化的是更丰富的控制流信号,例如:

  • pause —— 代理需要用户输入后才能继续
  • escalate —— 代理需要超出自身权限的人类决策
  • retry —— 瞬时错误,应由调度器自动重试

当前实践中,如果代理需要输入,通常会在文本响应中直接询问。还不存在正式的“阻塞等待输入”状态,这是一个仍在探索中的领域。


模型层级选择(Model tier selection)

并非所有代理操作都需要同等水平的智能。

任务类型 模型层级 原因
研究型代理 平衡型 工具循环 + 良好推理
对话 平衡型 对话速度足够
复杂综合 强模型 多来源分析
快速分类 快模型 高吞吐、低复杂度

纪律要求:在添加新代理时,应根据任务复杂度显式选择模型层级,而不是默认使用“最强模型”。


部分完成(Partial completion)

1
2
3
4
5
6
7
8
struct AgentTask {
var status: TaskStatus // pending, in_progress, completed, failed, skipped
var notes: String? // 失败原因或已完成说明
}

var isComplete: Bool {
tasks.allSatisfy { $0.status == .completed || $0.status == .skipped }
}

对于多步骤任务,应在任务级别跟踪进度。UI 可以显示:

1
2
3
4
5
6
7
进度:3 / 5 任务完成(60%)

✓ [1] 查找来源材料
✓ [2] 下载全文
✓ [3] 提取关键段落
✗ [4] 生成摘要 —— 错误:上下文限制
○ [5] 创建大纲

部分完成的常见场景:

  • 达到最大迭代次数:已完成的任务保留,保存 checkpoint,后续可继续
  • 单个任务失败:该任务标记失败,其它任务是否继续由代理自行判断
  • 网络错误:当前迭代抛出异常,会话标记失败,checkpoint 保留

上下文限制(Context limits)

代理会话可以无限延续,但上下文窗口不是。

设计原则:

  • 工具应支持渐进式精化(先摘要,再细化,再全文)
  • 给代理提供中途压缩知识的能力(例如“总结目前已知内容并继续”)
  • 假设上下文终将填满,并从一开始就为此设计

实现模式(Implementation patterns)

共享工作区(Shared workspace)

代理与用户应当在同一数据空间中工作,而不是隔离的沙箱。

1
2
3
4
UserData/
├── notes/ ← 代理与用户共同读写
├── projects/ ← 代理可整理,用户可覆盖
└── preferences.md ← 代理读取,用户可编辑

好处包括:

  • 用户可以检查并修改代理的工作成果
  • 代理可以在用户创建的内容基础上继续工作
  • 无需额外的同步层
  • 完全透明

这是默认选择。只有在明确需求(安全、避免破坏关键数据)时才引入沙箱。


上下文注入(Context injection)

代理需要知道它正在处理什么。系统提示应包含:

可用资源

1
2
3
4
5
## Available Data
- /notes 中有 12 条笔记
- 最近一条:"Project kickoff"
- /projects 中有 3 个项目
- 用户偏好位于 /preferences.md

能力范围

1
2
3
4
5
## What You Can Do
- 创建、编辑、标记、删除笔记
- 将文件组织到项目中
- 全文搜索
- 设置提醒(write_file)

近期活动

1
2
3
## Recent Context
- 两小时前创建了 "Project kickoff"
- 昨天询问了 Q3 截止时间

对于长会话,应提供刷新上下文的机制,以保持代理状态最新。


Agent 与 UI 通信(Agent-to-UI communication)

代理的行为应立即反映在 UI 中。推荐的事件类型:

1
2
3
4
5
6
7
enum AgentEvent {
case thinking(String)
case toolCall(String, String)
case toolResult(String)
case textResponse(String)
case statusChange(Status)
}

关键原则:不允许静默行为

实时反馈包括:

  • 展示代理当前思考内容
  • 展示正在执行的工具
  • 流式输出文本
  • 实时更新任务进度

通信方式:

  • 共享数据存储(推荐)
  • 文件系统监听
  • 事件系统(更解耦,但更复杂)

部分工具调用较为嘈杂,可使用 ephemeralToolCalls 标志隐藏内部检查,同时保留关键动作可见。

沉默的代理会让人感觉“坏掉了”;可见的进展能建立信任。


产品层面的影响(Product implications)

Agent-native 架构不仅改变了软件如何构建,也改变了产品呈现给用户的方式

渐进式揭示(Progressive disclosure)

产品应当上手即用,同时没有能力上限

简单的请求无需学习成本即可完成,而高级用户可以不断向系统施加更复杂、出乎意料的要求。

Excel 是一个经典例子:

  • 它既可以是一个简单的杂货清单
  • 也可以是一个复杂的财务模型

Claude Code 也具有这种特性。界面始终保持简单,但能力会随着用户提出的请求而扩展。

这一模式包含三个特征:

  • 低门槛入口:最基础的请求可以立即生效
  • 可发现的深度:用户在探索中逐渐发现系统的能力
  • 没有天花板:高级用户可以推动系统做出你从未预期的事情

代理在能力层面与用户保持同步,它不会要求用户先“学会如何使用它”。


潜在需求的发现(Latent demand discovery)

构建一个能力充足的基础系统,然后观察用户让代理去做什么

传统的产品开发流程是:

  • 设想用户需要什么
  • 构建功能
  • 验证是否命中需求

Agent-native 的流程是:

  • 构建一个能力完备的基础
  • 观察用户向代理提出的请求
  • 将反复出现的模式正式化

当用户请求代理完成某件事并成功时,这是信号;当请求失败时,这同样是信号,它揭示了工具缺失或对等性不足。

随着时间推移,你可以:

  • 为高频模式添加领域工具(更快、更可靠)
  • 为常见请求创建专用 prompt(更易发现)
  • 移除几乎无人使用的工具(简化系统)

在这种模式下,代理本身成为理解用户真实需求的研究工具


审批与用户自主权(Approval and user agency)

Needs validation

以下框架来自 Claude 在构建过程中提出的观点,目前尚未经过充分验证,Dan 仍在形成自己的判断。

当代理开始主动采取行动(而非仅响应用户明确请求)时,你需要决定给予它多大的自主权。这取决于两个因素:风险等级(stakes)可逆性(reversibility)

风险等级 可逆性 模式 示例
自动执行 整理文件
快速确认 发布到信息流
建议后执行 代码修改
显式审批 发送邮件

注意:该框架仅适用于代理的主动行为。如果用户明确指示代理执行某事(例如“发送这封邮件”),那本身就构成了授权。


自我修改必须是可理解的(Self-modification should be legible)

当代理可以修改自身行为(例如更改 prompt、更新偏好或调整工作流)时,设计目标是:

  • 用户能够看到发生了什么变化
  • 用户能够理解这些变化的影响
  • 用户能够随时回滚

审批流程是一种实现方式;带有回滚能力的审计日志是另一种。核心原则是:让变化是可理解、可追溯的


移动端(Mobile)

移动端是 agent-native 应用的一等平台,它既有独特的限制,也有独特的机会。

一个文件系统

代理可以天然地使用文件进行工作,使用的仍然是与其它平台一致的原语。

丰富的上下文

移动端是一个“围墙花园”,但你可以访问到极其丰富的上下文:健康数据、位置、照片、日历等——这些在桌面或 Web 上并不存在。

本地应用

每个用户都有自己的一份应用副本。应用可以按用户分叉、自我演进。

应用状态自动同步

借助 iCloud,所有设备可以共享同一套文件系统。代理的工作成果会自动出现在所有设备上,而无需构建服务器。


挑战

代理通常是长时间运行的,而移动应用并不是。

一个代理任务可能需要 30 秒、5 分钟,甚至 1 小时才能完成。但 iOS 会在应用短时间不活跃后将其置于后台,并可能直接终止以回收内存。用户可能在任务执行过程中切换应用、接听电话或锁屏。

这意味着移动端 agent 应用必须认真处理以下问题:

  • Checkpoint(检查点):保存状态,避免工作丢失
  • Resume(恢复):中断后从上次位置继续
  • 后台执行:高效利用 iOS 提供的有限后台时间
  • 本地 vs 云端:决定哪些内容在本地执行,哪些需要服务器

iOS 存储架构

Needs validation

这是我们正在尝试的一种方案,效果令人兴奋,但它只是众多可能方案中的一种。该方案主要由 Claude 实现,更优解仍有待探索。

这种架构带来的好处包括:

  • 无需构建基础设施即可实现设备间自动同步
  • 无需用户操作即可完成备份
  • 当 iCloud 不可用时可优雅降级
  • 用户在必要时可以在应用外部访问自己的数据

一种实现方式是:iCloud 优先,本地兜底

  1. iCloud 容器(优先)
1
2
3
4
5
iCloud.com.{bundleId}/Documents/
├── Library/
├── Research/books/
├── Chats/
└── Profile/
  1. 本地 Documents(兜底)
1
~/Documents/
  1. 迁移层
  • 自动将本地数据迁移到 iCloud
1
2
3
4
5
6
7
8
// iCloud 优先,本地兜底
if let url = fileManager
.url(forUbiquityContainerIdentifier: nil) {
return url.appendingPathComponent("Documents")
}
return fileManager.urls(
for: .documentDirectory,
in: .userDomainMask)[0]

Checkpoint 与恢复(Checkpoint and resume)

Needs validation

该方案来自 Claude 在实际构建过程中的经验,目前运行良好,但并非最终答案。

移动应用随时可能被中断,代理必须具备生存能力。

需要保存的内容包括:

  • 代理类型
  • 消息记录
  • 迭代次数
  • 任务列表
  • 自定义状态
  • 时间戳

保存时机:

  • 应用进入后台时
  • 每次工具返回结果后
  • 长时间操作过程中定期保存

恢复流程:

  • 加载被中断的会话
  • 根据有效期过滤(默认 1 小时)
  • 向用户展示恢复提示
  • 恢复消息并继续代理循环

恢复步骤:

  1. loadInterruptedSessions() 扫描 checkpoint 目录
  2. filter by isValid(maxAge:)
  3. 展示恢复提示
  4. 恢复消息并继续代理循环
  5. 结束后删除 checkpoint
1
2
3
4
5
6
7
8
9
10
11
12
struct AgentCheckpoint: Codable {
let agentType: String
let messages: [[String: Any]]
let iterationCount: Int
let taskListJSON: String?
let customState: [String: String]
let timestamp: Date
}

func isValid(maxAge: TimeInterval = 3600) -> Bool {
Date().timeIntervalSince(timestamp) < maxAge
}

架构取舍:可以存储完整的代理配置,也可以只存储 agentType 并从注册表中重建。后者更简单,但旧 checkpoint 可能因配置变更而失效。

关键差距在于:如果系统直接杀死应用,恢复能力取决于 checkpoint 的频率。为了最大鲁棒性,应在每次工具返回后保存。


云端文件状态(Cloud file states)

文件可能存在于 iCloud,但尚未下载到本地。在读取之前,应确保文件可用。

1
2
3
await StorageService.shared
.ensureDownloaded(folder: .research,
filename: "full_text.txt")

存储抽象层(Storage abstraction)

不要直接使用 FileManager。应当构建一层存储抽象,屏蔽 iCloud 与本地文件系统的差异。

1
2
let url = StorageService.shared
.url(for: .researchBook(bookId: id))

这样可以保证其余代码无需关心底层存储位置。


后台执行(Background execution)

Needs validation

以下模式来自 Claude 的实践经验。

iOS 提供的后台执行时间非常有限(约 30 秒):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func prepareForBackground() {
backgroundTaskId = UIApplication.shared
.beginBackgroundTask(withName: "AgentProcessing") {
handleBackgroundTimeExpired()
}
}

func handleBackgroundTimeExpired() {
for session in sessions where session.status == .running {
session.status = .backgrounded
Task { await saveSession(session) }
}
}

func handleForeground() {
for session in sessions where session.status == .backgrounded {
Task { await resumeSession(session) }
}
}

这段时间应当用于:

  • 尽可能完成当前工具调用
  • 保存 checkpoint
  • 平滑过渡到后台状态

对于真正需要长时间运行的代理,应考虑使用服务器端调度器运行,移动端仅作为展示与输入界面。


本地 vs 云端(On-device vs cloud)

组件 本地 云端
调度
工具执行(文件、照片、健康数据)
LLM 调用 ✓(Anthropic API)
Checkpoint ✓(本地文件) 可选(iCloud)
长时间运行代理 受 iOS 限制 可行

应用在推理时需要网络,但在离线状态下仍可访问本地数据。工具设计应在网络不可用时优雅降级。


高级模式(Advanced patterns)

动态能力发现(Dynamic capability discovery)

Needs validation

以下模式来自 Claude 在构建过程中的实践探索,Dan 仍在形成自己的判断。针对不同用例,可能存在更优方案。

在与外部 API 集成时,一种常见做法是:为 API 的每一个端点构建一个对应的工具。但这种静态映射存在明显问题。

静态映射的问题

1
2
3
4
5
6
7
// 你为 50 种数据类型构建了 50 个工具
read_steps()
read_heart_rate()
read_sleep()
// 当 API 新增一个指标时……
// 需要修改代码
// Agent 只能访问你事先预想过的内容

这种方式限制了代理的能力范围,并增加了维护成本。


动态能力发现

1
2
3
4
5
6
7
// 用两个工具覆盖所有能力
list_available_types() // 返回 ["steps", "heart_rate", "sleep", ...]
read_data(type) // 读取任意已发现的类型

// 当 API 新增指标时……
// Agent 会自动发现
// 无需修改代码

这是将“粒度”原则推向逻辑极限的结果:

  • 工具足够原子
  • 能够作用于构建时尚不存在的类型

何时使用动态能力发现

  • 外部 API,希望代理拥有与用户等价的访问能力(如 HealthKit、HomeKit、GraphQL)
  • 系统能力会随时间扩展
  • 希望代理能够访问 API 支持的全部内容

何时静态映射已经足够

  • 有意限制范围的代理
  • 需要对访问内容进行严格控制
  • API 简单、稳定、端点固定

该模式的核心是:

一个工具用于发现能力,一个工具用于访问任意已发现的能力。

将校验交给 API 本身,而不是在工具定义中通过枚举提前固化。


CRUD 完整性(CRUD completeness)

对系统中的每一种实体,都应确认代理具备完整的 CRUD 能力:

  • Create:是否能创建?
  • Read:是否能查看已有内容?
  • Update:是否能修改?
  • Delete:是否能删除?

审计方法

列出系统中的所有实体,并逐一检查这四种操作是否都对代理开放。

常见失败场景

你实现了 create_noteread_notes,但忘记了 update_notedelete_note。当用户让代理“修正我会议记录里的一个错别字”时,代理将无能为力。


从代理到代码(Graduating to code)

有些操作最终需要从“代理协调”升级为“优化后的代码实现”,以满足性能或可靠性要求。

一个常见演进路径是:

  1. 代理使用原语在循环中完成任务
    灵活,用于验证概念

  2. 为常见操作添加领域工具
    更快,仍由代理主导

  3. 将高频路径实现为优化代码
    快速、确定性强


重要前提

即使某个操作已经“毕业”为代码实现:

  • 代理仍然应该能够触发该优化路径
  • 并在遇到边缘情况时,回退到原始原语

“毕业”只关乎效率,而不是能力限制。对等性原则仍然成立。


动态系统的设计直觉

随着系统复杂度的提升:

  • 不要急于为每一种情况编写代码
  • 先让代理通过原语探索问题空间
  • 再将稳定、高频的模式固化为工具或代码

这样,你构建的是一个可生长的系统,而不是一组僵化的功能。


反模式(Anti-patterns)

以下做法并不一定是“错误”的,在某些场景下也可能是合理的选择。但它们并不符合本文所描述的 agent-native 架构,因此有必要明确区分。


将 Agent 作为路由器(Agent as router)

在这种模式下,代理的职责只是:

  • 理解用户意图
  • 选择并调用正确的函数

代理的智能仅用于分发请求,而不是执行任务本身

这种方式是可行的,但你只使用了代理能力的一小部分。


先构建应用,再添加 Agent(Build the app, then add agent)

你先用传统方式实现功能(以代码形式),然后再把这些功能暴露给代理。

结果是:

  • 代理只能做你已经明确构建过的事情
  • 系统不会产生涌现能力

这种路径会让你错过 agent-native 架构的核心价值。


请求 / 响应式思维(Request/response thinking)

代理接收输入,执行一次操作,然后返回输出。

这种模式忽略了 循环(loop)

  • agent-native 的核心是给代理一个“要达成的结果”
  • 代理在过程中处理意外情况
  • 直到结果完成

如果你的代理只是“一问一答”,那它仍然停留在传统范式中。


防御性过强的工具设计(Defensive tool design)

你因为习惯了防御性编程,而在工具中加入了大量限制:

  • 严格的枚举
  • 过度的输入校验
  • 多层权限检查

这在传统系统中是安全的,但在 agent-native 架构中会:

  • 限制代理处理未知情况的能力
  • 阻断涌现行为

应当将判断权留给代理,而不是全部写进工具。


幸福路径在代码里,Agent 只是执行者(Happy path in code)

你在代码中处理了所有边界情况,代理只负责调用。

这意味着:

  • 决策仍然在代码中
  • 代理只是一个执行接口

agent-native 的思路是:

  • 让代理处理边界情况
  • 让代码提供原语能力

具体反模式示例

Agent 执行你的工作流,而不是追求结果

1
2
3
4
5
6
7
# 错误示例:你写了完整工作流
def process_request(input):
category = categorize(input) # 你的代码在决策
priority = score_priority(input) # 你的代码在决策
store(input, category, priority)
if priority > 3:
notify()
1
2
3
# 正确思路:Agent 在循环中追求结果
tools: store_item, send_notification
prompt: "评估紧急程度 1-5,存储你的判断,若 >=4 则通知"

工作流形态的工具(Workflow-shaped tools)

analyze_and_organize 这样的工具,将判断逻辑封装进工具内部。

应当将其拆分为原语,让代理自行组合。


孤立的 UI 行为(Orphan UI actions)

用户可以通过 UI 完成某个操作,但代理无法完成同样的结果。

修复方式:维持 对等性(parity)


上下文饥饿(Context starvation)

代理不知道系统中“已经存在什么”。

用户说:“整理我的笔记”,但代理甚至不知道有笔记存在。

修复方式:

  • 向 system prompt 注入可用资源
  • 注入能力范围

无理由的能力门控(Gates without reason)

某个领域工具是唯一可行路径,但你并没有真正打算限制访问。

默认原则应当是:开放。只有在安全或数据完整性确有需要时才引入门控。


人为制造的能力限制(Artificial capability limits)

出于模糊的安全担忧而限制代理能力。

正确做法是:

  • 保留能力
  • 通过审批流程控制高风险操作

而不是直接移除能力。


本可动态却静态映射(Static mapping where dynamic would work better)

当“发现 + 访问”模式可以带来更强灵活性时,却构建了大量静态工具。

这会降低系统的可扩展性和未来适应能力。


启发式完成判断(Heuristic completion detection)

通过以下方式判断代理是否完成:

  • 连续几轮没有工具调用
  • 检查是否生成了某个文件

这种方式极其脆弱。

修复方式:

  • 要求代理显式发出完成信号

这些反模式的共同特征是:

将判断重新塞回代码,而不是交给代理。


成功标准(Success criteria)

以下清单用于判断你的系统是否真正符合 agent-native 架构。它既是设计时的自检表,也是实现后的验收标准。


架构(Architecture)

  • 代理能够完成用户通过 UI 能完成的任何事情(对等性)
  • 工具是原子能力;领域工具只是快捷方式,而不是唯一通路(粒度)
  • 可以通过编写新的 prompt 来添加新功能(可组合性)
  • 代理能够完成你未明确设计过的任务(涌现能力)
  • 改变行为意味着修改 prompt,而不是重构代码

实现(Implementation)

  • system prompt 中包含可用资源与能力说明
  • 代理与用户在同一数据空间中工作
  • 代理的行为能够立即反映在 UI 中
  • 系统中的每一种实体都具备完整的 CRUD 能力
  • 外部 API 在合适场景下使用动态能力发现
  • 代理通过显式信号声明完成,而不是依赖启发式判断

产品(Product)

  • 最简单的请求可以立即生效,无学习成本
  • 高级用户可以将系统推向你未预期的方向
  • 你通过观察用户让代理做什么来学习真实需求
  • 审批与自主权设计与风险等级和可逆性相匹配

移动端(Mobile)

  • Checkpoint / Resume 能够应对应用中断
  • 采用 iCloud 优先、本地兜底的存储策略
  • 后台执行能够高效利用有限时间

终极测试(The ultimate test)

向代理描述一个属于你应用领域内,但你从未为其构建过专门功能的结果

问题只有一个:

它能否在循环中自行推理、组合工具,直到完成这个结果?

  • 如果答案是 —— 你构建的是一个真正的 agent-native 系统。
  • 如果答案是 —— 你的架构仍然过于受限。

Agent-native 架构:代码终结之后,应用该如何构建
https://ai123.win/2026/01/11/Agent-native 架构:代码终结之后,应用该如何构建/
作者
AIs
发布于
2026年1月11日
许可协议