3 研究方法
本研究对开源编码智能体脚手架进行源代码级别的架构分析,从观察到的实现模式而非文档声明或概念模型中推导出分类类别。
3.1 智能体选取
候选智能体通过三个渠道识别:截至 2026 年初在 SWE-bench 排行榜文献中被评估和报告的智能体、在开发者工具中具有显著采用率的智能体(以 GitHub star 数作为社区使用的代理指标 [^7])以及在近期 LLM 软件工程综述中被引用的智能体 [^61]。检索在任何单一渠道内都并非穷尽性的;候选池反映的是研究者通过这些来源所接触到的智能体,而非满足某一固定阈值的所有智能体的完整枚举。一个包含 22 个候选的初始池依据三项纳入标准进行筛选(完整的候选列表及每个排除理由见 Appendix A):
- 编码专用。智能体必须是为软件工程任务(代码编辑、缺陷修复、代码仓库导航)而设计的,而非通用任务自动化工具。这排除了通用框架(Open Interpreter [^38]、Deep Agents [^29])和多智能体编排平台(MetaGPT [^26]、CrewAI [^16]),后者的分析单元是智能体间的协调而非单个智能体的架构。
- 开源且实现可读。智能体的脚手架代码(控制循环、工具定义、状态管理)必须以可读源代码的形式存在于公开仓库中,并固定到特定的提交。这排除了 Claude Code [^5](以编译后的二进制文件分发,无公开源代码仓库)和 MASAI [^6] 1。脚手架代码不可检视的专有智能体(GitHub Copilot Workspace、Cursor 的 AI 后端、Windsurf)也据此被排除。
- 架构上有区分度。近似重复的智能体被移除以避免冗余分析(例如,共享同一核心代码库或仅在前端集成上有差异的智能体)。
保留用于分析的 13 个智能体列于 Table 1。它们跨越两个自然的来源类别:为交互式开发者使用而构建的 CLI 智能体和主要为自动化问题解决而构建的 SWE-bench 智能体。另有一个智能体 mini-swe-agent [^56] 作为刻意设定的最小基线纳入:它由 SWE-agent [^57] 团队发布,作为展示最简可能完整脚手架的参考实现。该选取并非穷尽性的,但旨在覆盖截至 2026 年初开源编码智能体生态系统中所呈现的架构策略范围。
Table 1:所分析的智能体,按 GitHub star 数排序作为社区采用的代理指标 [^7]。"类别"区分了交互式 CLI 工具和为自动化 SWE-bench 评估而设计的智能体。所有智能体均在固定的提交哈希处进行分析(见 Appendix B)。
| 智能体 | 类别 | 语言 | Star 数 | 来源 |
|---|---|---|---|---|
| OpenCode [^3] | CLI | TypeScript | 135k | SST |
| Gemini CLI [^25] | CLI | TypeScript | 100k | |
| Codex CLI [^39] | CLI | Rust / TS | 72k | OpenAI |
| OpenHands [^52] | SWE-bench | Python | 70k | All Hands AI |
| Cline [^43] | CLI | TypeScript | 60k | Independent |
| Aider [^23] | CLI | Python | 43k | Independent |
| SWE-agent [^57] | SWE-bench | Python | 19k | Princeton / CMU |
| mini-swe-agent [^56] | 基线 | Python | 4k | Princeton / CMU |
| AutoCodeRover [^62] | SWE-bench | Python | 3k | NUS / SonarSource |
| Agentless [^54] | SWE-bench | Python | 2k | UIUC |
| Prometheus [^41] | SWE-bench | Python | 1k | EuniAI |
| Moatless Tools [^40] | SWE-bench | Python | 600 | Independent |
| DARS-Agent [^2] | SWE-bench | Python | 70 | Independent |
3.2 分析维度
分析框架包含九个维度(在结果中产生 12 个分类法维度,如下所述)。这些维度并非先验固定的,而是在对两个架构差异显著的智能体——Aider(一个较简单的交互式 CLI 脚手架)和 OpenHands(一个复杂的事件驱动容器化脚手架)——进行试点分析的过程中,通过迭代的开放编码 [^51] 逐步形成的。选择这两个智能体是为了在试点阶段最大化架构多样性;具体的选择理由和改进细节见 Section 3.4。
初始试点从概念性智能体架构文献 [^35] 中提取了六个候选维度:控制循环、工具接口、状态管理、上下文检索、执行隔离和多模型路由。在试点过程中,由于源代码揭示了初始维度集未能捕捉的架构变异,新增了三个维度:工具发现策略(源于 Aider 和 OpenHands 注册工具方式的差异)、上下文压缩(源于 Aider 的显式摘要逻辑与 OpenHands 缺乏此逻辑之间的对比)以及持久化记忆(源于 Aider 的约定文件)。稳定化过程包括将修订后的九维度框架再次应用于两个试点智能体,以确认每个维度在两个智能体间均能产生有区分力的发现,且没有源代码观察结果落在框架之外而未被开放式部分捕获。在此过程中没有移除任何维度。若干最终维度与此前编码智能体的单系统分析 [^13] 和概念性智能体架构综述 [^35] 中独立识别的架构关注点相一致,为其相关性提供了外部支持。每个维度捕捉脚手架中一个独立的架构决策点。
- 控制循环类型。智能体主执行循环的结构:它如何编排 LLM 调用、工具分发和观察处理。一个子属性——循环驱动者——记录循环是由用户发起还是由 LLM 驱动,这一区分是在试点过程中添加的,因为观察到它决定了若干下游架构决策(Section 4.1.2)。
- 工具集与工具接口设计。模型可用的完整工具集,包括工具如何被定义并传达给 LLM(例如,通过函数调用的 JSON schema、内联系统提示描述或自定义文本格式)。该维度还记录智能体在提出文件修改时使用的编辑与补丁格式。
- 工具发现策略。完整的工具集是在启动时注册(静态)还是根据任务状态在运行时有条件地加载、动态注册或组装(动态)。
- 状态管理策略。智能体如何在循环迭代间累积和表示历史:数据结构(扁平消息列表、类型化事件日志、树)、状态是只追加的还是可变的,以及除原始消息之外还存储了什么。
- 上下文检索范式。智能体在任务执行之前或期间识别相关源代码的机制:LLM 导向的工具调用(grep、find、AST 查询)、预计算的代码仓库索引、基于嵌入的语义搜索,或者包含在初始提示中的静态代码仓库映射。
- 执行隔离模型。智能体在何处运行 shell 命令和代码:在宿主文件系统上、在 Docker 容器中、在沙箱化的子进程中,还是在远程云环境中。这记录了智能体与宿主系统之间的信任边界。
- 上下文压缩方法。当对话历史接近模型上下文窗口上限时所采用的策略:硬截断、滑动窗口、LLM 生成的摘要、选择性丢弃工具结果,或者没有任何机制。
- 多模型路由。是由单个模型处理所有智能体步骤,还是将不同模型分配给不同角色(例如,大模型用于规划,小模型用于定位),以及路由决策如何做出。
- 持久化记忆。是否有任何信息在会话间留存:项目约定、之前的任务结果、用户偏好或代码仓库事实,以及所使用的存储机制。
分析模板还包括一个开放式的第十部分,用于记录不符合九个维度中任何一个的观察。这遵循了定性编码的标准做法,其中在预定义类别之外预期会出现涌现类别 [^46]:强制将每个发现归入预定义类别可能会抑制新模式的发现。在实践中,该部分捕获了 47 项跨维度发现(在逐个智能体的分析文档中逐一列举),这些发现为 Section 4 中呈现的分类法结构提供了信息。
九个分析维度在结果中映射为 12 个分类法维度。在分析过程中,两个子属性证明具有足够的区分力而值得独立处理:循环驱动者(控制循环类型的子属性)和编辑与补丁格式(工具集设计的子属性)各自产生了独立的频谱和证据表,在 Section 4 中作为独立维度呈现。第三个维度——控制流实现(实现控制循环的代码层面机制:while 循环、递归、编译图或基于异常的信号传递)——在分析过程中涌现,作为与循环拓扑正交的一个变异轴,同样独立呈现。从分析框架到分类法结构的这种扩展是定性编码的正常结果:框架指导数据收集,但最终的类别反映数据所揭示的内容 [^46]。
3.3 工具计数方法
工具计数采用两种互补方法进行报告,以避免将接口粒度与功能覆盖混为一谈。
注册计数按照 LLM 所见的方式统计工具:每个单独注册的可调用单元(函数调用 schema 条目、系统提示中定义的命令或等效物)计为一次。该度量受脚手架开发者如何划分功能的影响。
能力类别计数按照工具的功能进行分组:读取、搜索、编辑、执行、验证和代码仓库状态。这些类别通过试点分析归纳得出:在编目前两个智能体的所有工具之后,将反复出现的功能角色归入若干类别,然后在其余十一个智能体上进行验证。该度量可在不同智能体间进行比较,不受粒度选择的影响。一个拥有单一 bash 工具的智能体与一个拥有独立的 run_command、run_tests 和 run_linter 工具的智能体都覆盖了执行类别。两种计数均在结果中报告;能力类别计数用于跨智能体比较。
3.4 分析流程
每个智能体使用一个结构化模板进行分析,该模板源自 Section 3.2 中建立的九个维度,并在全部 13 个智能体中一致应用。该模板区分三个描述层次,遵循实证论断应可追溯到原始数据源而非从二手文档推断的原则 [^44]:
- 观察:代码做了什么,以数据流和控制流的方式描述,附有具体的文件和行号引用。
- 分类:观察到的行为如何映射到分类法维度,附有明确的映射理由。
- 证据:锚定到所分析特定提交哈希的文件路径和行号。
对于每个智能体,该模板生成一份结构化文档,涵盖全部九个维度加上开放式部分,并以主控制循环的完整调用链追踪作为入口点。该模板在与维度开发相同的两个智能体(Section 3.2)上进行了试点:Aider 和 OpenHands。此次试点与维度稳定化的目的不同;它测试的是三层观察格式是否能产生一致且足够详细的分析文档。试点还暴露了对双重工具计数方法(Section 3.3)的需求——在观察到原始工具计数在接口粒度不同的智能体间不具可比性之后。全部 13 个智能体的完整分析文档均遵循该模板;各分析文档的相关章节在结果中被引用,作为特定论断的主要证据。
所有分析均固定到特定的 git 提交哈希,列于 Appendix B,因为若干被研究的智能体(Cline、Aider、OpenHands、Gemini CLI)在分析期间处于活跃开发状态,未固定的分析将产生不可复现的结果。当源代码存在歧义时,分析明确记录不确定性而非赋予一个高置信度的分类。对于某些智能体确实不适用的维度(例如,没有跨会话存储的智能体的持久化记忆)记录为"不存在"而非省略。所有分析由作者独立完成,并大量使用了基于 LLM 的编码助手进行代码导航、调用链追踪和陌生代码库的初步总结。所有 LLM 生成的观察结果在纳入分析文档之前均已与源代码进行了核实;分析文档本身记录了文件路径和行号以便于独立验证。单作者设计是对构造效度的一个威胁;缓解措施在 Section 6 中讨论。
3.5 范围与局限性
本研究纯粹是分类性的。未进行性能基准测试,也未就脚手架设计与任务成功率之间的相关性提出任何主张。排除性能分析的决定反映了可用数据的两个局限性:第一,跨智能体的 SWE-bench 结果无法直接比较,因为不同的智能体使用了不同的底层模型,而模型能力是比脚手架设计更大的混淆因素;第二,SWE-bench 问题描述中已有文献记录的解决方案泄露 [^22] 使得原始通过率无论如何都不是可靠的信号。语料库仅限于具有可读源代码的开源智能体;由此产生的威胁在 Section 6 中讨论。