最近很多团队开始尝试让 AI 编程 Agent 在浏览器里跑任务、多个人同时盯一个云端开发环境。你可能会产生一个疑问:现在大家在本地终端里用 Claude Code、Codex 这类工具不是已经很顺手了吗,为什么还要搬到云端去?
这个疑问背后,其实是 AI 编程工作方式的再一次迁移:从“开发者自己机器上的一套本地 harness”走向“多人在线共享的云端执行环境”。公开讨论里,Charlie Holtz 是愿意认同“多人云端开发环境将取代本地 harness”这个判断的人之一。我不想把这次讨论搞成“名人背书”式的预测,真正值得关心的是:为什么这个判断会让许多每天和 Agent 打交道的人产生共鸣。
这篇文章会把三个问题拆开讲清楚。第一,harness 到底是什么,为什么它比提示词工程更接近 Agent 的真正骨架;第二,多人云端开发环境相比本地 harness,到底改变了哪个环节;第三,如果这个判断成立,一个普通项目团队应该怎么低成本验证、怎么迁移,以及有哪些安全边界不能碰。
1. 为什么“本地 harness 将被取代”值得较真
在过去一年里,AI 编程工具的角色发生了明显的转换。早期它是“补全下一个 token”的编辑器插件,后来进化成能改文件、能跑测试、能修复报错的 Agent;再往后,它能自己执行多步任务,改完前端改后端,跑完单测跑集成测试,甚至直接在云端临时环境里开一个预览站点。角色改变之后,一个尴尬的问题出现了:Agent 的工作现场在谁手里、以什么形式存在?
如果你是在本地终端里运行一个 coding agent,那么整个执行过程中的文件系统、会话状态、历史记录、测试输出,全都绑定在那台电脑上。只有你自己能看到完整的执行轨迹。同事想知道 Agent 做了什么,只能等你贴一段聊天记录,或者把一次次git diff单独拉出来看。这还算好的。更常见的情况是,团队里两个人同时在本地挂 Agent,各改各的模块,最后提交 PR 时撞在一起,合并起来像一场没有裁判的辩论。
另一个值得注意的信号是,检索关键词里开始出现大量类似“codex harness”“deepseek harness”“deepseek harness 桌面版”“deepseek harness 插件”的组合词。这种词并不一定指向某个统一产品,它反映的是很多使用者在用“模型名 + harness”来指代“让模型跑起来的那层工程外壳”。有一部分是官方提供的工具组件,有一部分是社区教程把某个模型简单地包进现成命令行框架。如果你在搜索时看到这些词,不要默认它们是同一个东西,更重要的判断是:harness 已经从内部术语变成了一个被广泛使用的日常词汇。
之所以说这个话题值得较真,是因为它不再只是“哪个 IDE 更好用”的产品偏好问题。它关系到团队把状态、权限、日志、评审机制放在哪里,把哪一层作为 Agent 的执行基础设施。当 Agent 真正开始独立完成多步骤工程任务时,执行环境的可共享性和可观测性会成为一个架构决策,而不是一个编辑器设置项。
2. harness 到底是什么,不是什么
要讨论“多人云端开发环境会取代本地 harness”,首先得把 harness 这个被滥用得厉害的概念说清楚。它不是一个具体软件的独占名称。这里讨论的 harness,可以理解为包在语言模型外面的工程套具:模型本身只负责推理和生成文本,而真正让它变成“能改代码、能查文件、能执行命令、能遵循审批流程”的东西,是 harness 提供的工具、上下文、权限和状态管理。
用一个类比来说,模型像是一个新入职的工程师的脑子,推理能力很强,但对你的代码库一无所知。harness 是这个新员工入职后获得的整套办公系统:可能是一台开发机,一堆可用工具,一套项目文件访问权限,一份操作手册,还有必须经过审批的操作流程。同一个脑子,配上一套糟糕的 harness,可能只会写出正确的废话;配上一套设计良好的 harness,才能真正交付可运行的代码。你在网上搜索到的各种“XX 模型 + harness”组合,本质上都是在尝试给模型搭一套合适的办公系统。
如果继续拆解,一个相对完整的 agent harness 通常由几部分组成。工具执行层负责把模型的想法变成实际动作,比如修改文件、运行 shell 命令、搜索代码、调用数据库客户端;上下文管理负责决定该让模型看到哪些文件和历史信息,避免无关内容冲淡关键信号;权限与审批层负责在风险操作前拦截,例如是否允许执行危险命令、是否允许写入受保护路径;状态管理负责保存会话、任务清单和中间产物,让 Agent 能够长时间工作并在出错时恢复。上面任何一块缺失,模型的智商都很难转化为项目产出。
这里需要破除几个常见误解。第一个误解是“本地 harness 等于本地模型”。完全不是一回事。即使你用的是云端模型 API,只要执行环境还在你的笔记本上,那依然是本地 harness。第二个误解是“harness 就是提示词”。提示词只是上下文的一部分,工具定义、权限策略、执行回滚机制往往比提示词更决定成败。第三个误解是把 harness 和某个 CI/CD 产品混为一谈。确实有一家叫 Harness 的持续交付平台,但这个讨论里的 harness 是一个通用工程概念,指的是围绕 Agent 的整套控制壳,而不是特定公司。混淆这两者,会在阅读大量资料时产生不必要的困惑。
3. 多人云端开发环境到底改变了什么
云端的开发环境并不是一个新概念。早在 AI Agent 流行之前,远程开发机、网页版 IDE、容器化工作区就已经存在很多年,它们做的事情是把开发环境从个人电脑挪到服务器上。多人云端开发环境的真正区别,在于这样一个转变:开发环境不再只是给人用的交互界面,也变成了给 Agent 用的执行空间,而且这个执行空间是多个 Agent 和多个人类共享的。
你可以把这种环境理解成一个类似“共享实验室”的体系。仓库、依赖、构建结果、测试报告、预览服务都在云端某个可寻址的工作区里,多个 Agent 可以像多个实验员一样在里面并行工作。一名 Agent 负责重构某个模块,另一名 Agent 跑全量测试,第三名 Agent 站在评审视角检查安全风险和改动范围,而人类则在统一的看板里审批关键操作。与本地终端里一个 Agent 单打独斗相比,最大的变化不是“用浏览器访问代码”,而是执行状态从个人私有变成了团队可见、可暂停、可回滚、可审计的公共资产。
多人云端开发环境还有一个容易被忽略的优势:它把“可临时生成”这件事变得很自然。本地每次跑集成测试、拉起一个预览服务、模拟多种依赖环境,都需要开发者自己的机器具备足够的算力和磁盘。云端环境可以针对不同任务临时创建容器,任务结束后直接销毁,环境配置写成代码放进仓库。这意味着 Agent 可以在完全隔离的临时环境里做高风险操作,而不会污染团队的主仓库或某台开发机。
这个方向之所以和 Agent 化趋势高度契合,本质上是因为 Agent 的工作模式更接近“在机器上执行任务”,而不再只是“给人类补全代码”。当一个程序需要替你完成多步骤工程任务时,它必须拥有真实可运行的环境,必须能安装依赖、修改配置、执行测试、启动服务,并且要能在出错后重建。个人电脑显然不能每次都承担这种不确定的风险,多人共享的云端开发环境则更适合作为这类任务的默认执行层。
4. 本地 harness 与多人云端开发环境对照
先把两种模式放在一张表里对比,后面的分析会更有方向感。
| 对比维度 | 本地 harness | 多人云端开发环境 |
|---|---|---|
| 执行载体 | 开发者个人电脑 | 云端容器、虚拟工作区或远程开发机 |
| 状态归属 | 会话状态在本地,别人不可见 | 工作区状态在云端,团队可访问、可追溯 |
| 文件系统 | 以本地磁盘为准 | 云端共享仓库与构建产物 |
| 协作方式 | 单人或通过 Git 异步交叠 | 多人、多 Agent 共享同一环境和评审通道 |
| 计算能力 | 受个人电脑限制 | 可按任务申请更大算力或完整服务栈 |
| 审批与审计 | 审批发生在本地终端,难以留痕 | 审批与日志集中在团队可查的地方 |
| 安全边界 | 源码留在本地,但个人电脑防护参差 | 源码集中到云端,需要额外治理访问策略 |
| 离线可用 | 较好,不依赖服务端 | 基本依赖网络和云平台 |
| 成本模型 | 固定电脑成本,追加算力代价高 | 按时或按任务计费,闲置要及时回收 |
| 最合适的使用阶段 | 快速原型、私有仓库单文件修改 | 多步 Agent 任务、并行协作、需要审计的团队场景 |
这张表不是在说本地模式一无是处。实际上,在很多场景里本地 harness 仍然是最顺手的起点。比如你只想快速让 Agent 改一个函数、跑一次单元测试,本地启动几乎没有额外开销;又比如项目处于高度保密阶段,代码暂时不能落到任何外部环境,那本地执行就是唯一选择。真正变化的是“默认位置”:当 Agent 承担的任务越来越接近一个完整开发者的日常工作时,团队会逐渐倾向于把主执行环境搬到云端,而把本地作为一种应急和调试模式。
这种位置迁移带来四个深层影响。第一,状态从“我机器上的文件”变成了“团队可寻址的资源”,二元的 Git 合并不足以描述 Agent 的所有中间动作,云端工作区保留了命令历史、日志和缓存,排错时能回放当时的环境。第二,审批从“终端里按一下 y”变成了“团队通道里的一次可审计决策”,这让 Agent 有可能进入更正式的工程流程。第三,一次运行的结果可以被复制,同一份环境定义可以由任意成员重新拉起来执行,这在本地很难做到。第四,单 Agent 优化的思路会被多 Agent 调度的思路取代,任务拆分和资源并发成为更值得设计的事项。
5. “多人 + 云端 + Agent”会形成正向循环吗
如果仅仅是换一台机器运行 Agent,那还不足以构成颠覆性的判断。真正让“多人云端开发环境取代本地 harness”这个判断有分量的原因,是在云端环境里,Agent 工程能够形成一套持续的改进循环。
本地 harness 很难沉淀团队经验。每个工程师电脑里的终端配置、权限习惯、使用的工具组合各不相同,Agent 在这台电脑上跑得流畅,换一个人可能就变得非常不可靠。而把执行环境搬上云端并编写成配置后,环境就变成了代码。这份配置可以跟随仓库走,新成员加入时不需要在自己的电脑上反复调试环境;Agent 在不同任务中遇到的失败案例和策略调整,也可以沉淀到公共的策略文件、日志和评测数据里。
打个比方,这就像数据库技术从“每个开发者本地维护一份数据文件”过渡到“统一使用一个由团队管理的数据库服务”。乍看只是把文件挪了个地方,实际上却催生了事务、权限、备份、监控这一整层工程能力。云端 Agent 环境同理:当多人共享一套可重复的 Agent 执行平台时,工具权限、审批流、日志审计、成本配额才能被当作基础设施来设计。
不过也要冷静看待。正向循环的前提是团队真的把 Agent 任务当成工程来治理,而不是只在云端开一个在线编辑器。如果只是把本地终端的坏习惯原样搬到网页版终端里,那依然享受不到这个循环的收益。真正会形成正向循环的团队,通常具备三个特征:一是所有环境都通过代码描述,可以重复生成;二是 Agent 的每一次关键操作都有日志和评审记录;三是每次失败都会被当作改进 harness 配置的素材,而不是归咎于模型不够聪明。当这三个条件成立,云端多人环境就远远不只是 a remote IDE 那么简单的产品。
6. 一条可落地的迁移路径:从本地执行到云端共享执行
趋势判断可以聊得很远,但工程团队需要的是验证步骤。下面我会给出一个比较务实的迁移路径,先跑通最小链路,再逐步扩大范围。请注意,以下代码和配置是示范模板,字段可以根据自己团队的规则调整,不绑定任何具体商业产品。
6.1 先把项目容器化
多人云端开发环境的第一步,是让项目环境可重复。最常见的文件是.devcontainer/devcontainer.json,它描述了一个开发容器需要的镜像、工具、端口和启动命令。单独在本地执行或推送云端时,由平台根据这份配置生成工作区。
{ "name": "team-agent-workspace", "image": "mcr.microsoft.com/devcontainers/universal:2", "features": { "ghcr.io/devcontainers/features/python:1": {}, "ghcr.io/devcontainers/features/node:1": {} }, "customizations": { "vscode": { "extensions": [ "ms-python.python", "dbaeumer.vscode-eslint" ] } }, "postCreateCommand": "python -m pip install -r requirements.txt && npm install", "forwardPorts": [3000] }这份文件的核心价值是统一。之前团队成员总会在“我这边能跑啊”这件事上争论不休,使用容器化配置后,Agent 和开发者面对的是同一套可复现的环境。如果使用支持 devcontainer 的云端开发平台,只需要把这个 json 放进仓库,云端平台会自动根据它创建工作区。如果在本地想先体验,也可以用 devcontainer 命令行工具在当前文件夹里启动容器验证。
6.2 第二步:把 Agent 权限和命令写进策略文件
本地 harness 时代,要不要允许 Agent 执行某条命令,很多时候依赖你在终端里随手按下的 y 或 n。到了多人云端环境,这种个人判断必须变成策略文件,否则不同人在不同任务里的审批标准完全不一致。
下面是一份示意性的策略文件agent-policy.yaml,用于描述允许命令、禁止命令、Agent 可以修改的路径、哪些操作需要人工审批。
version: "1.0" workspace: "/workspace/repo" tool_policy: - tool: "bash" enabled: true allow_prefix: - "git status" - "git diff" - "git add" - "git commit" - "python -m pytest" - "node --test" deny_pattern: - "rm -rf" - "git push --force-with-lease" - tool: "file_edit" allowed_roots: - "/workspace/repo/src" denied_files: - "/workspace/repo/.env" - "**/*.pem" approval_rules: - subject: "git push" mode: "manual" - subject: "dependency_add" mode: "manual" logging: trace_to: "/var/log/agent-traces"在实际项目里,策略文件的设计有几个原则值得遵循。第一条是最小权限:不给 Agent 任何它当前任务用不到的命令或路径权限。第二条是 deny 比 allow 更可靠,你要先定义允许列表,再用禁止列表补上边界。第三条是不要把密钥写进配置文件里,Agent 运行时的凭证应当来自独立的安全存储并由平台注入。第四,策略文件本身需要走代码评审流程,不能由某个工程师随手改动。
6.3 第三步:给 Agent 提供云端执行入口
有了受控环境,还需要一个执行入口。下面是一个极简的云端 Agent 任务执行器示例run_agent_task.py,它会读取task.json中的命令序列,在策略限制下执行并输出结构化结果。实际生产级实现会比这复杂得多,这里只是为了展示“执行层 + 策略层”的基本结构。
"""极简云端 Agent 任务入口(示意)。 前提:本脚本运行在共享云端工作区/容器中,只负责把任务描述中的 shell 命令限制在白名单内,不适合直接作为生产安全边界。 """ from __future__ import annotations import json import subprocess import sys ALLOWED_PREFIXES = ( "git status", "git diff", "git add", "git commit", "python -m pytest", "node --test", ) def run_shell(command: str) -> dict: if not any(command.startswith(p) for p in ALLOWED_PREFIXES): return {"ok": False, "error": f"command not allowed: {command}"} proc = subprocess.run( command, shell=True, text=True, capture_output=True, cwd="/workspace/repo", timeout=300, ) return { "ok": proc.returncode == 0, "exit_code": proc.returncode, "stdout": proc.stdout[-4000:], "stderr": proc.stderr[-4000:], } def main() -> None: task_file = sys.argv[1] if len(sys.argv) > 1 else "task.json" with open(task_file, "r", encoding="utf-8") as f: task = json.load(f) for step in task.get("steps", []): result = run_shell(step["command"]) print(json.dumps({"step": step["name"], **result}, ensure_ascii=False)) if not result["ok"]: sys.exit(1) if __name__ == "__main__": main()对应的task.json可以这样写:
{ "steps": [ { "name": "查看仓库状态", "command": "git status" }, { "name": "运行单元测试", "command": "python -m pytest" } ] }跑起来的方式也很简单:
docker run --rm -v /srv/team-agent-data:/workspace/repo \ -e GIT_SAFE_DIRECTORY=1 \ agent-workspace python run_agent_task.py task.json这里的重点是:命令只能在白名单内执行,执行目录固定在/workspace/repo,输出结果会返回给上层调度。一旦 Agent 运行在共享环境里,任何人都能看到这个容器执行了什么命令、输出了什么,而不是像本地终端那样只有当事人知道。
6.4 第四步:把日志与回滚纳入流程
把 Agent 迁到云端后,最容易忽略的是日志和回滚。本地环境下,命令历史就在终端里,一关机就消失;云端环境下,你应该主动让每条命令、每次审批、每次文件修改都留下可检索记录。上面的示例已经把日志路径指向/var/log/agent-traces,实际生产环境建议接入团队已有的集中日志平台,按任务 ID 关联所有相关记录。
回滚策略同样要在迁移前想清楚。Agent 每完成一个有意义的阶段,都应该对应一次 commit 或一次 checkpoint。这样即使 Agent 后续操作把环境搞坏了,团队也能回到最近的稳定点,而不是从头重来。云端环境的“可重建性”也是回滚的一部分:某个容器被销毁后,只要镜像和配置还在,可以立刻拉新容器,而不需要等待某位工程师修好自己的本地环境。
7. 这个判断落地前,需要观察哪些信号
从公开讨论看,Charlie Holtz 的认同之所以有代表性,是因为这类判断往往来自一线工程经验。但任何人说某个趋势会“取代”另一样事物时,我们都应该问一句:如果要把它当作团队决策依据,到底看什么信号?
第一,Agent 在云端环境里的多步骤任务成功率,是否稳定超过本地运行的同等任务。这个指标不会只来自一次演示,而需要一段时间的真实数据。第二,一个团队能否把知识沉淀为可复用的 harness 配置,而不是每个项目都从零开始折腾。如果云端环境让人人都能用上团队沉淀的工具权限和经验,迁移的动力会显著增强;如果只是换了一个远程终端,那动力不大。第三,安全与合规边界是否被真正解决。团队必须接受源码在云端运行,并为此设计访问控制、审计和外部审查机制。云厂商不同,细节标准也不同,没有通解。
同时,也有两类说法需要警惕。其一,不要相信“本地 harness 马上就会消失”。代码开发永远存在保密要求高、网络条件差、需要快速实验的时刻,本地模式至少会在一个较长周期里作为重要模式存在。更准确的表述是:默认执行重心会转移,而不是某一天彻底消失。其二,不要因为某个有影响力的技术人认同某个判断,就立刻改变自己团队的架构。明星开发者站在聚光灯下,其观点代表真实样本,但不代表所有行业的约束条件。严谨的做法是把自己的项目放到这种模式里跑一轮小型验证,用数据替代情绪。
8. 常见问题与排查思路
把 Agent 从本地迁到多人云端环境时,会碰到一些典型问题。这里整理成一张排查表,方便