1. 这不是新赛道,是 runtime 层的“操作系统时刻”来了

你有没有在深夜调试一个跑了三小时的 AI agent,眼睁睁看着它在第 187 步突然开始胡言乱语,而你翻遍日志只看到一行模糊的 context_length_exceeded ?或者更糟——它没报错,只是 quietly hallucinated,把上一步从数据库查出的客户邮箱,替换成自己编造的、格式完全正确但根本不存在的地址,等你发现时,300 封营销邮件已经发了出去。这不是虚构场景,这是我去年在给一家保险科技公司做智能理赔助手时的真实事故。我们当时把所有 session state 塞进 Claude 的上下文窗口里,以为靠 prompt engineering 和 careful truncation 就能撑住。结果呢?它像一根被反复弯折的回形针,在某个临界点无声断裂。没有崩溃日志,没有可回溯的执行链,只有业务数据在静默中被污染。

Anthropic 在 4 月 8 日发布的 Claude Managed Agents ,表面看是一次常规的产品更新:支持 Notion、Asana 集成,有 sandboxed execution,checkpointed sessions,credential vaulting。媒体通稿里满是“十倍提速”、“下一代智能体架构”这类词。但如果你真去读他们那篇工程博客,会发现一个被刻意淡化、却重如千钧的核心命题: 他们正在把 AI agent 的 runtime 层,变成一个可独立演进、可持久化、可审计的操作系统抽象层 。关键词不是“agent”,而是 session-as-event-log harness-as-stateless-executor sandbox-as-cattle 。这和 90 年代 Linux 内核把硬件资源(CPU、内存、磁盘)虚拟化成统一的文件描述符和虚拟内存地址空间,本质上是同一类事情——把混乱、脆弱、与模型强耦合的执行环境,抽离成一组稳定、解耦、可替换的接口。

为什么这个时间点如此关键?因为就在 Anthropic 发布前五个月,AWS Bedrock AgentCore 已经进入通用可用阶段;Google Vertex AI Agent Builder 的 Registry 已通过 Apigee 深度集成;微软则把 AutoGen 和 Semantic Kernel 整合进了 Azure AI Foundry。整个市场不是在等待 Anthropic 来“开创”一个新类别,而是在等待一个信号: runtime 层的 commoditization(商品化)进程,是否已不可逆转? 答案是肯定的。Anthropic 这一拳,打的不是创新,而是防御——防御它的核心资产:Claude 模型的 token 收入。当 AWS 可以用免费的 microVM + 低廉的 session-hour 定价,把你的 Claude agent 托管在它的云上时,你还会为 Anthropic 的托管 runtime 买单吗?不会。你会为 Claude 的推理能力买单,但 runtime?它正快速滑向“零成本”的临界点。这篇文章要讲的,就是这个正在发生的、肉眼可见的底层坍塌,以及,当 runtime 归零时,钱到底会流向哪里。

2. 核心设计拆解:为什么是“Session-as-Event-Log”,而不是“Context-as-Storage”

2.1 旧范式的致命伤:把上下文当硬盘用

在 Managed Agents 出现之前,绝大多数自研 agent 系统都遵循一个朴素但危险的逻辑: 模型的上下文窗口,就是我的数据库、我的内存、我的日志系统 。我们用 system prompt 定义角色,用 few-shot examples 提供记忆,用 tool call 的返回结果拼接进 history,再喂给下一轮推理。听起来很自然,对吧?但问题在于,这个“硬盘”有三个无法绕开的硬伤:

  1. 容量硬上限 :Claude 3.5 Sonnet 的上下文是 200K tokens,听起来很大。但别忘了,这 200K 是模型输入的总长度,它必须同时容纳:system prompt(通常 2K-5K)、当前任务描述(1K)、历史对话(每轮至少 200-500 tokens)、上一轮 tool call 的完整 JSON 返回(可能高达 10K+)、以及留给模型生成 response 的空间。实测下来,一个需要调用 5 次 API、每次返回 2K 数据的复杂分析任务,往往在第 3 轮就触发了 context overflow。这时,主流框架(如早期 LangChain)的默认策略是 truncation —— 粗暴地砍掉最老的几轮对话。这就埋下了第一个雷: 你丢失了执行的因果链 。模型看到的是一段被截断的历史,它不知道自己为什么要做这件事,也不知道上一步的结论是什么,于是开始基于残缺信息进行“合理推测”,也就是 hallucination。

  2. 状态不可靠 :上下文是易失的。一次网络抖动导致的请求失败,一次模型随机采样产生的低概率输出,甚至一次不恰当的 temperature 设置,都可能导致上下文里混入错误信息。而这个错误信息,会像病毒一样,在后续所有轮次中被模型当作“事实”来引用和强化。我见过一个金融 agent,因为第一次解析 PDF 表格时把“Q1 Revenue”误读为“Q1 Revenu”,后面所有基于此的计算和报告,都建立在这个错误基石上,直到人工审计才发现。

  3. 审计与调试黑洞 :当 agent 出错时,你唯一能看的,就是最终的 response 和那一长串被截断、被混淆的上下文。你想知道它在第 7 步调用了哪个 API?传了什么参数?返回了什么?你得手动去 parse 那段几千行的 JSON history,而且如果它已经被 truncation 过,这段 history 本身就是不完整的。这就像让一个汽车修理工只凭最后的刹车失灵现象,去诊断发动机内部的故障,效率极低,且几乎不可能复现。

提示:我踩过的最大坑,是试图用 LLM 自己来“总结”和“压缩”长上下文。模型会非常自信地告诉你“我已经记住了所有要点”,但它总结的“要点”,往往是它自己脑补出来的、符合其内在 bias 的版本,而非原始数据的忠实映射。这比不总结更危险。

2.2 Anthropic 的解法:把“硬盘”搬出模型,放到外面

Managed Agents 的核心洞见,就是彻底承认: 模型的上下文,只应该做它最擅长的事——进行推理和生成。而状态管理、持久化、审计追踪,这些是传统软件工程的领域,应该交给专门的、可靠的、可扩展的外部系统 。这就是 “session-as-event-log” 模式的全部意义。

  • Session 不再是一个字符串,而是一个数据库记录 :每一次 agent 的启动( awake(sessionId) ),系统都会从一个持久化的、高可用的事件存储(比如 Amazon DynamoDB 或 Google Cloud Bigtable)中,加载该 sessionId 对应的完整事件流。这个事件流是一个严格有序的、不可变的 append-only log,记录着:

    • event_id: 1, type: "user_input", payload: "请分析这份财报"
    • event_id: 2, type: "tool_call", name: "pdf_parser", input: {"file_id": "abc123"}
    • event_id: 3, type: "tool_result", name: "pdf_parser", output: {"revenue_q1": 123456789}
    • event_id: 4, type: "llm_thinking", content: "Q1 revenue is $123.46M..."
    • event_id: 5, type: "tool_call", name: "send_email", input: {"to": "ceo@company.com", "body": "..."}

    这个 log 是原子性的、可查询的、可回放的。你可以随时 SELECT * FROM events WHERE session_id = 'xyz' ORDER BY event_id ,得到一份完美的、可审计的“黑匣子”记录。

  • Harness 是无状态的“快递员” Harness 这个概念,指的就是那个真正执行 execute(name, input) -> string 的轻量级运行时。它本身不保存任何状态,也不关心业务逻辑。它的工作流程极其简单:

    1. 接收一个 sessionId 和一个 step_id
    2. 从 event log 中,按需拉取最近 N 条相关事件(比如,只拉取 type: "user_input" type: "tool_result" 的事件,用于构建本次推理的 prompt)。
    3. 将这些事件组装成一个精简、高效的 prompt,喂给 Claude 模型。
    4. 解析模型的输出,识别出下一个 tool_call 指令。
    5. 调用对应的工具(这个工具本身也运行在一个隔离的 sandbox 中),并将结果作为一条新的 tool_result 事件,写入 event log。
    6. 结束,等待下一次 awake() 调用。

    这个过程,Harness 本身可以 crash、可以重启、可以水平扩容,因为它不持有任何 state。state 全在 event log 里。这就像一个快递员,他不需要记住每个客户的家庭住址,他只需要每次拿到一张写着“收件人ID”和“包裹内容”的单子,然后去查公司的中央数据库,找到对应地址,完成投递。他的工作是 stateless 的,系统的可靠性由数据库保证。

  • Sandbox 是“一次性容器”,不是“宠物服务器” Sandbox 的设计哲学是“cattle, not pets”。每次 tool_call 发起时,系统会动态 provision(供应)一个全新的、干净的、隔离的执行环境(可能是 Docker container,也可能是更轻量的 WebAssembly runtime)。这个 sandbox 的生命周期,仅限于本次 tool call 的执行。它启动、执行、返回结果、然后被立即销毁。最关键的是, credentials(API keys, database passwords)永远不会以环境变量或配置文件的形式注入到 sandbox 内部 。它们被安全地存放在 Anthropic 的 Vault 服务中,当 harness 需要调用一个工具时,它会向 Vault 请求一个临时的、有时效的、作用域受限的 access token,然后将这个 token 作为参数传递给 sandbox。sandbox 本身,永远看不到原始的、长期有效的密钥。这堵死了 LLM 通过 system prompt user input 诱导 agent 泄露密钥的最常见攻击路径。

注意:这种设计对开发者是友好的,但对运维是挑战。你需要一个能毫秒级启动、秒级销毁容器的 orchestration layer。Anthropic 显然投入了大量工程资源在底层的 sandbox provisioning latency 上,这也是他们敢承诺 p95 time-to-first-token >90% 的底气。如果你自己搭建,别指望用普通的 Kubernetes Deployment,得上 K3s + Firecracker microVM 或者类似的轻量级方案。

3. 实操细节与关键配置:如何真正用好 Managed Agents

3.1 定义你的 Agent:YAML vs. Natural Language,选哪个?

Managed Agents 允许你用两种方式定义 agent:一种是结构化的 YAML 文件,一种是自由的自然语言描述。很多新手会直接跳到后者,觉得“更简单”。但根据我帮三家客户落地的经验, 强烈建议从 YAML 开始,哪怕你最终目标是 NL

YAML 的优势在于 精确性、可版本控制、可自动化测试 。一个典型的 agent.yaml 文件长这样:

# agent.yaml
name: "Financial-Report-Analyzer"
description: "An agent that parses financial PDFs and generates executive summaries."

system_prompt: |
  You are a senior financial analyst at a Fortune 500 company.
  Your task is to extract key metrics (Revenue, Net Income, EBITDA) from quarterly reports
  and explain trends in plain English for non-finance executives.

tools:
  - name: "pdf_parser"
    description: "Extracts text and tables from a PDF file."
    input_schema:
      type: "object"
      properties:
        file_id:
          type: "string"
          description: "The unique ID of the PDF file stored in our S3 bucket."
    output_schema:
      type: "object"
      properties:
        revenue_q1:
          type: "number"
          description: "Revenue for Q1, in USD."
        net_income_q1:
          type: "number"
          description: "Net Income for Q1, in USD."

  - name: "send_slack_message"
    description: "Sends a formatted message to a Slack channel."
    input_schema:
      type: "object"
      properties:
        channel_id:
          type: "string"
          description: "The Slack channel ID (e.g., C012AB3CD)."
        summary:
          type: "string"
          description: "The executive summary text to send."

guardrails:
  - type: "output_safety"
    policy: "financial_data_only"
    action: "block_and_alert"
  - type: "input_validation"
    regex: "^Q[1-4] [0-9]{4} Report$"
    action: "reject_with_message"

这个 YAML 文件,就是一个可执行的合约。它清晰地定义了:

  • Agent 的身份和职责 system_prompt
  • 它能调用哪些工具,每个工具的输入/输出格式是什么 tools )—— 这是让 LLM 能精准调用工具的关键,远比一段模糊的自然语言描述可靠。
  • 它不能做什么,以及违规时的处理方式 guardrails )—— 这是生产环境的底线。

而自然语言描述,更适合在原型验证阶段,或者当你有一个非常成熟的、内部已知的工具集时,作为一种快捷方式。例如,你可以说:“用我们的内部 PDF 解析器分析这份财报,然后把结果发到 #finance-reports 频道。” 但这句话背后,依然依赖于一个预先注册好的、带有明确 schema 的 pdf_parser 工具。 NL 是语法糖,YAML 是骨架。

3.2 Pricing 模型:$0.08/session-hour 是怎么算出来的?

官方定价是 $0.08 per session-hour of active runtime ,外加标准的 Claude token 费用。这个“session-hour”是理解成本的关键,它 不是按你创建 session 的总时长计费,而是按 harness 实际在 CPU 上执行的时间累加

举个例子:

  • 你创建了一个 sessionId: abc123 的 session。
  • 第 1 分钟:用户输入,harness 启动,调用 pdf_parser (耗时 8 秒),收到结果,生成 summary(耗时 2 秒),结束。 计费:10 秒 ≈ 0.0028 小时 × $0.08 = $0.000224
  • 第 5 分钟:用户追问“Q1 和 Q2 的对比呢?”,harness 再次启动,从 event log 中加载历史,调用 pdf_parser (再次 8 秒),生成对比分析(3 秒)。 计费:11 秒 ≈ $0.000244
  • 这个 session 总共存在了 24 小时,但 harness 只活跃了 21 秒,所以总 runtime 费用约为 $0.000468 ,几乎可以忽略不计。

这和传统云服务的“按实例运行时间计费”有本质区别。它鼓励你创建 long-lived sessions(长达数天),因为闲置期间不收费。这也解释了为什么 Notion 能让用户“委托工作给 Claude”——一个 session 可以代表一个用户的整个工作流,跨越多个会议、多个文档,而成本依然可控。

实操心得:在设计 agent 时,要刻意追求“短平快”的 harness 执行周期。避免在 harness 内部做任何耗时的计算(比如大模型级别的 re-ranking),这些都应该下沉为一个独立的、可异步调用的 tool。你的 goal 是让每次 execute() 的耗时,稳定在 100ms-500ms 区间。这不仅能省钱,更能保证用户体验的流畅性。

3.3 与现有生态的集成:Notion、Rakuten、Sentry 的启示

Anthropic 的 launch 文案里提到 Notion、Rakuten、Sentry 是早期 adopter,这绝非随意举例,而是揭示了 Managed Agents 最典型的三种集成模式:

  1. 嵌入式工作流(Notion) :Notion 的场景是“在已有协作环境中,无缝引入 AI 能力”。他们的 agent 不是一个独立应用,而是作为 Notion Page 的一个 Block。用户在写 OKR 时,可以右键选择“让 Claude 分析这个季度的销售数据”,agent 会自动:

    • 从当前 Notion 页面提取关键指标(如目标销售额)。
    • 调用 Notion API 获取关联的销售数据库视图。
    • 调用 data_analyzer 工具进行计算。
    • 将结果以富文本形式,直接插入到当前页面下方。 这种模式的成功,依赖于 agent 的 tool ecosystem 必须与宿主平台的 API 深度对齐 。Notion 的工程师,一定花了很多时间,把 notion_get_database_items notion_update_page 这些操作,封装成了符合 Managed Agents schema 的、带强类型输入/输出的 tools。
  2. 跨渠道代理(Rakuten) :Rakuten 构建了销售、市场、财务三套 agent,并通过 Slack 和 Teams 统一接入。这解决的是 “一个 agent,多端口接入” 的问题。它的核心在于 harness 的路由层。当一个消息从 Slack 到达时,harness 会先解析 channel_id user_id ,然后决定:

    • 这个用户属于哪个部门(Sales/Marketing/Finance)?
    • 这个频道的主题是什么(#sales-leads / #marketing-campaigns)?
    • 应该将这个请求路由给哪个具体的 agent 实例? 这本质上是一个轻量级的 service mesh。Managed Agents 的 sessionId 设计,完美支持这种模式——同一个 sessionId 可以在 Slack 和 Teams 之间无缝切换,因为 state 在 event log 里,不在某个特定的客户端里。
  3. 闭环开发(Sentry) :Sentry 的案例最激进:他们的 debugging agent 能自动分析错误堆栈,然后调用 Claude agent 来“写 patch 并提 PR”。这要求 agent 具备 完整的、生产级的代码操作能力 。它需要的 tools 至少包括:

    • github_get_repo (获取代码仓库)
    • github_search_code (搜索相关文件)
    • github_create_branch (创建新分支)
    • github_create_pull_request (创建 PR) 这些 tools 的 input_schema 必须极其严谨,比如 github_create_pull_request 的输入,必须包含 base_branch: "main" , head_branch: "fix/issue-123" , title: "Fix: Null pointer in UserAuthenticator" , body: "This PR fixes..." 。任何一个字段缺失或类型错误,都会导致 PR 创建失败。这再次印证了 YAML 定义的必要性——它强迫你在设计阶段就思考清楚每一个边界条件。

4. 竞争格局与未来推演:Runtime 层为何注定“归零”

4.1 Hyperscaler 的降维打击:免费即是最强武器

Anthropic 的 Managed Agents 是一个优秀的产品,但它的市场定位,从诞生第一天起,就注定了是一场防御战。因为它的主要竞争对手,不是某个初创公司,而是 AWS、Google、Microsoft 这三大云厂商。而云厂商的武器,从来都不是“做得更好”,而是“做得足够好,并且免费”。

  • AWS Bedrock AgentCore :它不是一个“产品”,而是一个 基础设施原语 。它被深度集成在 AWS 的 IAM、VPC、CloudWatch 生态中。一个企业客户,只要已经在用 AWS,那么启用 AgentCore,意味着:

    • 无需额外采购新服务,直接在现有账单上增加微乎其微的费用。
    • 安全策略(如 VPC endpoint、KMS 加密)可以直接复用,无需重新学习一套新规则。
    • 监控告警(CloudWatch Metrics)开箱即用, AgentCore.SessionDuration AgentCore.ToolCallLatency 这些指标,天然就出现在你的 Grafana 仪表盘上。 当 AWS 把一个 runtime 的价格,压到和 EC2 t3.micro 的 idle 成本差不多时(即,你为它付费的唯一理由,是它比你自己维护一个 EC2 更省事),这个 runtime 就不再是“可选项”,而是“默认项”。这就是 commoditization 的终极形态: 它不再是一个需要被评估、被采购、被谈判的“软件”,而是一个像电力、网络一样,被默认提供的“服务”。
  • Google Vertex AI Agent Builder :Google 的策略是 “AI-native first” 。Vertex 的 Agent Registry 不是孤立的,它和 Google 的 BigQuery、Looker、Apigee 形成了一个数据飞轮。一个 agent 可以直接查询 BigQuery 里的 PB 级数据,生成的报告可以一键发布到 Looker,而整个访问权限,由 Apigee 的 API Gateway 统一管控。对于一个已经重度使用 Google Cloud Data Analytics 套件的企业来说,Vertex Agent 不是“另一个 AI 工具”,而是“数据分析工作流的自然延伸”。它的价值,不在于 agent 本身,而在于它如何无缝编织进你已有的数据资产。

  • Microsoft Azure AI Foundry :微软的杀招是 “开发者体验” 。AutoGen 和 Semantic Kernel 是开源社区里最成熟、文档最全的 agent framework。Foundry 不是取代它们,而是“拥抱”它们。你可以在本地用 AutoGen 写好一个复杂的 multi-agent workflow,然后一键部署到 Foundry 上,所有的 GroupChatManager ConversableAgent 都能原样运行。这极大地降低了迁移成本。对于一个拥有大量 .NET 和 Python 开发者的大型企业,选择 Foundry,意味着他们可以继续用熟悉的工具链,而不用为了一个新 runtime,去重构整个技术栈。

这三家巨头,都在做同一件事: 把 agent runtime,变成自己云平台的“空气” 。你感觉不到它的存在,但离开它,你就无法呼吸。在这种背景下,Anthropic 的 $0.08/session-hour ,无论多么有竞争力,都只是一个“溢价”。它的生存空间,只存在于那些对 vendor lock-in 极度敏感、且愿意为“Claude 专属优化”支付额外费用的 niche 客户。

4.2 开源压力:Daytona、Kubernetes SIG、Deer-flow 的崛起

如果说 hyperscaler 是从上往下压,那么开源社区就是从下往上拱。2025 年初,几个关键项目标志着 runtime 层的开源生态已经成型:

  • Daytona :这个项目最初是为开发者打造的本地 IDE 环境,但在 2025 年初,它宣布全面转向 AI agent infrastructure。它的核心卖点是 sub-90ms sandbox spin-up time 。这意味着,当你在 VS Code 里点击“Run Agent”时,从你按下回车,到 sandbox 启动、tool call 执行、结果返回,整个过程不到 0.1 秒。这种极致的性能,来自于它对 WebAssembly runtime 的深度定制。它证明了一件事: 高性能的 sandbox,不再需要昂贵的 VM,一个轻量级的 WASM runtime 就够了 。这对于边缘计算、桌面应用等场景,是颠覆性的。

  • Kubernetes SIG Agent-Sandbox :这是 Kubernetes 官方成立的一个特别兴趣小组,旨在为 agent 提供标准化的 sandbox 编排能力。它提出的 Sandbox CRD(Custom Resource Definition),定义了一套 Kubernetes 原生的 sandbox 生命周期管理 API。这意味着,未来你可以在任何兼容 Kubernetes 的集群上(无论是 AWS EKS、GCP GKE,还是你自己的 on-prem 集群),用 kubectl apply -f sandbox.yaml 的方式,一键部署一个符合安全规范的 agent sandbox。这直接把 sandbox 的管理,变成了和 Deployment Service 一样的基础设施原语。

  • Deer-flow :ByteDance 开源的这个项目,代表了 agent 架构的下一个前沿: planning and subagents 。它不再把 agent 看作一个单一的、线性的执行单元,而是允许一个 master agent 动态地 spawn 出多个 specialized subagents(比如一个 research_subagent ,一个 code_generation_subagent ,一个 review_subagent ),并协调它们之间的通信。这种架构,天然就需要一个强大的、分布式的 runtime 来管理这些 subagents 的生命周期、状态同步和错误恢复。Deer-flow 的出现,预示着未来的 agent runtime,必须支持更复杂的、图状的执行拓扑,而不仅仅是简单的 request-response loop。

这三股力量合在一起,构成了一个清晰的路线图: 从专有、封闭、昂贵的 runtime,走向开放、标准、免费的 runtime 。这个过程,和当年 VMware ESX 被 KVM 和 Xen 取代的历史,惊人地相似。唯一的区别是,这一次,速度更快,周期更短。

4.3 价值迁移:当 Runtime 归零,钱流向哪里?

当一个技术层 commoditize,它并不会消失,而是像水蒸气一样,沉降到更低的基础设施层,成为默认的、透明的背景。而价值,则会迅速向上迁移,聚集在那些能解决更高阶、更业务化问题的层面上。对于 AI agent 生态,这个价值迁移,正清晰地指向三个方向:

价值层 核心问题 代表玩家 为什么能胜出?
Trace Store (可观测性) “这个 agent 到底做了什么?谁批准的?结果可信吗?” Braintrust (Brainstore), Arize (Phoenix), LangSmith 这是 runtime 的“影子”。当 runtime 变得无处不在、难以区分时, 谁拥有了最完整、最标准、最易迁移的 trace 数据,谁就拥有了 agent 的“真相” 。Brainstore 之所以能融到 $36M,是因为它把 AI interaction logs 当作一种新型的 OLAP 数据库来设计,支持亚秒级的复杂关联查询(比如,“找出所有在调用 send_email 前, pdf_parser 返回了 revenue_q1 < 0 的 session”)。这是一个 runtime 无法轻易复制的壁垒。
Governance & Policy (治理) “这个 agent 被允许做什么?它的权限边界在哪里?如何审计?” AWS AgentCore Policy Controls, OWASP Agentic Top 10 当 agent 开始操作真实世界的系统(银行账户、生产数据库、HR 系统)时, 安全和合规,不再是可选项,而是准入门槛 。AWS 的政策控制 GA,意味着企业采购的第一个问题,不再是“这个 agent 多快”,而是“它能不能满足我们的 SOC2 合规要求?”。谁能提供开箱即用的、符合行业标准的 policy engine,谁就能卡住 enterprise sales 的咽喉。
Vertical Agent Marketplaces (垂直市场) “这个 agent 能帮我解决什么具体的业务问题?” Salesforce Agentforce, virattt/ai-hedge-fund, vxcontrol/pentagi 企业不为“AI”付费,只为“结果”付费。Salesforce Agentforce 的 $800M ARR,证明了这一点。当 runtime 成为免费的“水电煤”, 真正的利润,来自那些能打包成“销售线索生成器”、“医疗理赔审核员”、“网络安全渗透测试员”的、开箱即用的垂直解决方案 。这些 solution 的价值,不在于它用了什么 runtime,而在于它内置的 domain knowledge、pre-trained workflows、和与特定 SaaS(如 Salesforce, ServiceNow)的深度集成。

我个人在实际操作中的体会是:现在开始规划一个 agent 项目,第一件事,绝对不是选 runtime,而是问自己三个问题:1. 我的 trace 数据,未来要迁移到另一个云平台,难不难?2. 我的 agent 的权限策略,能否通过一个 YAML 文件,清晰地定义出来,并被安全团队一键审批?3. 我的 agent,能不能被包装成一个独立的、有名字、有 logo、有定价页的 SaaS 产品?如果这三个问题的答案都是“否”,那你大概率,还在 building the wrong thing。

5. 常见问题与实战避坑指南:从上线到规模化

5.1 “Session Timeout” 错误:不是 bug,是设计

问题现象 :用户反馈,一个运行了 3 小时的 session,突然返回 SessionTimeoutError ,所有状态丢失。

排查思路 :首先,确认这不是一个 bug。Managed Agents 的 session 本身是 durable 的,但 awake(sessionId) 调用有一个默认的 inactivity timeout (非活动超时)。这个 timeout 的默认值是 2 小时 。也就是说,如果一个 session 在 2 小时内没有任何 awake() 调用,系统会认为它已“死亡”,并自动清理其在内存中的缓存(虽然 event log 依然存在)。

解决方案

  • 前端保活 :在你的前端应用(如 Notion 插件、Slack App)中,实现一个后台定时器,每隔 90 分钟,向后端发送一个 keep_alive(sessionId) 的心跳请求。这个请求不需要触发任何 agent 逻辑,它只是告诉 Anthropic 的 harness:“这个 session 还活着,请续期。”
  • 后端兜底 :在你的后端服务中,监听 SessionTimeoutError 。一旦捕获,不要直接报错,而是尝试 awake(sessionId) 。因为 event log 是持久的,这次调用会成功加载所有历史,用户感觉不到中断。这相当于一个优雅的“自动续期”。

注意:这个机制的设计初衷,是为了防止海量的 idle sessions 占用 harness 的内存资源。它不是缺陷,而是对资源的一种负责任的管理。

5.2 Tool Call 失败:90% 的原因是 Schema 不匹配

问题现象 pdf_parser 工具总是返回 {"error": "Invalid input format"} ,但你在本地测试时,JSON 输入看起来完全正确。

根因分析 :这是 YAML 定义中最常见的陷阱。假设你的 input_schema 是这样的:

input_schema:
  type: "object"
  properties:
    file_id:
      type: "string"

而你传入的 JSON 是:

{
  "file_id": 123456789
}

注意! 123456789 是一个 number ,但 schema 要求的是 string 。LLM 在生成 tool call 时,经常犯这种“类型混淆”的错误,尤其是在处理 ID、timestamp 等字段时。

解决方案

  • 强制类型转换 :在你的 tool 实现代码里,不要直接 json.loads(input) ,而是先做一层严格的类型校验和转换。例如,在 Python 中:
    def pdf_parser(input_json):
        try:
            data = json.loads(input_json)
            # 强制转换为 string,即使传入的是 number
            file_id = str(data.get("file_id", ""))
            if not file_id:
                raise ValueError("file_id is required")
            # ... rest of logic
        except Exception as e:
            # 记录详细的 error log,包括原始 input_json
            logger.error(f"pdf_parser failed for input {input_json}: {e}")
            raise
    
  • Prompt Engineering :在 system_prompt 里,加入一句明确的指令:“ All tool call parameters must be strings. Never use numbers or booleans for any parameter. ” 这能显著降低 LLM 的出错率。

5.3 Credential Leaking:Vault 的正确打开方式

问题现象 :安全审计发现,sandbox 的日志里,出现了明文的 API key。

根因分析 :这几乎 100% 是因为你没有正确使用 Anthropic 的 Vault。你可能在 tool 的实现里,直接从环境变量读取了 API_KEY ,然后把它拼接进了 curl 命令。这是大忌。

正确姿势

  1. 在 Anthropic Console 的 Vault 中,创建一个名为 notion_api_key 的 secret。
  2. 在你的 tool input_schema 中, 不要定义 api_key 字段 。相反,定义一个 notion_workspace_id 字段。
  3. harness 的执行逻辑中,当它识别出要调用 notion_api_key 时,它会:
  • 向 Anthropic Vault 发送一个请求,获取 notion_api_key 的临时 token。
  • 将这个 token,作为 Authorization header,直接传递给 notion_api_key 工具。
  • notion_api_key 工具本身,只负责接收这个 header,并用它去调用 Notion API。
  1. Sandbox 的整个生命周期内,它只看到一个临时的、一次性的 bearer token,而永远看不到原始的、长期有效的 API key。

实操心得:把 credential management 当作一个独立的、有 SLA 的 service 来对待。它的 uptime 和 security,应该和你的核心数据库一样重要。不要把它写死在代码里,也不要放在 configmap 里。用 Vault,就是用最好的实践。

5.4 Scaling 瓶颈:Harness 成为性能天花板

问题现象 :当并发 session 数超过 1000 时,p95 time-to-first-token 从 200ms 暴涨到 2s。

根因分析 :Harnes 本身是一个单点服务。它需要:

  • 从 event log(如 DynamoDB)读取数据。
  • 调用 Claude API。
  • 解析响应,生成新的 event。
  • 写入 event log。 这四个步骤,任何一个环节的延迟,都会被放大。尤其是当 event log 的读写成为瓶颈时。

优化方案

  • 读写分离 :为 event log 建立一个 read replica。harness 的 read 操作(加载历史)走 replica, write 操作(写入新 event)走 primary。这能立刻提升 30%-50% 的吞吐。
  • 本地缓存 :在 harness 进程内,为高频访问的 session(比如最近 10 分钟内活跃的)建立一个 LRU cache。cache 的 key 是 sessionId ,value 是最近 10 条 event 的摘要。这样,90% 的 awake() 调用,都不需要访问远程数据库。
  • 异步写入 :将 write new event 的操作,改为异步。harness 在生成完 event 后,将其放入一个 Kafka topic,由一个独立的 consumer service 来负责写入 event log。这能将 harness 的响应时间,稳定在 100ms 以内,代价是 event log 的最终一致性(延迟在毫秒级)。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐