任务和验证器钉死,改动才有进退|AI Engineer × Xander Song
- 原始标题
- How to Test Your Agents on Real Tasks With Harbor - Xander Song, Arize AI
- 节目 / 来源
- AI Engineer
- 嘉宾
- Xander Song
- 原始发布日期
- 2026-10-27
- 时长
- 约 56 分钟
- 内容类型
- 会议演讲 / Agent 真实任务评测框架 Harbor
- 原始内容
- 前往原始来源 ↗
用户问过去几个月哪一天轨迹最多、每个模型花了多少钱。REST 和 GraphQL 上没有现成的汇总接口。智能体就一页一页翻,自己加总。数据一多,工具调用堆起来。Arize 的团队给 MCP 加了一件工具:让智能体写一条只读 SQL,直接打到数据库上。工具加上之后,智能体面前变成三样,REST、GraphQL、SQL,它不知道该用哪样。提示得改。改完一句,聊天里看起来少点了几次。Xander Song 要的是另一件事:任务和验证器不动,只改这一句,跑完能看见奖励、SQL 次数、GraphQL 次数和工具调用是升是降。
他是 Arize AI 的工程师,做 Phoenix。Phoenix 是他们的开源可观测、实验和评测平台。字幕把 Arize 听成 Arise、ARIS。这场要介绍的是 Harbor,一个开源框架,在隔离沙箱里用真实数据、按真实任务评测智能体。主题是凭证据发版,不凭感觉。他先声明:自己不是 Harbor 的维护者,到这场为止把自己算成重度用户。Phoenix 他是维护者。演讲是讲解,不是动手工坊。
原始来源:How to Test Your Agents on Real Tasks With Harbor - Xander Song, Arize AI。中文深度整理,非逐字翻译。本文依据 YouTube 自动生成的英文字幕,专有名词和数字可能有识别误差。开场片头略去。与框架无关的寒暄不展开。下文 Harbor、Arize、Phoenix、Daytona、Modal、E2B、Claude Code 按标题和已能对上的公开拼写;其余听写保留原词。
三件套:指令、沙箱、验证器
Harbor 让人用自然语言写下希望智能体做成的事。这些指令放在一份 Markdown 里,交给智能体。智能体跑在一套新的沙箱里,沙箱里放着和这道题有关的真实数据。每道题再定义自己的验证器。验证器只检查:智能体在环境里有没有留下预期的副作用。验证器产出奖励。奖励的例子是二元分数,0 或 1,通过或失败。
他要人在这张简单的图上停一下。任务和数据若现实,验证器若真的写出了这道题上什么叫成功、什么叫失败,就可以把任务和验证器钉死,只改智能体的实现。把这条管道从头跑到尾,改动对这道题是改进还是回退,会有一个信号。再往前一步,编的不是一道题,而是盖住智能体能力表面的许多题。循环在这里闭上。发版可以带上单独靠感觉得不到的把握。
拆开看,一道题有三块。指令是那份 Markdown。环境通常是一份 Dockerfile,里面放这道题要用的数据。Harbor 不管你放哪种数据。例子包括一个 SQLite 文件。字幕多处把 SQLite 听成 SQL light、SQL life,后文有一处直接说后端是 SQLite 或 Postgres,下文按 SQLite。编程智能体很常见的一种数据,是停在某一个提交上的 Git 仓库。验证器放在一个测试目录里,就是一些脚本,等智能体跑完,在环境上检查预期的副作用是否发生。
题通常不止一道,收成一个数据集。数据集里的每道题,Harbor 可以跑可配置次数的试验。试验是同题的独立执行,用来对付随机性:大语言模型是随机的,智能体是随机的,两次行为不一样。每次试验建一套新环境,一只全新的 Docker 容器,种进刚才说的数据。Harbor 把你选的智能体放进去,喂给它那份指令 Markdown,让它自己做。编程智能体通常会改源文件,数据库在里面的话也可能改数据库。做完之后验证器在环境上跑。奖励写进一个文件。那个文件名字幕听成 reward.ext,本文不改成另一个扩展名。
还可以选配轨迹。智能体按一种叫 ATIF 的格式吐出轨迹。ATIF 是 agent trajectory interchange format,Harbor 定的、基于 JSON 的追踪格式,用来看智能体为了留下那个副作用,内部走了哪些步。它服务于调试、日志和记录。
数据集里的全部题目、每题若干次试验、验证器打出的奖励、收上来的轨迹,这一整段从头到尾,Harbor 称为一次 job。字幕有一处把 Harbor 听成 Harper,下文按 Harbor。
先用解答脚本把管子跑通
Harbor 还可以往环境里放的不只是智能体,还有 oracle。oracle 就是这道题的一份解,一段把题做掉的脚本。他后文把 oracle 说成有用,是因为它让人在把智能体投进去、花任何 token 之前,先把管道里的扭结解开。token 是模型计量用量的单位。要确认的是数据是好的,环境配置是对的,验证器按预期工作。
他用一道假设的题把部件走了一遍。关心的智能体是编程智能体,或带一套特定技能的编程智能体,或配了他正在跑的定制 MCP 服务器的编程智能体。任务是修好一次失败的迁移。指令 Markdown 就是用户会说的话:我注意到这次迁移失败了,请试着修好。环境里可以有一份真实的 SQL 文件,一些建表语句(DDL),以及一段包含向上迁移的源码。数据被种成:向上迁移会失败。测试就是脚本:跑向上迁移,确认退出码是 0;再查表,预期的列在不在,预期的索引在不在,迁移是不是真的在系统上留下了预期副作用。解法是可选的,就是一段真能修好这次迁移的脚本。
他愿意写这段解,是为了较快地确信系统装对了、验证器是对的。以他的经验,这样可以对验证器有一份信心,而不必逐行审过去。智能体跑完,会去改那个坏掉的迁移文件,在文件系统上留下几处修改,然后验证器跑。
本地默认用 Docker 跑 Harbor 时,验证器在智能体结束之后才挂进容器。这样智能体在执行期间碰不到验证器,也碰不到解法,免得作弊。
这张图上他要人拿走的一点是:验证器对智能体的实现是无知的。它们对智能体一无所知。它们在乎的是智能体留下了什么。可以写成另一种验证器,去窥视 ATIF 轨迹,按实现或按执行过程打分。那不是他认为的常规验证器。常规做法把智能体当成一只黑箱,只按环境里的副作用和产出打分,不按它产生这些副作用的精确方式打分。
他把它比成集成测试。写得好的接口或 API 集成测试,对接口后面的实现是无知的。好的验证器描述的是:期望智能体做什么、期望它在环境里产生什么副作用,并且和实现脱开。一套测试有这个性质,就可以在测试仍通过时把实现换掉。任务钉死,智能体的实现整个换掉,再很快把管道打一遍,看是不是都还工作。这就是他说的迭代快、发版有把握。
现场有人问到他们正在改的东西。他在把技能收成可复用的一份,让它不依赖智能体从哪边进来:MCP、命令行,或他们自己的服务端智能体。几套智能体体验有大量重叠,也有一些差别。他们走到这一步,是因为吃过反过来做的苦。测试和实现耦在一起,改一个工具,测试就坏,哪怕智能体真正的功能还在。和实现脱开的那套测试,维护才站得住。
每次试验都是一只新容器
每道题、每次试验独立,各有自己的环境、自己的 Docker 容器。整条管道因此可以水平扩展,和 Daytona、Modal、E2B 这类沙箱提供方合得上,想跑多快就可以撕开跑。他们用 Daytona,大约 200 个并发 worker。大套件也能很快撕完。200 是他给的并发规模,节目没有附账单或排队时间。
幻灯片上竖直排了数据集里的四道题,其中包括刚说的修迁移。要试的编程智能体有两套:Claude Code 配字幕里的 Opus 5,以及一格听成 codeex、模型听成 gbt5 的组合。后文又把 codecs 和 Claude、Cursor 放在一起。下文把 codeex、codecs 记成 Codex,gbt5 和 Opus 5 不升成另一份已核实的型号表。试验假设做三次,k 等于 1、2、3,用来对付随机、不完美、每次不一样。彼此独立,就可以在这些沙箱上并行。
单次试验可以收成你关心的汇总指标。例如 pass at k:这道题三次尝试之后过了没有。他指着修迁移那条说,两套智能体都是三次里通过;另一条只有两套里的一套在三次里通过。同一类汇总也可以打在整个数据集上。数据集若盖住你在乎的功能,改动表现得怎么样,这张图来得快。四道题、三次、两套智能体谁在三次里通过,是他讲解这张幻灯片时的画面,不是一份公布的榜。
有人追问那些格子是不是互相看见。每一格是一只完全分开的 Docker 容器,开头相同,放进去的是各自的智能体,然后各做各的。同题、同智能体的几次试验也彼此隔离。等于把 Claude Code 跑三次,每次都说请修好这次迁移,再问三次之后 Claude Code 修好了没有。
轨迹进 Phoenix,Harbor 自己也能看
他把 Harbor 接上 Phoenix。声明再重复一次:Harbor 他不是维护者,只是用户;Phoenix 他是维护者,Phoenix 是 Arize 的开源 AI 可观测工具。这张幻灯片的意思是,Harbor 里的原语在他们这边有对应物。数据集映到他们的数据集,实验被跟踪,试验被记下,奖励转成他们称为评测的那种奖励。
轨迹转成 OpenInference。字幕把这个名字拆开读。OpenInference 是一套开放的语义约定,建在 OpenTelemetry 上面。OpenTelemetry 是记录日志、指标和轨迹的开源遥测框架。这些约定规定 AI 应用可以吐出的数据结构,Phoenix 这类下游再吃进去,才能做出靠这些结构才搭得起来的界面和工作流。他补充,自己也是这份规范的维护者。后半句字幕听成 both imprints。规范不久前捐了出去,字幕说捐给 cloud native,以及一个听成 hotel 的工作组。本文不改成另一家基金会或工作组的正式名。他说这是考虑使用 OpenInference 的一个理由:它在 Arize 外面有了一些牵引。
左边是修迁移那道题的 ATIF 轨迹,能看见单步,包括一次模型调用和一次工具调用。右边是进了 OpenInference 之后的样子。产品里因此可以做专门的界面:按模型和工具来渲染轨迹;给任务和数据集做版本,任何时刻都知道 Harbor 某一次 job 面对的任务长什么样;跟踪实验,把指标和奖励画出来。奖励在这个例子里可以想成通过或失败、0 或 1。连着跑一串实验,能看见奖励是不是朝对的方向走。他们还有技能、命令行和 MCP 服务器,让 Claude、Codex 和 Cursor 容易拿到这些数据。
Harbor 自己有可以在本机跑的开源界面,也有托管的网页服务。用 Harbor 不必用 Phoenix。想要他刚说的版本、实验、可视化和智能体入口,才是试 Phoenix 的理由。
塞得进镜像的,才是这套评测的边界
他们自己的一天长什么样,他用 Phoenix 的架构说明。这是他们团队的形状,别人的项目可以完全不同。左边是终端用户的 AI 应用或智能体,埋了 OpenTelemetry 和 OpenInference,经 OTLP 把轨迹出口到 Phoenix 服务器。OTLP 是 OpenTelemetry 的协议。轨迹可以来自生产,也可以来自正在试的应用。Phoenix 吃进去,写到 SQLite 或 Postgres。数据进了系统之后,有一组核心服务:轨迹、span、会话、数据集、实验、评测。span 是轨迹里的一步。这些服务通过 REST 或 GraphQL 露出来。
他们还要让终端用户、对方的编程智能体和其他智能体容易拿到数据、用上数据。要保住的智能体体验有三面。编程智能体可以用命令行,命令行再去调 REST 或 GraphQL。也可以配他们的 MCP 服务器,做同样的事。第三面是他们自己维护的服务端智能体,名叫 Pixie。Pixie 能用那台 MCP 服务器,因此能用 REST 和 GraphQL,还有一个 bash 模拟器。它像编程智能体,跑在服务端。要测、要保证能工作的,就是这三面:带命令行的编程智能体,带 MCP 的编程智能体,以及他们自己的 harness。harness 是包住模型、让它能调用工具的那一层,这里就是 Pixie。
测的时候他们有一个结构上的便宜:这台服务跑在单节点上。字幕把这种架构听成 graphana-like。本文只保留他紧接着说的那句:单节点,很容易放进 Docker。把整个东西放进一只容器。做法是拿一份 SQLite,里面是他们自己开发、自己使用产品时攒下的、并且已经测过的现实数据;用一个测试客户端换掉浏览器;放进 Docker。然后就可以交给 Harbor,喂他们的用户在乎的那种任务。
例如:从我上周的轨迹里找出一些幻觉出来的模型调用,加进一个数据集。这是用户可能对编程智能体或对 Pixie 说的话。三种智能体里的任何一种,都可以在这个环境里放开做。最后跑验证器。这种布置下验证器可以很简单,因为容器里有一台服务和那份 SQLite。可以打一个 REST 端点,确认预期的副作用已经发生;也可以直接查那份 SQLite,看数据集那张表里的某一行是不是按预期写上了。字幕把行听成 tupil,下文按一行记录。
有人问一张图里是不是同时测三个智能体。一次试验只测一个。可以只测带命令行的 Claude Code,可以只测带 MCP 的 Claude Code,可以只测 Pixie。
Harbor 怎么把提示送进去,他补了一个此前没讲的细节。Harbor 是一个程序,一个命令行工具。它并不跑在 Docker 环境里面。它跑在宿主机上:本地就是你的笔记本,进持续集成就是 GitHub Actions 的 runner。环境默认在本地 Docker 里跑。要规模,就放到沙箱提供方上,例如 Daytona。Harbor 是编排器,在笔记本上或在 GitHub Actions 里把运行踢起来,让智能体开始。驱动方式全是脚本。搭的时候得把脚本放进镜像里该在的位置:有脚本启动任务,有脚本跑验证器,有脚本跑 oracle。脚本在容器里。Harbor 自己留在宿主机上做编排。他把这说成和 Harbor 的合同:镜像要能跑,就是脚本有没有放对地方。
这张图的收获是环境可以改得很自由。人起步最常举的例子,是编程智能体对着一个 Git 仓库。他们的例子不同:一份 SQLite 里的数据,整个应用,连同它的 API、它自己的服务端智能体,容器里是一台在跑的服务,还有命令行。图上没画进去的,是文件系统上还有一套技能,智能体碰得到。能放进 Docker 镜像,Harbor 基本上就能跑它。
分布式系统他没有做过。提问者的系统不是单节点,不是一份 SQLite,要维持的是带对象存储的分布式系统,字幕里举的是 S3。他说那大概更难,而且自己还没碰到,得花很多想。初步想法是把智能体再切出来一点,用一个接口把实现藏起来。若有一道比较稳的 API 边界,喂进去的数据有一种格式,智能体最终能按这种格式拿到数据,这是一条路。他承认这要看具体布置,可能不能令人满意。智能体若真的在查 S3,是不是把那些 S3 调用全部换成假的。一开始换成假的,就回到他们用 Harbor 想离开的那个世界。他没有一个已经试过的答案。他倒是知道 Harbor 能拉起多个 Docker 镜像、转起多件东西。这个功能他前面一直略过。能不能把应用包进其中某一只,他愿意这么去想,没有给结论。
数据要放到多大,他们眼下不做「把整份巨大的 SQLite 或一整套轨迹拿去评」。现在的做法是:这里有一些数据,让 Claude 帮着为这组任务清理一下。Harbor 的一个好处是同一份数据可以给很多道题用,但不是必须。某个问题只用一小子集就能回答,就不必为了这一问把全部数据传上去。若要测的本来就是系统满、数据库相当满时智能体的表现,放进很多数据就完全说得通。他们还没这么做。
只用 Harbor、不用 Phoenix,完全可以。他给 Phoenix 的理由是数据集版本、实验、可视化、智能体体验,以及能很快钻进去看。这些问题他们做了几年,界面为这种钻探调过。
正确性看结果,优化调用会去看路径
最近碰到的问题是:MCP 和命令行能打到 REST 和 GraphQL,用户问的却常常不是这两条路好答的。哪一天最忙、那天有多少条轨迹、每个模型花多少、哪一个模型在全部模型调用里最贵。智能体能找 REST 路由或 GraphQL resolver 时会去找。那些不是汇总用的 resolver。它就自己翻页、自己汇总。数据够多,翻页和工具调用就很多。
他们加上的那一条,就是 MCP 上的只读 SQL。实现细节他没有展开。工具做好之后他们发现:智能体有时并不调用对的工具。它站在 REST、GraphQL 和 SQL 中间,不知道该用哪个。于是得改提示,告诉它怎么做。告诉了之后,还得验证它真的在这么做。改提示是一回事。他们要凭证据发,不凭感觉。
改动很小。改之前提示只提到 GraphQL。改之后说:若面对的是汇总,例如 count 或 group,先用 SQL 工具,别先伸手拿 GraphQL。
要回答这句改动有没有用,先得有现实的数据。他们放进一份半现实的 SQLite,是自己开发、自己使用产品时陆续收集的。他觉得 Harbor 较新的部分是后面这步:让 Claude 去看应用里的域,轨迹、span、数据集、实验,头脑风暴一份用户问法,有的是汇总,有的不是,再为这些问法写 oracle。oracle 就是一次 REST 调用,或一条数据库查询,编程智能体会去写。数据集因此是合成问题。他抽查问题,看它们是不是大体说得通。验证器仍是环境里跑的脚本。有的是让模型当裁判,有的是 SQL 或 REST。因为这些验证器先对着 oracle 通过,智能体还没进系统之前,扭结已经解开一轮,他对验证器有一份信心。
这一句提示测下来,系统如他所料,更频繁、更猛地使用 SQL。他要的是多用,而不是用得不够。不够的话,它会开始靠翻页去做汇总查询。那是坏事。只改这一句,每条轨迹里的工具调用次数、平均次数在往下掉。这正是他们做这件事的原因。数据集不大,不必大量翻页。他认为这些温和下滑低估了问题,因为数据本来就不大。具体掉了多少,节目没有给数。
进 Phoenix 之后,先看见数据集里的例子,也就是那些任务。它们有版本,每次改动都有历史,可以点开看。有的是汇总问法,有的不是。一条他在乎的汇总是:按总花费,最贵的三个模型是哪三个,各花多少。这问用 SQL 比翻 REST 更容易答。下面的答案来自 oracle,是对一份具体数据跑出来的 SQL。答案是确定的。他对此例没有强烈的再核对的需要,并把一份信任放在 Claude 能写出一条好 SQL 上。这是他的取舍。
实验视图就是他在 Harbor 里称为 job 的东西。为这场演讲他跑了很多次 job。图上是人可能关心的指标,花费或运行延迟都有。这道题的奖励相当高,因为他没有做真正会把系统弄坏的事。系统一开始就在给出正确答案,奖励一直高。多出来的是工具调用太多。这是一次优化。答案从一开始就是对的,奖励因此一直高,要压下去的是工具调用。图上能看见工具调用次数,也能看见用没用 SQL。
奖励从哪来,有人问。奖励来自验证器,验证器由定义任务的人控制。每道题写一段脚本,说明什么叫成功、什么叫失败。脚本吐出 0 或 1,通过或失败。奖励的名字可以不叫通过失败。开发者、维护者要自己想:对这道题,成功是什么,失败是什么;只看环境里的副作用,看文件系统或数据库文件,怎么判断智能体成功了。那就是奖励,也是他们沿时间跟踪的东西。视图里跟踪的是整次 job 的汇总奖励。
紧接着的问题戳到他前面的原则。验证器通常对轨迹、对执行路径无知,可是有的验证器明显在看智能体用没用 SQL。这算不算作弊。他说算。验证器最纯的时候,确实不看轨迹,只看文件系统或副作用。那种局面是你在乎正确性的时候。他没在这张图上展示的另一类,是他们做过的回归测试:最终有没有走到正确答案。那些验证器他认为相当纯,不看轨迹,只看答案对不对。这一题他关心的东西略有不同。他在优化一项指标,特别是工具调用。Harbor 可以干很多事。可以做集成测试,可以做端到端,可以用来确认正确性,可以跑在持续集成里。也可以用来对付一个很具体的问题:汇总查询上它表现差,怎样又快又糙地让自己确信,它正在做我希望它做的事。至少对他们来说,至今回看,用哪种验证器取决于你在试图做什么。有时值得朝轨迹里面看。哪怕这会让测试对改动没那么稳。
团队规模他不能用亲身经验回答大团队怎么协作。眼下就是他和少数几个人。Phoenix 在这件事上可能帮上的,是共享数据、从不同来源整理数据、把轨迹加进数据集、把数据存在外部文件里再写回数据库,然后跑。他说的是这些能力在。一套已经在大团队里跑通的流程,节目没有给出。
一句提示前后,奖励不动,路径在动
他用 Phoenix 比较两次 job,粒度到单题。选中的是字幕里的 Opus 5,改那一句提示之前和之后。一列是之前,一列是之后。顶上的指标告诉他:在乎的这些奖励,这一拧之后整体怎么变。GraphQL 工具调用下降,它比以前更少调用 GraphQL。奖励保持不变,意思是仍全部通过。SQL 调用上升。工具次数下降。智能体所花的回合下降,因为原先要好多回合的步骤,被 SQL 收进一个回合。SQL 用得更多,GraphQL 用得更少。在他看来,顶上这些指标用来确认:这是一处还不错的改动。
表里他点开大约四条任务。其中一条就是最贵的三个模型、各花多少。能看见期望答案,能看见每一次 job 的实际答案,能看见指标怎么变。这一条上,工具数下降,回合数下降。SQL 调用数也下降了,这出乎他的意料。四条是比较视图里他展示的数量,节目没有说整套合成题一共有多少道。
过滤是一位叫 Miko 的人最近做的功能。他用自然语言说:找出第二次实验的工具次数低于第一次的那些运行,并用确切的指标名帮它。浏览器里的一个本地模型把这句话转成查询 DSL。那次转坏了。他改口说得换一个更强的。提示接口也有人插了一句。他于是贴进自己知道是对的表达式。滤下来的,是改进了的那些行:以前不用 SQL,现在用了。有一条 SQL 从无到有,次数加一。
点进轨迹,ATIF 已转成 OpenInference 轨迹。改之前它在用 bash,bash 底下在调 GraphQL。他此前介绍 Pixie 时说过,这只服务端智能体有一个 bash 模拟器,模拟器再去调 GraphQL。第二次 job 里对应的那条轨迹,不再经 bash 调 GraphQL,而是直接对数据库发了一条 SQL。他可以看见:这一例上它做对了。他也可以直接问智能体,看一组实验、看一道题,让它说明发生了什么。他们的一部分数据就是这么来的:用智能体,记下轨迹,拿数据,再用智能体改它自己。
回归测试他称为还很早。他们在铺的是顺利路径。结构围绕技能。在他看来,做这些回归时有点像 Playwright:端到端,环里有一个智能体,环里有模型调用。技能在描述工作流,适合写这种测试。眼下是把最重要的技能上的顺利路径钉住,并让顺利路径在他们要支持的那一排模型和提供方上都能过。Playwright 是他的类比,节目没有展示一套已经进持续集成的回归数字。
另一个评论是技能会互相踩。你可以写出世界上最好的一份技能,别人写的另一份若在前置说明上踩到你,它可能不再触发。从不触发,写得再好也没有用。一条路是:不关心哪一份触发了,只要有一个好测试;这份技能没触发,测试多半过不了。另一条路是,像前面说的,验证器伸进轨迹,问给定这个问题,它有没有调用这份特定技能。他们有过这种测试。难处始终是可维护。技能改名,测试就会飘。若只测一个回合,只想知道对的技能有没有触发,甚至不需要很好的数据:问它一句,看技能触发了没有。这种套件可以维持。它更不像端到端,在「和实现完全脱开」到「和实现耦在一起」的谱上,更靠近耦住的那一端,仍然可能有用。他的结论是没有理由不写。覆盖的是你在乎的那些事。
生产里的图和他评测时的图不一样。Phoenix 部署在生产时,轨迹从埋好点的应用或智能体进系统,写进数据库。跑 Harbor 时,OTLP 入口和用户的那个智能体消失,数据库用种进去的数据。评测时他们不假装、也不仿真一个终端用户的应用。他们假定终端用户的应用存在过,并且已经把数据留在那份 SQLite 里。字幕把 OTLP 有一处听成 OTOP,下文按他定义过的 OTLP。
Harbor 的常规用途是评编程智能体。他们做的事情一面相似,评测单位却不是孤立的编程智能体。他们不改 Claude Code,也不改 Codex。要优化的是一个混合体:Claude Code 加上他们特制的 MCP 服务器,或加上他们维护的那一套技能,或加上他们的命令行,或 Claude Code 在和他们的 API 交互。混合体包含编程智能体,又比编程智能体多出他们维护的、让 Claude Code 更会用他们产品的那些配套。这些东西会一起变,就得作为一个单位一起评,所以全部塞进同一个环境。他用了一点时间才在概念上落到这张图。落到得比较快,部分是因为那个便宜:Phoenix 单节点,容易放进 Docker。做分布式系统的人,日子会更紧。这个优势是他们的,不是 Harbor 白送给每一种架构的。
Harbor 难用的地方在于,它要守的合同就是某些目录里的脚本。任务启动脚本放这里,验证器脚本放这里。没有现成的检查器能让编程智能体靠它确认这样放就对。能做的最好的事,是去下 Harbor 的技能,那些技能会帮你把项目搭对。
SQLite 放哪,眼下是一次性的做法。他们有一份通常在用的数据。这道题用得上,他就复用那个文件。用不完全部,就让 Claude 把不需要的切掉,推到云存储。数据才是难的部分。哪一类任务都如此。数据越现实,系统越能替你翻出现实的问题。