Stripe Ramp Coinbase 都在用的 Coding Agent 架构: 究竟有何奥秘

时间:2026-07-06 08:28:47 来源:互联网

当前开发者若仍采用传统方式编写代码,几乎等同于追求成为非遗传承人,多数人已普遍借助Claude Code、Cursor这类Coding Agent。尽管方向正确,但不同场景需求各异——开发者本地安装AI助手以提升个人效率,与在组织内部构建AI驱动的研发协作体系,属于截然不同的两种模式。前者已有成熟产品,后者方兴未艾。本文将重点探讨后者。Stripe、Ramp、Coinbase 都在用的 Coding Agent 架构,究竟有何奥秘?

什么是组织级Coding Agent,都有谁在做?

2025年底至2026年初,一个引人注目的现象接连出现:Stripe、Ramp、Coinbase这三家知名企业几乎同步对外公开了它们各自在企业内部部署的Coding Agent。Stripe的称为Minions,Ramp的命名为Inspect,Coinbase的则名为Cloudbot。这三家公司各自独立开发,互不借鉴,但最终却不谋而合地形成了高度相似的架构模式。

这种趋同绝非偶然。当Coding Agent的使用场景从一个开发者在终端内独立操作,升级为整个团队通过Slack或GitHub Issue随时触发的协作工具时,必然会面临一系列相同的工程挑战。为了解决这些挑战,开发者会不约而同地选择类似的解决方案:需要构建沙箱来隔离执行环境,需要支持Agent在执行中断后能继续先前的工作,需要使其能够接入Slack、GitHub、飞书等多种入口,还必须防止单个用户的失控循环消耗整个公司的模型调用额度。

LangChain团队敏锐地洞察到了这一规律。2026年3月,他们发布了Open SWE——一个旨在将Stripe、Ramp、Coinbase共同采纳的模式提炼为开源框架的项目。Open SWE的README文档开头便直截了当地点明了核心理念:

"Meet engineers where they already work"——这句话精准地阐述了组织级Coding Agent的核心设计思想:并非要求工程师学习一个全新的工具,而是让Agent主动融入工程师们正在使用的Slack频道、GitHub Issue、IM对话中,成为团队工作流程中一个自然而然的组成部分。

AgentScope Java 2.0的AgentScope Harness模块遵循了同样的设计路径。本文将以官方示例agentscope-examples/agents/agentscope-codingagent为线索,详细阐述一个生产级Coding Agent是如何利用Harness构建起来的。本文将逐一解析每一行配置所解决的问题,并说明如何从本地CLI模式逐步演进到挂载在GitHub Webhook之后的企业级服务。

先把定位说清楚

在深入探讨之前,必须清晰界定本文要构建的目标与Claude Code、Cursor这类本地工具之间的差异。

Claude Code优化的目标是“我一个人写代码更快”——你输入指令,它执行操作,你可以实时观察其工作过程,并随时中断或纠正。其状态存储在你的本地机器上,触发者只有你自己,信任边界仅限于你对自己机器的信任。

本文所要构建的解决方案旨在解决另一个问题:“团队中某个小任务,我无需亲自查看,直接交给Agent处理,待其完成并提交拉取请求后,我只需审核即可”。触发者可能是任何一个Issue评论者,Agent将在远程服务器上运行十几分钟甚至一小时,期间无需人工监控。正如Stripe的工程师在Slack中@Minions指示“帮我修这个bug”,随后便收到一个草稿式拉取请求——这正是组织级Coding Agent应有的表现。

这两种形态在功能集方面存在交集——它们都能编写代码、执行命令、修改文件。然而,底层的工程约束条件却截然不同。一个恰当的比喻是:Claude Code相当于你自己的私家车,驾驶员是你本人,因此除了安全气囊外几乎不需要额外的防护措施。而组织级Coding Agent则类似于出租车公司的运营车辆——乘客(触发者)并非车主,驾驶(执行)发生在远端。因此,你需要行车记录仪、GPS追踪、里程限制、紧急制动等机制,并且还需要确保一辆车发生故障不会影响整个车队。

Open SWE将其哲学总结为一句话: "Isolate first, then give full permissions inside the boundary." 先隔离,再放权。AgentScope Harness的设计理念与此完全一致。

那厂商的Cloud Agent呢?

事实上,许多厂商也在提供SaaS形式的产品服务。例如,GitHub Copilot Coding Agent已支持在Issue上通过assign触发,在云端执行完任务后自动创建草稿式拉取请求;Claude Code也提供了headless模式,能够在CI环境中被程序化调用。

在核心理念上,这些厂商提供的服务并无本质区别——沙箱隔离、异步触发、以拉取请求为产出驱动——它们是将头部企业验证过的模式进行产品化,封装成了开箱即用的SaaS服务。而Stripe、Ramp、Coinbase这些公司之所以选择自建,更多是出于自身工程体系的特殊性:对内部系统进行深度集成的需求、数据合规方面的要求、以及工作流的高度定制化需求,这些因素使得它们选择了自建道路。

这两条路径并不矛盾。选择哪一条更合适,取决于组织自身的约束条件和具体需求。AgentScope Harness意在将实现此类系统的工程难题(如沙箱管理、会话恢复、多通道接入、长期记忆管理等)抽象成可组合的基础能力,从而使选择自建的团队无需从零开始。

5分钟跑通:先有感性认识

这是最快的体验路径——只需设置一个环境变量并执行一个Maven命令,即可在本地文件系统上运行一个交互式REPL。整个过程无需Docker、无需webhook、也无需GitHub App。

# 1. 设置模型key(默认DashScope;也支持OpenAI或Anthropic)
export DASHSCOPE_API_KEY=sk-...
# 2. 在仓库根目录构建依赖(后续运行可省略此步)
cd agentscope-java
mvn install -pl agentscope-examples/agents/agentscope-codingagent -am -DskipTests -q
# 3. 启动CLI
mvn exec:java -pl agentscope-examples/agents/agentscope-codingagent

启动后会出现banner,随后进入You>提示符。Agent的工作区位于~/.agentscope/codingagent/workspace/——标准做法是将目标仓库克隆到该工作区中再进行操作:

You> write hello.txt with a haiku about Java
You> clone https://github.com/example/repo.git into the workspace and tell me what it does
You> review /exit

无需任何额外配置,启动后即可拥有完整的工作区、会话持久化和长期记忆功能。这是AgentScope Harness价值的第一层。

如果希望每个session都隔离在Docker沙箱中运行,只需额外一步操作:

docker build 
  -t agentscope/coding-sandbox:latest 
  agentscope-examples/agents/agentscope-codingagent/src/main/docker/coding-sandbox/
export SANDBOX_TYPE=docker
mvn exec:java -pl agentscope-examples/agents/agentscope-codingagent

由此便引出了组织级Coding Agent真正的工程核心问题。

真正的难题:从"能跑一次"到"7x24服务一个团队"

快速运行一个演示程序并不困难。真正的难点在于如何让它在生产环境中稳定地服务于整个团队,每天处理几十个Issue、几十个Pull Request,并且确保每个任务都能完整执行、不相互干扰、不出现内存溢出、不超出预算消耗。

这些工程难题,Stripe、Ramp、Coinbase各自都踩过不少坑,Open SWE在框架层做了抽象,AgentScope Harness也提出了自己的解决方案。下面我们将按问题域逐一展开讨论。

沙箱:让Agent可以放心执行rm -rf

Coding Agent面临的最大工程矛盾在于:我们需要让模型具备真正的执行能力——例如git clone、npm install、mvn test以及任意shell命令——但同时必须防止它对宿主机造成误伤。

Coinbase使用自建的沙箱基础设施来解决这个问题。Ramp则采用Modal的云端容器。Open SWE进行了一层抽象,支持Modal、Daytona、Runloop等多种后端。AgentScope Harness也做了类似的抽象——FilesystemSpec是统一接口,Docker容器、远端KV、本机文件系统都是可插拔的实现。以Docker后端为例:

HarnessAgent agent = HarnessAgent.builder()
    .name("coding")
    .model(model)
    .workspace(workspace)
    .filesystem(new DockerFilesystemSpec()
        .image("agentscope/coding-sandbox:latest")
        .isolationScope(IsolationScope.SESSION))
    .build();

只要添加这一行.filesystem(...)read_filewrite_fileexecute等所有内置工具都会自动改用沙箱后端,而Agent代码本身无需任何修改。IsolationScope.SESSION确保每个GitHub Issue、Pull Request或IM对话各自独立运行——这是最自然也最安全的方式。

跨调用恢复:第二轮call()才是真考验

当用户在PR上评论"再补个测试"时,Agent必须能够基于上一轮的环境继续工作——如果每次都需要重新执行git clonenpm install并等待五分钟,这是任何人都无法接受的。

Open SWE通过"persistent sandbox"解决了这个问题——同一个thread的后续消息复用同一个沙箱。AgentScope Harness的方案更为精细,沙箱在每次call()结束时将工作区状态打包成快照并存储起来,下次调用时根据需要恢复:

  1. 容器仍存在时,直接复用(速度最快)。
  2. 容器已宕时,利用快照重新创建一个,并恢复工作区状态。
  3. 无快照可用时,执行全量初始化(冷启动)。

快照后端支持多种选择,包括LocalSnapshotSpec(适用于本地单机)、OssSnapshotSpec(兼容S3,适用于多副本场景)以及RedisSnapshotSpec(低延迟,适合小工作区)。在生产环境中只需添加一行配置即可:

.filesystem(new DockerFilesystemSpec()
    .image("agentscope/coding-sandbox:latest")
    .snapshotSpec(new OssSnapshotSpec(ossClient, "my-bucket", "agentscope/")))

长会话记忆:上下文窗口不是无限的

一个冗长的Issue可能包含数十轮对话,git diff的输出可能达到上万字符,mvn test的日志可能多达几十K,这些因素很容易撑爆模型的上下文窗口。

AgentScope Harness的解决方案是四套独立且可组合的机制。对话摘要压缩会在消息条数过多时自动触发,保留尾部原文,将前面的内容压缩成摘要。大工具结果卸载会将超过80K字符的输出写入工作区文件,在上下文里仅保留首尾各约2K字符以及一个read_file路径提示,Agent如需查看全文可以自行读取。参数截断也会截断write_file中较大的输入参数,因为这些内容已经写入文件,后续对话无需再次查看。溢出兜底在确实遇到context_length_exceeded时执行紧急压缩并重试。

HarnessAgent.builder()
    .compaction(CompactionConfig.builder()
        .triggerMessages(50)
        .keepMessages(20)
        .truncateArgs(CompactionConfig.TruncateArgsConfig.builder()
            .maxArgLength(2000).build())
        .build())
    .toolResultEviction(ToolResultEvictionConfig.defaults())
    .build();

这并非可选项。Coding Agent必然会运行长会话,必然会输出大量的diff内容,如果不启用这些机制,迟早会遇到问题。

同时,MEMORY.md会从每天的对话流水账中周期性合并出长期事实信息。随着Coding Agent运行时间的增长,MEMORY.md中可能会积累出类似这样的内容:

- 仓库 owner/repo 的测试命令是 `mvn -pl module test`,根目录 `mvn test` 太慢不要用
- main 分支受保护,必须通过 PR 合并;feature 分支命名约定为 `feat/`
- CI 用 GitHub Actions,配置文件在 .github/workflows/ci.yml

Agent自己学会了团队的规矩,下次就不再需要询问了。所有使用同一工作区的对话都能从中受益。

会话持久化:节点挂了对话不能断

组织级Coding Agent是一个长生命周期的应用。一个Issue可能从早上一直聊到晚上,在此期间服务可能会经历滚动发布、扩缩容、副本切换等操作,但用户感知到的应该是"对话不会中断"。

默认情况下,AgentScope Harness使用本地文件存储状态,这足以满足开发需求。如果需要多副本生产环境,可以切换到Redis,只需一行配置:

HarnessAgent.builder()
    .stateStore(RedisAgentStateStore.builder().lettuceClient(redisClient).build())
    .build();

切换到Redis之后:当节点崩溃时,会话会自动漂移到另一个节点;执行滚动发布时,旧pod会自动保存状态,新pod会自动恢复;甚至在GitHub Issue中聊到一半时切换到钉钉继续对话也毫无问题——只要sessionId保持一致,所有记忆信息都能得到保留。

组织级特有的工程问题

前面讨论的沙箱、恢复、记忆、持久化等机制,是确保一个Coding Agent"能够在生产环境中稳定运行"的基础设施。但组织级场景还面临一些独特的问题需要解决。

多通道接入:同一个Agent接得住所有入口

Stripe的Minions通过Slack访问,Coinbase的Cloudbot也通过Slack,而Open SWE则同时接入了Slack、Linear和GitHub。组织级Coding Agent的一个共识是:不要让用户切换到一个新的界面去寻找Agent,而是让Agent出现在用户已经习惯使用的平台中。

Coding Agent在AgentScope Harness之上增加了一层通道适配器,将不同入口的事件统一映射到(threadId, message):

github:issue:owner/repo#42 → SHA-256 → UUID → coding agent thread
dingtalk:appKey:staffId → SHA-256 → UUID → coding agent thread
feishu:tenantKey:chatId → SHA-256 → UUID → coding agent thread

这种确定性映射确保了同一个Issue的所有评论都能路由到同一个Agent session中,对话历史会自动恢复,用户无需操心。

多租户隔离:谁和谁不能串

个人工具不需要考虑这个问题——只有一个用户,所有状态天然是隔离的。然而,组织级服务从第一天起就是多租户的:可能有几十个Issue、几十个PR、几十个IM对话同时在运行,每个都有自己的代码仓库、依赖目录、对话历史和长期记忆,绝不能发生串扰。

AgentScope Harness使用IsolationScope来控制隔离粒度。SESSION(默认设置)让每个sessionId拥有独立的沙箱——对Coding Agent而言,这意味着每个Issue、PR或IM对话各自独立运行,这是最自然也是最安全的方式。USER则让同一用户的不同对话共享同一份仓库克隆,适用于"个人工作台"场景。隔离不仅限于沙箱层面——会话状态、记忆、子Agent任务也都按照相同的粒度进行隔离,开发者无需额外操心。

并发控制:一个thread同一时间只跑一个推理

Coding Agent通过RunDispatcherMessageQueueHook强制保证这一点。当用户在一个Agent正在运行的过程中又发表了一条新的评论时,新消息不会打断当前的推理过程,而是进入队列等待下一轮开始前被注入——这与Open SWE的check_message_queue_before_model middleware机制类似。

同时,ThreadBudgetHook负责控制每个thread的模型调用上限,ModelCallLimitHook则控制全局上限——确保某个用户的失控循环不会消耗掉整个公司的模型调用额度。

工作区:人格、记忆、技能都是文件

AgentScope Harness将所有需要跨调用、跨重启保留的内容组织成一个目录——workspace。行业内现在将这类设计称为"Context Engineering"。有趣的是,几乎所有主流Coding Agent都独立地走到了同一个模式:Claude Code有CLAUDE.md,GitHub Copilot有.github/copilot-instructions.md,Open SWE有AGENTS.md。仓库级别的规约不应硬编码在system prompt中,而应作为文件存在,这样可以进行版本控制、代码审查和独立更新。

~/.agentscope/codingagent/workspace/
├── AGENTS.md            ← 人格 + 行为约定
├── MEMORY.md            ← 长期记忆
├── skills/              ← 可复用技能(提交规范、测试规范等SOP)
├── subagents/           ← 子agent声明
├── knowledge/           ← 领域知识(API文档、代码规范)
└── plans/               ← Plan Mode计划文件

三个工程价值:

团队规范以文件形式生效。 如果希望所有PR都遵循特定的commit message规范?只需编写一份skill文件放入skills/commit-style/SKILL.md,所有Agent实例在下次call()执行时便会生效,无需重启服务或修改代码。

Agent在使用过程中越来越了解团队。 第一次Agent询问"我们使用哪个测试框架"时,你回答"JUnit 5 + Mockito"。下次call()执行时它就会记住——所有使用同一工作区的对话都能从中受益。

workspace可以当作Git仓库进行管理。 AGENTS.mdskills/subagents/knowledge/共同构成了Agent的"配置仓库"——使用Git进行管理,通过CI进行验证,在部署时将其hydrate到所有副本中。频繁变化的应该是workspace中的内容,而非Java代码。

子agent:把独立任务委派出去

Open SWE通过Deep Agents的task tool实现子Agent派发,Stripe的Minions使用Blueprints进行编排,Ramp的Inspect则采用Sessions和Child Sessions机制。AgentScope Harness同样支持子Agent,而且用法非常轻量——只需在workspace中编写一个markdown文件即可:

# workspace/subagents/researcher.md
---
description: 调研子agent。当需要先了解一个外部仓库或文档再做修改时使用。
workspace:
  mode: isolated
tools: [read_file, grep_files, fetch_url, web_search]
---
你是调研助手。使用fetch_url或web_search收集材料,read_file或grep_files查看代码,
向主agent提供一份包含要点和引用的简报。

主Agent调用agent_spawn agent_id="researcher" task="调研ABC库的v2升级要点",子Agent会在隔离的上下文中完成任务,并将结果返回给主Agent。在后台调用中添加timeout_seconds=0参数,主Agent便不会被阻塞,框架会在下一轮推理时自动将结果注入。

Plan Mode:大改之前先想清楚

让Coding Agent直接着手进行"重构整个鉴权模块"这类高风险操作,可能会产生不可预料的后果——它可能会边思考边修改,导致一片混乱。AgentScope Harness的Plan Mode将这一过程固化为"先构思,形成计划,等待人类确认,再动手执行"的流程。启用Plan Mode后,Agent进入只读阶段,只能调用读取工具和与plan相关的四个白名单工具,退出plan模式需要获得人类的确认。

这与Coinbase Cloudbot的"Agent Councils"理念类似——在高风险操作前加入人类审批节点,通过流程约束来避免过分依赖模型的准确性。

工具精选与确定性兜底

Stripe在公开分享Minions经验时提到了一个观察:他们的Agent拥有大约500个工具,但他们强调"工具的精选和维护比数量更重要"。Open SWE也采纳了这一理念,只暴露了约15个核心工具。Harness也采取了类似的做法,其内置工具集控制在文件操作、shell执行和记忆检索这个范围内,业务工具则通过toolkit.register(...)按需注册。

另一个行业共识是:不能仅依赖prompt告诉模型"记得运行测试",关键步骤必须通过确定性逻辑来保证。 GitHub Copilot Coding Agent在执行完任务后会通过repo现有的CI pipeline进行验证;Open SWE则提供了一个open_pr_if_needed middleware作为兜底——如果Agent忘记创建PR,middleware会自动补上。Harness的middleware机制(如MessageQueueHookThreadBudgetHook等)也遵循同样的思路:需要明确划分哪些事情交给模型决定,哪些事情通过确定性代码来保证。

还有一点值得强调:Draft PR作为输出契约。无论是Copilot Coding Agent、Open SWE还是Stripe Minions,Agent最终的产出都是草稿式的PR,永远需要经过人类审核后才能合并。Agent不允许直接修改生产代码——这是组织级Coding Agent的一个基本安全假设。

从单机到企业:一条演进路线

AgentScope Harness允许从最简单的形态开始,根据需求逐步切换配置——同一份Agent代码逻辑,只需不同的配置就能展现出不同的能力。

Stage 1:本机CLI。 无需任何额外配置。execute直接在宿主的sh -c中运行,状态存储在本地文件中。仅适用于受信任的本机环境——这相当于一个具备记忆和技能功能的增强版本地Coding Agent。

Stage 2:本机 + Docker沙箱。 只需添加一行.filesystem(new DockerFilesystemSpec()...),所有执行操作都将进入容器内部。这适用于GitHub Webhook模式——每个Issue或PR拥有一个临时容器,宿主不会暴露攻击面。

Stage 3:多副本 + 分布式。stateStore切换为Redis,将沙箱快照存储在OSS中,并添加executionGuard进行并发控制。至此,Coding Agent即可实现横向扩展——可以挂载在负载均衡器后面运行多个副本,任何副本都能接住任何用户的任何对话。

.filesystem(new DockerFilesystemSpec()
    .image("agentscope/coding-sandbox:latest")
    .isolationScope(IsolationScope.USER)
    .snapshotSpec(new OssSnapshotSpec(ossClient, "bucket", "prefix/"))
    .executionGuard(RedisSandboxExecutionGuard.builder(jedis)
        .leaseTtl(Duration.ofMinutes(30)).build()))
.stateStore(RedisAgentStateStore.builder().lettuceClient(redisClient).build())

Stage 4:可观测与限流。 Spring Boot Actuator用于暴露健康探针和Prometheus指标,ThreadBudgetHookModelCallLimitHook用于守住模型预算,FallbackModel用于应对上游限流。这些组件组合在一起,便构成了一个"上线后能够稳定运行"的Coding Agent应有的形态。

总结

回顾文中提及的这些项目——Stripe Minions、Ramp Inspect、Coinbase Cloudbot、LangChain Open SWE、GitHub Copilot Coding Agent、Claude Code,再加上AgentScope Harness——它们在编程语言、生态系统、部署形态上各有千秋,但在核心架构决策上却高度一致。这些共同点包括:per-session隔离沙箱、确定性的thread ID路由、middleware拦截链、Agent运行时的message queue注入、repo级指令文件以及draft PR作为输出契约。这种跨项目的架构趋同,本身就是这个领域最清晰的路标,指引着组织级Coding Agent从个人提效工具迈向稳定服务整个团队的工程体系。

文中描述的Coding Agent是一个功能完整且可直接运行的示例,但距离一个生产可用的产品仍有差距。建议直接克隆仓库并运行代码,再深入阅读源码——它将本文讨论的这些工程问题与真实代码一一对应了起来。

如需进一步深入了解,建议查阅AgentScope 2.0官方文档:java.agentscope.io