找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3237

积分

0

好友

459

主题
发表于 11 小时前 | 查看: 1| 回复: 0

原文标题:Effective harnesses for long-running agents
原文作者:Justin Young
原文地址:https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents

尽管AI智能体的能力在持续增强,但当我们尝试将更复杂、耗时长达数小时甚至数天的任务交给它们时,一个关键问题依然存在:如何让智能体在跨越多个上下文窗口的情况下,实现持续且稳定的工作推进

你是否也曾遇到过这样的困境?让智能体去开发一个完整项目,几轮对话下来,它要么中途“失忆”,要么早早宣布“大功告成”,留下一个半成品或充满隐患的代码库。本文将从人类软件工程师的工作协作中汲取灵感,分享一种经过实践验证的、适用于长时间运行智能体的双层架构方案,以解决“跨会话遗忘”这一核心难题。

长时间运行智能体的核心挑战

Claude Agent SDK 是一个非常强大的通用智能体框架,能够完成“获取上下文 → 规划 → 执行”的复杂循环。它支持上下文压缩,理论上可以让智能体长时间运行而不会耗尽上下文。

但现实是,仅靠上下文压缩远远不够

即使使用像 Claude Opus 4.5 这样的顶级模型,如果只是简单地给它一个高层目标(例如“构建一个 claude.ai 的克隆版本”),并期望它在 SDK 中循环运行,你很可能无法稳定地得到一个真正可投入生产的 Web 应用。在实践中,我们观察到了两种典型的失败模式。

失败模式一:贪多嚼不烂

智能体倾向于“一次性写完整个应用”。这通常导致:

  • 在实现过程中耗尽上下文
  • 留下一堆半成品功能
  • 没有留下任何清晰的进展记录或说明

当下一个会话启动时,新的智能体对之前的工作一无所知,不得不花费大量时间重新搭建基础环境。即使使用了上下文压缩,这种情况依然频发,因为压缩并不能保证关键信息被清晰、无歧义地传递下去。

失败模式二:过早宣布胜利

在项目后期,当智能体看到一部分功能已经实现时,可能会直接判定“任务完成”,而实际上仍有大量收尾或优化工作尚未进行。

这些失败模式促使我们将问题拆解为两个核心目标:

  1. 在项目一开始就建立稳固的基础环境:明确完整的功能范围、技术栈和工作流程,为智能体设定清晰的边界。
  2. 确保每一次会话都只完成“一个可交付的增量”:并在会话结束时,将项目整理到一个“干净状态”。

这里的“干净状态”指的是:代码可以随时合并到主分支,没有明显的阻塞性 Bug,结构清晰且文档完整。这样,下一位“工程师”(即下一个会话中的智能体)可以立刻基于此状态继续工作,而不是先花时间去修复遗留问题。

基于此,我们为 Claude Agent SDK 设计了一套双层协作方案:

  • 初始化智能体 (Initializer Agent):只在第一次运行时启动,负责搭建环境、明确目标和约束。
  • 编码智能体 (Coding Agent):在后续的每一个会话中持续、增量地推进工作,并为下一次会话留下清晰、可接续的工作痕迹。

相关的代码实现思路,你可以在云栈社区的后端 & 架构板块找到更多启发。

环境管理:为长期协作奠定基础

在更新版的 Claude 提示词指南中已经提到,处理多上下文窗口的任务时,应为第一个上下文窗口使用一个专门的提示词

这个提示词的目的,是让初始化智能体一次性建立起所有后续编码智能体都需要的上下文基础。以下是几个关键的组成部分。

功能清单:明确“完成”的定义

为了防止智能体“拍脑袋”决定项目何时完成,我们要求初始化智能体基于用户需求,生成一份完整且细粒度的功能清单

以构建 claude.ai 克隆为例,这份清单可能包含超过 200 个功能点,例如:“用户可以点击‘新建聊天’按钮,创建一个全新的对话。” 所有功能在初始状态下都被标记为 passes: false,这让后续的智能体始终清楚“什么才算真正完成”。

{
  "category": "functional",
  "description": "New chat button creates a fresh conversation",
  "steps": [
    "Navigate to main interface",
    "Click the 'New Chat' button",
    "Verify a new conversation is created",
    "Check that chat area shows welcome state",
    "Verify conversation appears in sidebar"
    ],
  "passes": false
  }

我们明确要求编码智能体:

  • 只能修改 passes 字段,将其从 false 改为 true
  • 禁止删除或改写功能描述本身。

经过多次尝试,我们发现使用 JSON 格式比 Markdown 更可靠:模型更不容易“意外地”修改或破坏结构化的数据。

循序渐进:强制增量开发

在这个设定下,每一轮编码智能体会话只被允许处理并完成一个功能点。这一步至关重要,直接遏制了智能体“试图一把梭”的倾向。

同时,我们要求智能体在每次修改后:

  • 使用清晰的提交信息(commit message)将更改提交到 Git 仓库。
  • 在专门的进度记录文件(如 claude-progress.txt)中写明本次完成了什么。

这样一来,智能体不仅能利用 Git 的历史记录回滚错误的修改,还能快速地将项目恢复到上一个已知的稳定状态,避免了在同一个问题上反复踩坑。

测试:确保功能真实可用

另一个常见问题是:智能体在没有进行充分验证的情况下,就将某个功能标记为完成

如果没有明确要求,Claude 通常只会编写单元测试,或者用 curl 简单测试一下 API 接口,却忽略了端到端(E2E)流程是否真的对用户可用。在 Web 应用开发场景中,一旦我们明确要求 Claude 使用浏览器自动化工具(如 Puppeteer)进行像真实用户一样的操作,其端到端测试的质量就会得到显著提升。

使用 Puppeteer MCP 服务器后,Claude 能够发现许多“仅看代码无法察觉”的界面交互问题。

当然,工具也有其局限性。例如,Claude 可能无法识别浏览器原生的 alert 弹窗,因此那些依赖此类弹窗的功能更容易出现 Bug。

Claude 使用 Puppeteer MCP 进行端到端功能测试的界面截图

快速进入状态:标准化的工作流程

在这套完整的机制下,每个编码智能体在开始工作前,都会执行一套标准化的“热身”流程:

  1. 运行 pwd,确认当前的工作目录。
  2. 阅读 Git 提交日志和进度记录文件。
  3. 查看功能清单,选择一个尚未完成的、优先级最高的功能。

同时,由初始化智能体创建的 init.sh 脚本可以一键启动开发服务器,并运行一轮基础的 E2E 测试,以确保项目处于健康状态。如果发现项目运行有问题,智能体会优先修复这些问题,而不是继续堆砌新功能,从而避免技术债务的累积。

一个典型的会话开始时,助手会显示类似以下的消息:

[Assistant] I'll start by getting my bearings and understanding the current state of the project.
[Tool Use] <bash - pwd>
[Tool Use] <read - claude-progress.txt>
[Tool Use] <read - feature_list.json>
[Assistant] Let me check the git log to see recent work.
[Tool Use] <bash - git log --oneline -20>
[Assistant] Now let me check if there's an init.sh script to restart the servers.
<Starts the development server>
[Assistant] Excellent! Now let me navigate to the application and verify that some fundamental features are still working.
<Tests basic functionality>
[Assistant] Based on my verification testing, I can see that the fundamental functionality is working well. The core chat features, theme switching, conversation loading, and error handling are all functioning correctly. Now let me review the tests.json file more comprehensively to understand what needs to be implemented next.
<Starts work on a new feature>

下表总结了常见的失败模式及其对应的解决方案:

问题 初始化智能体的解决方案 编码智能体的解决方案
Claude 过早认为项目已完成 创建结构化的功能清单 JSON 文件,明确定义“完成”标准 在会话开始时查阅功能清单,并只选择一个未完成的功能进行开发
Claude 留下的环境存在 Bug 或未记录的改动 初始化 Git 仓库并创建进度记录文件 会话开始时,阅读进度文件和 Git 日志,并运行基础测试以发现未记录的问题;会话结束时提交代码并更新进度
Claude 将功能过早标记为完成 创建功能清单文件 只有在通过仔细的端到端测试后,才能将功能标记为“通过”
Claude 不知道如何运行应用 提供 init.sh 启动脚本 阅读并执行 init.sh 脚本来开始新会话

未来展望

以上方案证明,通过设计合适的协作框架和约束条件,智能体确实有能力在多个上下文窗口中持续推进复杂的长期任务。

当然,这只是一个起点。未来还有许多值得探索的方向,例如:

  • 是使用一个通用的编码智能体更高效,还是采用多智能体分工协作的模式(如专门的设计、测试、部署智能体)更优?
  • 测试、质量保证、代码重构等专业性较强的角色,是否应由更专门的智能体来承担?

此外,这套方法目前主要针对 Web 全栈应用开发场景,未来也有潜力被推广到科学研究、金融建模等需要智能体长期运行和持续迭代的其他领域。




上一篇:C++实战性能优化指南:从内存管理、编译优化到代码习惯
下一篇:Nginx四层反向代理实践:Stream模块七个阶段详解与核心指令配置
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-4 21:46 , Processed in 0.282203 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表