1. 这不是新赛道,是 runtime 层的“操作系统时刻”来了
你有没有在深夜调试一个跑了三小时的 AI 代理,突然发现它开始胡言乱语,而日志里只有一行模糊的context window exceeded?或者更糟——它没报错,只是悄悄把前两步调用的 API 返回结果给“忘了”,然后基于残缺记忆生成了一份完全错误的采购合同?我去年就栽在这上面。团队花了四天重写状态管理模块,把所有中间结果从 prompt 里抠出来,存进 Redis,再用唯一 session ID 去关联。做完那一刻我才真正明白:当 agent 的“记忆”还赖在模型上下文里,它就永远不是个可信赖的生产级服务,而只是一个精致的、会自我瓦解的玩具。
Anthropic 在 4 月 8 日发布的 Claude Managed Agents,表面看是一套托管运行时,但它的核心价值根本不在“托管”二字上。它真正交付的,是一个被工程化验证过的、可落地的session-as-event-log 架构范式。这个范式把 agent 的“生命史”从 volatile(易失)的 token 流里解放出来,变成一份持久、可查询、可回溯、可审计的事件日志。Harness(执行器)变轻了,它只负责按需拉起沙箱、执行工具调用、返回字符串;Session(会话)变重了,它成了独立于模型之外的、有自己生命周期的实体;Sandbox(沙箱)则彻底沦为“牛”——用完即焚,按需创建,绝不留痕。
这背后的技术逻辑,和 90 年代操作系统虚拟化硬件如出一辙。当年,程序员不用再为不同 CPU 的寄存器寻址方式发愁,因为 OS 抽象出了统一的内存地址空间和文件描述符。今天,开发者也不必再为 Claude 3.5 Sonnet 的 200K 上下文和未来某款新模型的 1M 上下文做适配性重构,因为 Managed Agents 提供了稳定的awake(sessionId)接口。模型可以换,工具可以加,但 session 的事件流结构不变。这才是它值得被认真对待的原因——它不是又一个“更快的 API”,而是试图定义 agent 时代的“系统调用”。
关键词“Towards AI - Medium”在这里不是平台标签,而是一种信号:这篇文章的读者,是那些已经亲手写过 LangChain Chain、部署过 CrewAI Agent、被 context overflow 烧过眉毛的实战派。他们不需要听“agent 将改变世界”的宏大叙事,他们只想知道:这个东西能不能让我明天就少改 200 行状态管理代码?能不能让 QA 同事不再指着日志说“这一步到底调没调 Slack?”?能不能让法务在审计时,直接导出一份带时间戳、工具名、输入输出全量的 PDF?答案是:能,而且它已经上线了。这不是未来蓝图,是今天就能抄作业的生产环境方案。
2. 核心设计拆解:为什么是 YAML + Event Log + MicroVM,而不是别的?
2.1 架构分层:Harness、Session、Sandbox 的三角铁律
Managed Agents 的架构图看起来简洁,但每一层的设计选择都直指过去两年 agent 工程实践中最痛的三个点。我们来一层层剥开:
Harness(执行器)必须是 stateless(无状态)的。这是 Anthropic 最清醒的判断。很多团队早期会把 session state 存在 Harness 进程的内存里,或者用本地文件缓存。这在单机测试时没问题,一旦上 K8s 做滚动更新或水平扩缩容,进程重启,state 就丢了。Managed Agents 强制 harness 只做一件事:收到
execute(tool_name, input)请求,就去调度一个 sandbox,等结果回来,原样返回。它不记事,不决策,不缓存。这种“傻瓜式”设计,换来的是极致的可伸缩性和可靠性。你可以放心地把它部署在 100 个节点上,任何一个挂了,流量切走就行,session 不受影响。这背后是深刻的工程哲学:把复杂性推到边界,让核心路径尽可能薄。Session(会话)必须是 durable(持久化)且 external(外部化)的。这是全文的题眼。Managed Agents 的 session 不是存在某个数据库表里,而是以事件日志(event log)的形式存在。每一次 tool call、每一次 model response、每一次 guardrail 触发,都被序列化为一条结构化事件,打上时间戳、session ID、trace ID,写入底层存储。这意味着:
- 可回放(Replayable):你可以在任意时间点,用
replay(sessionId, fromEventId)重新跑一遍整个会话,验证修复是否生效。 - 可审计(Auditable):法务或安全团队要查“这个 agent 是如何批准一笔 50 万美金付款的?”,你直接导出从
tool_call: approve_payment到model_response: approved的完整事件链。 - 可补偿(Compensatable):如果某次
send_email工具调用失败,你可以基于事件日志,精准定位到那条失败事件,手动重试或触发补偿流程,而不是重启整个会话。
- 可回放(Replayable):你可以在任意时间点,用
Sandbox(沙箱)必须是 cattle(牲畜),而非 pets(宠物)。这个词用得极准。传统做法是给每个 agent 配一个长期运行的 Docker 容器,里面装着 Python 环境、依赖包、甚至硬编码的 API Key。这导致沙箱成了需要精心呵护的“宠物”——要打补丁、要监控内存、要处理僵尸进程。Managed Agents 的沙箱是“牲畜”:每次 tool call 都是一个全新的、最小化的 microVM 实例。它启动快(官方数据 p50 < 120ms),生命周期短(通常几秒到几分钟),用完即焚。最关键的是,credentials(凭证)绝不以环境变量形式注入。而是由 Anthropic 的 vault 服务,在沙箱启动瞬间,通过安全通道将临时 token 注入其内核,且该 token 无法被用户代码读取或导出。这堵死了绝大多数 LLM 注入攻击的入口——模型再怎么“幻觉”,也拿不到它不该看到的密钥。
提示:这个 credential 隔离机制,是经过血泪教训的。我见过最惨的一次事故:一个 RAG agent 在解析用户上传的 PDF 时,被恶意构造的文本诱导,生成了一条
curl -H "Authorization: Bearer xxx"命令。因为密钥就躺在环境变量里,这条命令真的被执行了,导致整个 AWS 账户的 IAM 密钥被泄露。Managed Agents 的设计,就是从根子上杜绝这种可能性。
2.2 为什么选 YAML 作为配置语言?而不是 JSON 或 DSL?
很多人第一反应是:“YAML?太老土了吧,不如搞个图形化界面!” 但 Anthropic 的选择恰恰体现了对开发者工作流的深刻理解。
YAML 的可读性与可维护性碾压 JSON。一个典型的 agent 配置,包含 system prompt、tools 列表、guardrails 规则、timeout 设置等。用 JSON 写,会充斥着
{}和[],嵌套三层后,人眼几乎无法快速定位tools[1].auth.type。而 YAML 的缩进语法,天然契合配置的层级结构。更重要的是,YAML 支持注释(#),这意味着你可以直接在配置文件里写:# 生产环境禁用此工具,仅用于 QA 验证 - name: "debug_print" description: "Print debug info to console" disabled: true这种能力,JSON 永远做不到。
YAML 是 DevOps 的通用语。K8s manifests、Terraform backend 配置、GitHub Actions workflows,全都是 YAML。一个 SRE 工程师,不需要额外学习一门新语言,就能立刻上手修改 agent 的超时策略或资源限制。它降低了跨职能协作的门槛。
YAML 天然支持多文档(--- 分隔)。这为大型 agent 项目提供了模块化可能。你可以把
system_prompt.yaml、tools.yaml、policies.yaml分开维护,再用 CI/CD 流水线合并成最终部署包。这种工程实践,是任何自研 DSL 都难以企及的成熟度。
当然,YAML 也有坑,比如缩进空格 vs Tab 的经典战争,以及yamllint工具链的必要性。但权衡之下,它依然是当前生态里,平衡了表达力、可读性、工具链成熟度的最优解。
2.3 定价模型:$0.08/小时,是陷阱还是甜点?
$0.08 每 session-hour 的定价,初看很便宜,但必须结合使用场景来算账。
Session-hour 的定义是关键。它不是 agent 启动后就一直计费,而是指 session 处于“活跃”状态的时间。什么是活跃?官方定义是:从
create_session()被调用,到该 session 最后一次execute()返回,之间的时间窗口。如果一个 session 创建后,用户 2 小时没操作,它不会计费;但只要有一次execute(),计费就会从这次调用开始,持续到下次调用(或 session 关闭)。所以,对于一个高频交互的客服 agent,计费时长接近真实在线时长;而对于一个低频的周报生成 agent,计费时长可能只有几分钟。成本构成是叠加的。$0.08/session-hour 只是 runtime 成本,不包含 Claude 的 token 费用。后者是按输入/输出 token 单独计费的。这意味着你的总成本 =
$0.08 * active_hours + (input_tokens * $0.000003 + output_tokens * $0.000015)(以 Claude 3.5 Sonnet 为例)。一个典型场景:一个销售 agent 帮客户生成报价单,平均每次会话耗时 8 分钟(0.13 小时),消耗 1200 输入 tokens 和 800 输出 tokens。那么单次会话成本 ≈$0.08 * 0.13 + (1200*0.000003 + 800*0.000015) = $0.0104 + $0.0036 + $0.012 = $0.026。这个价格,对于一个能替代人工销售助理的 agent 来说,极具竞争力。真正的成本杀手是“长尾”会话。那些需要跨天、跨周完成的复杂任务(比如“帮我调研并对比三家云厂商的 GPU 实例价格,生成 PPT”),session 会一直保持活跃。此时,runtime 成本会成为大头。这时,你需要主动设计
pause_session()和resume_session()逻辑,在 agent 等待用户反馈或外部系统响应时,主动暂停 session,停止计费。这要求你在业务逻辑里,把“等待”这个状态显式建模出来,而不是让它隐式地躺在 context 里。
注意:不要被低价迷惑。$0.08 是一个“锚定价格”,它的意义在于告诉市场:runtime 层的边际成本已经低到可以忽略不计。真正的战场,不在这里,而在上层。
3. 实操过程:从零部署一个“会议纪要生成 Agent”
光说不练假把式。下面我带你完整走一遍,如何用 Managed Agents 部署一个真实的、能接入企业微信的会议纪要生成 agent。这个例子覆盖了所有核心环节:配置编写、工具开发、沙箱集成、会话管理、事件追踪。
3.1 第一步:定义 agent.yaml —— 你的 agent “宪法”
我们先写一个最简但完整的agent.yaml。它定义了 agent 的身份、能力、规则和底线。
# agent.yaml name: "meeting-minutes-agent" description: "An agent that generates professional meeting minutes from audio transcripts and participant lists." system_prompt: | You are a meticulous and professional meeting secretary. Your task is to generate concise, action-oriented meeting minutes. Always follow these rules: 1. Extract key decisions, action items (with owners and deadlines), and open questions. 2. Never invent facts not present in the transcript. 3. If the transcript is too short (< 200 words) or contains no clear decisions, respond with: "Transcript insufficient for meaningful minutes." 4. Format output in Markdown with clear headings. tools: - name: "get_transcript" description: "Fetch the full audio transcript from the specified meeting ID." input_schema: type: "object" properties: meeting_id: type: "string" description: "The unique ID of the meeting in our internal system." - name: "get_participants" description: "Get the list of participants and their roles for the meeting." input_schema: type: "object" properties: meeting_id: type: "string" description: "The unique ID of the meeting in our internal system." - name: "send_to_wechat" description: "Send the generated minutes to the specified WeCom group chat." input_schema: type: "object" properties: group_id: type: "string" description: "The WeCom group ID where minutes should be posted." content: type: "string" description: "The Markdown-formatted minutes content." guardrails: - type: "content_filter" severity: "block" categories: ["harassment", "hate", "self-harm"] - type: "tool_call_filter" allowed_tools: ["get_transcript", "get_participants", "send_to_wechat"] blocked_patterns: ["rm -rf", "curl.*http://127.0.0.1"] timeout_seconds: 120这个 YAML 文件就是 agent 的“宪法”。它清晰地界定了:
- 你能做什么(tools):只能调用三个特定工具,且每个工具的输入格式都有严格 schema。
- 你不能做什么(guardrails):内容过滤器会拦截有害输出;工具调用过滤器会阻止任何危险的 shell 命令或非法工具调用。
- 你的行为准则(system_prompt):用自然语言规定了输出风格、事实核查要求和格式规范。
3.2 第二步:实现工具函数 —— 沙箱里的“肌肉”
Managed Agents 要求所有工具函数都必须是无状态的、幂等的、且能被沙箱安全执行。我们以get_transcript为例,展示一个生产级的实现。
# tools/get_transcript.py import os import json import requests from typing import Dict, Any def get_transcript(meeting_id: str) -> Dict[str, Any]: """ Fetches the meeting transcript from our internal API. Uses a short-lived, scoped token fetched from Anthropic's vault. """ # 1. Get the scoped token from the secure vault (this is handled by Anthropic) # In your code, you just read it from a predefined path try: with open("/run/secrets/transcript_api_token", "r") as f: api_token = f.read().strip() except FileNotFoundError: raise RuntimeError("Transcript API token not available in sandbox") # 2. Call our internal transcript service headers = { "Authorization": f"Bearer {api_token}", "Content-Type": "application/json" } url = f"https://api.internal.corp/transcripts/{meeting_id}" try: response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() data = response.json() # 3. Sanitize and return only what the model needs return { "success": True, "transcript": data.get("text", ""), "word_count": len(data.get("text", "").split()), "duration_minutes": data.get("duration", 0) } except requests.exceptions.RequestException as e: return { "success": False, "error": f"Failed to fetch transcript: {str(e)}" } except json.JSONDecodeError: return { "success": False, "error": "Invalid JSON response from transcript service" }关键点解析:
- 凭证安全:我们没有把 API Token 写死在代码里,也没有通过环境变量传入。而是通过
/run/secrets/这个标准 Linux secrets mount point 来读取。这是容器编排领域的最佳实践,Anthropic 的沙箱完美支持。 - 错误处理:函数返回一个结构化的字典,明确区分
success: True/False,并附带详细的error信息。这能让模型在success为False时,准确地向用户解释失败原因,而不是抛出一个无法理解的异常。 - 输入输出契约:函数签名
def get_transcript(meeting_id: str) -> Dict[str, Any]和 YAML 中的input_schema必须严格一致。这是类型安全的基石。
3.3 第三步:创建会话与驱动执行 —— 你的“大脑”在哪里?
Managed Agents 的核心思想是:Harness 不是大脑,它是手和脚;真正的“大脑”是你写的 system prompt 和工具组合逻辑。所以,你的应用代码(比如一个 FastAPI 服务)只需要做三件事:
- 创建会话(create_session)
- 驱动执行(execute)
- 查询事件(list_events)
下面是一个精简的 FastAPI 示例:
# app.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import anthropic app = FastAPI() client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY")) class MeetingRequest(BaseModel): meeting_id: str wecom_group_id: str @app.post("/generate-minutes") async def generate_minutes(request: MeetingRequest): try: # 1. Create a new session session = client.sessions.create( agent_id="your-managed-agent-id", metadata={"source": "webhook", "meeting_id": request.meeting_id} ) # 2. Kick off the first execute - this will trigger the agent # The agent will use its system_prompt to decide which tool to call first result = client.sessions.execute( session_id=session.id, tool_name="get_transcript", input={"meeting_id": request.meeting_id} ) # 3. The agent will now run its loop: call tools, get responses, make decisions # We don't need to orchestrate this! It's all handled by the Harness. # We just wait for the final output, or handle intermediate events. # For simplicity, we'll poll for the final result (in prod, use webhooks) import time for _ in range(10): # Poll for up to 10 seconds time.sleep(1) events = client.sessions.list_events( session_id=session.id, limit=10, order="desc" ) # Look for the final model response event for event in events.data: if event.type == "model_output": return {"minutes": event.content, "session_id": session.id} raise HTTPException(status_code=500, detail="Timeout waiting for minutes") except Exception as e: raise HTTPException(status_code=500, detail=str(e))这段代码的精妙之处在于它的“懒惰”。它没有去解析result的内容,也没有去决定下一步该调哪个工具。它只是创建了一个会话,然后把初始输入(meeting_id)扔给了 agent。之后的一切——是先调get_transcript还是get_participants,是调一次还是三次,是生成 Markdown 还是纯文本——都由 agent 自己根据system_prompt和工具返回的结果来决策。你的应用代码,退化成了一个纯粹的“会话生命周期管理者”。
3.4 第四步:事件追踪与调试 —— 你的“黑匣子”记录仪
当 agent 出现问题时,list_eventsAPI 就是你的救命稻草。假设用户反馈:“我让 agent 生成会议纪要,但它回复说‘Transcript insufficient’,可我明明传了一个 5000 字的录音!” 这时,你不需要猜,直接查事件日志:
# 使用 curl 查询最近 5 条事件 curl -X GET \ "https://api.anthropic.com/v1/sessions/{session_id}/events?limit=5&order=desc" \ -H "x-api-key: YOUR_API_KEY" \ -H "anthropic-version: 2023-06-01"你会得到类似这样的响应:
{ "data": [ { "id": "evt_abc123", "type": "tool_call", "timestamp": "2026-04-12T10:15:22.123Z", "tool_name": "get_transcript", "input": {"meeting_id": "mtg-789"} }, { "id": "evt_def456", "type": "tool_result", "timestamp": "2026-04-12T10:15:25.456Z", "tool_name": "get_transcript", "output": { "success": true, "transcript": "Hello everyone... [truncated to 198 words]", "word_count": 198 } }, { "id": "evt_ghi789", "type": "model_output", "timestamp": "2026-04-12T10:15:28.789Z", "content": "Transcript insufficient for meaningful minutes." } ] }真相大白:get_transcript工具返回的word_count是 198,触发了system_prompt中的第 3 条规则。问题不在 agent,而在你的get_transcript工具实现——它截断了长文本!解决方案很简单:修改工具,确保返回完整 transcript,或者调整system_prompt的阈值。
这就是 event log 的力量。它把原本不可见的、发生在黑盒中的推理过程,变成了可观察、可测量、可归因的数据流。
4. 常见问题与排查技巧实录:踩过的坑,比文档还管用
4.1 典型问题速查表
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
execute()调用后,长时间无响应,最终超时 | 1. 工具函数内部死循环或网络阻塞 2. system_prompt过于模糊,导致 agent 陷入无限 tool-call 循环3. 沙箱资源不足(CPU/Memory) | 1. 查看list_events,确认最后一条事件是tool_call还是tool_result2. 检查 tool_result事件的output字段,看是否有错误信息3. 在工具函数中添加 print(f"[DEBUG] Starting {tool_name}")日志 | 1. 在工具函数中增加timeout参数和重试逻辑2. 在 system_prompt中加入明确的终止条件,例如:“如果连续两次调用同一工具未获得新信息,则停止调用并总结。”3. 在 agent.yaml中增加resources配置项,为沙箱分配更多内存 |
tool_result事件中output字段为空或格式错误 | 1. 工具函数未按约定返回Dict[str, Any]2. 工具函数抛出未捕获异常,被沙箱静默吞掉 3. input_schema与实际传入参数不匹配 | 1. 在本地用相同参数运行工具函数,检查返回值 2. 查看沙箱的 stdout/stderr 日志(可通过 Anthropic 控制台或 list_events中的sandbox_log事件获取)3. 使用 jsonschema.validate()在函数入口校验输入 | 1. 严格遵循函数签名,用pydantic.BaseModel定义输入输出 Schema2. 在工具函数最外层用 try/except包裹,确保所有异常都转化为结构化错误输出3. 在 agent.yaml的input_schema中,为每个字段设置default值,提高鲁棒性 |
model_output事件中出现敏感信息(如 API Key) | 1.system_prompt未禁止模型输出凭证2. Guardrail 的 content_filter未启用或配置不当3. 工具返回的 output中已包含敏感信息 | 1. 检查agent.yaml中guardrails配置是否生效2. 在 system_prompt中加入强约束:“绝对禁止在任何输出中显示任何形式的 API Key、Token、密码或内部 URL。”3. 审计所有工具函数的 output字典,确保不返回原始凭证 | 1. 启用content_filter并设置severity: block2. 在工具函数中,对所有返回的 output字典进行后处理,用正则表达式脱敏所有疑似密钥的字段3. 使用 tool_call_filter明确禁止调用任何可能暴露凭证的工具 |
会话active时间远超预期,导致费用激增 | 1. 应用代码未在用户交互间隙调用pause_session()2. system_prompt中未定义“等待用户输入”的明确指令,导致 agent 一直尝试自主决策3. timeout_seconds设置过大 | 1. 在list_events中查找tool_call和model_output的时间间隔,确认是否存在长时间空闲2. 检查 agent.yaml中的timeout_seconds是否合理(建议 30-120 秒) | 1. 在应用逻辑中,当 agent 的model_output包含“请提供更多信息”、“请确认以下选项”等提示时,立即调用pause_session()2. 在 system_prompt中加入:“当需要用户提供额外信息时,明确告知用户,并停止进一步行动,等待用户下一次execute。” |
4.2 我踩过的三个“血泪坑”
坑一:把system_prompt当作文档,而不是“宪法”
我最初写system_prompt时,把它当成一份技术规格说明书,堆砌了大量细节:“你应该先调 A 工具,再调 B 工具,A 工具的输入是 X,B 工具的输出要解析为 Y…” 结果 agent 表现极其僵硬,一旦get_transcript返回的格式稍有变化,它就卡死。后来我才悟到:system_prompt的核心作用是定义 agent 的角色、目标和原则,而不是指挥它每一步怎么走。我把 prompt 重写为:“你是一位专业的会议秘书。你的唯一目标是生成高质量的会议纪要。为此,你需要获取会议内容和参与者信息。如果任一信息缺失,你应明确告知用户,而不是猜测。” 效果立竿见影,agent 变得健壮且灵活。
坑二:低估了tool_call_filter的威力
为了快速上线,我一开始把allowed_tools设为["*"],想着“先跑起来再说”。结果 agent 在一次调试中,真的调用了os.system("ls -la")(虽然沙箱里没这个命令,但这个念头本身就很危险)。tool_call_filter的存在,不是为了防君子,而是为了防小人——包括那个被 prompt engineering 带偏了的、正在“幻觉”的 LLM。现在,我的所有agent.yaml文件,allowed_tools都是精确到具体函数名的白名单,一个都不能多。
坑三:在沙箱里做“重活”,忘了 Harness 的职责
有一次,我需要对一个 10MB 的 PDF 做 OCR。我本能地想把tesseract安装到沙箱里,然后在工具函数里调用。结果发现沙箱启动时间飙升到 5 秒,且 OCR 过程不稳定。后来我意识到:Harness 的设计哲学是“轻”,而 OCR 是“重”。正确的做法是,把 OCR 作为一个独立的、高可用的微服务(比如用 AWS Textract),然后让get_pdf_content工具函数去调用这个服务。沙箱只负责发起一个 HTTP 请求,拿到结果。这样,沙箱启动快、执行稳,而重活交给了专业服务。
实操心得:Managed Agents 的最大心智转变,是接受“Harness 不是你的计算单元,它只是你的调度员”。把计算密集型、IO 密集型、状态密集型的任务,全部剥离出去,做成独立的、可扩展的、可观测的微服务。Harness 只负责 orchestrating(编排),不负责 computing(计算)。
5. 竞争格局与价值迁移:为什么 runtime 层注定走向“零价”?
5.1 不是 Anthropic 在开创,而是在防御
把 Anthropic 的 Managed Agents 放在更大的产业图谱里看,它的真实定位就非常清晰了。文章里提到的 Amazon Bedrock AgentCore,早在 2025 年底就已进入 GA(正式发布)阶段。到 2026 年 3 月,其 SDK 下载量已突破两百万。AWS 的 AgentCore 不是概念验证,而是已经承载了海量生产流量的基础设施。它同样提供 microVM 沙箱、session 管理、policy controls,并且,最关键的是,它原生支持 Claude 模型。
这意味着什么?意味着对于一个正在评估技术栈的 CTO 来说,他的选择题从来就不是“用 Anthropic 还是用 AWS?”,而是“用 AWS 的 AgentCore + Claude,还是用 Anthropic 的 Managed Agents + Claude?” 前者是免费的(计入 AWS 账单),后者是收费的($0.08/hour)。在这种情况下,Anthropic 的产品,本质上是一场防御战:它不是在争夺“runtime 层”的王冠,而是在防止自己的核心资产——Claude 模型的 token 销售额——被 AWS 的免费 runtime 所虹吸。如果开发者可以在 AWS 上无缝、免费地运行一个 Claude agent,那他们为什么还要为 Anthropic 的托管 runtime 付费?Anthropic 的答案是:用更好的 developer experience(DX)、更严格的 security posture(安全姿态)、更深度的 tooling integration(工具集成)来建立壁垒。但这壁垒,终究是商业层面的,而非技术层面的护城河。
5.2 历史的镜像:VMware 与开源 Hypervisor 的兴衰
Anthropic 的工程师在博客里自豪地将 Managed Agents 比作“90 年代的操作系统”,这个类比非常精准,但也暗含了残酷的预言。让我们复盘一下虚拟化的历史:
- 1999年:VMware 凭借 ESX hypervisor,开创了 x86 虚拟化时代,成为企业软件的明星。
- 2003年:开源 Xen 项目诞生,性能和功能迅速追赶。
- 2007年:KVM(Kernel-based Virtual Machine)被合并进 Linux 主线内核,虚拟化成为操作系统的一部分。
- 2010年代:AWS、GCP、Azure 将虚拟化作为 IaaS 的基础能力,免费提供。它不再是“产品”,而是“水电煤”一样的基础设施。
- 2020年代:VMware 依然存在,仍有巨大营收,但整个行业的创新和价值增长,已经完全转移到了上层:Terraform(基础设施即代码)、Kubernetes(容器编排)、Service Mesh(服务网格)。
Managed Agents 正站在同样的历史岔路口。AWS AgentCore、Google Vertex AI Agent Builder、Microsoft Azure AI Foundry,这些 hyperscaler(超大规模云厂商)的产品,其战略目标从来就不是“卖 runtime”,而是“让 runtime 变得无关紧要,从而让你更离不开我的云”。它们会把 runtime 做得足够好、足够快、足够安全,然后把它打包进你的云账单里,让你感觉不到它的存在。当 runtime 的成本趋近于零,它的技术差异性也就消失了。
5.3 价值上移:Trace Store、Governance、Vertical Marketplaces 的崛起
当 runtime 层被压缩为“零价”基础设施,价值必然向上迁移。目前,有三个方向已经清晰可见:
Trace Store(追踪存储):谁拥有 agent 的“黑匣子”数据?Braintrust 的 Brainstore、Arize 的 Phoenix、LangChain 的 LangSmith,都在争夺这个位置。它们的价值不在于“展示日志”,而在于“成为系统唯一真相源(Single Source of Truth)”。当你的 agent 从 Anthropic 迁移到 AWS,或者从云端迁移到私有集群,你的 trace 数据能否无缝迁移?谁能提供跨 runtime 的 trace portability,谁就拥有了不可替代的粘性。这就像 Kubernetes 的 CRD(Custom Resource Definition),它不关心你用哪家云,只关心你的应用定义。
Governance & Policy(治理与策略):当 agent 开始审批付款、访问 HR 数据、生成法律文件时,“它被允许做什么”就成了生死攸关的问题。AWS 的 AgentCore Policy Controls、OWASP 的 Agentic Top 10,都在构建这个领域的标准。未来的 CISO(首席信息安全官)会问:“你们的 agent 有哪些权限?谁批准的?审计日志在哪里?” 这不是一个技术问题,而是一个合规问题。谁能提供企业级的 policy-as-code、RBAC(基于角色的访问控制)、自动化的合规报告,谁就能在 enterprise sales(企业销售)中占据高地。
Vertical Agent Marketplaces(垂直领域 agent 商店):Salesforce 的 Agentforce ARR 达到 8 亿美元,这不是靠卖“runtime”赚来的,而是靠卖“销售开发 agent”、“客户服务 agent”、“财务分析 agent”这些能直接解决业务问题的“成品”。这印证了一个真理:企业为“结果”付费,不为“技术”付费。一个能帮你把销售线索转化率提升 15% 的 agent,其价值远高于一个“支持 100K context 的 runtime”。Virattt 的 ai-hedge-fund、Vxcontrol 的 pentagi,这些开源项目,正是未来垂直市场的种子。资本已经涌入,因为大家都知道,当底层基建 commoditize(商品化)后,真正的利润,永远在能直接创造业务价值的应用层