基于 2026 年 9 月 9 日更新后的 Seed-Evolving,一次真实复杂代码仓库的端到端开发实测。
最近我一直在用 Apache Fluss 做公司项目的 POC。
Apache Fluss 是一个面向实时分析的流式存储项目。在这个 POC 里,我需要通过 Spark 读取 Fluss 中的数据并Tiering(为什么不用Flink的Tiering去做这里不再赘述) 。原本以为主要工作只是把 Fluss、Spark 和测试环境串起来,但真正开始跑之后,很快遇到了两个典型的工程问题。
由于该项目在公司有保密要求,下面测评我只会截已经提交到Apache Fluss代码库的相关内容。
第一个问题是,当前Apache Fluss版本没有一个Web管理服务,因此为了满足老板们的可视化需求,直接开发一个Fluss Manager Web的工具,改工具需要支持管理Fluss的database/table/server信息,现有 Java SDK 还不能直接读取 Tablet Server 所在机器的资源信息。为了判断节点是否还有足够空间承载后续数据,并为部署规划和故障排查提供依据,我需要扩展 Java SDK,使调用方能够查询 Tablet Server 的机器资源、磁盘总容量、已使用空间和可用空间等信息。
第二个问题更加直接:在 Primary Key 下执行 Spark 读取并触发下推到iceberg,会出现一些异常。它不是简单的配置错误,而是涉及 Spark Connector、Fluss 读取链路以及 fluss-lake-iceberg和fluss-spark 之间的协作。
这两件事放在一起,刚好构成了一次比较完整的 Coding 测试:一个是从需求出发新增能力,一个是从异常现象出发定位并修复问题。
于是,我决定用AI Coding来帮我完成、修复现在面临的问题,正好在火山引擎看到Seed-Evolving新模型的发布,最终决定吧这个艰巨的任务交给 Seed-Evolving。
最终,Seed-Evolving 在没有获得文件位置和实现方案的情况下,完成了 Fluss Java Client和Server的能力扩写,并将 Spark 读取问题定位到 数据湖查询下推读取offset问题。整个过程持续 2小时,修改了 33 个文件,新增或更新了 20 个测试,中间需要人工介入 0 次。
但比“有没有生成代码”更值得关注的是:它能不能理解 Apache Fluss 这样一个复杂代码仓库,能不能持续推进任务,以及它说“已经完成”时,代码是否真的通过了测试。
为什么选择 Seed-Evolving
我使用的是 2026 年 9 月 9 日更新后的 Seed-Evolving,调用的 Model ID 是 doubao-seed-evolving。
Seed-Evolving 并不是一个传统意义上的固定版本。它使用统一的 Model ID 持续升级,新的模型能力会自动生效。按照火山方舟模型页的说明,9 月 9 日这次更新重点增强了 Agent 长程执行、可信调研和多模态理解能力,尤其强调复杂任务的持续规划、工具协同,以及根据真实结果完成最终验收。
官方信息可参考:Seed-Evolving 模型详情(https://ark.volcengine.com/region:cn-beijing/model/detail?name=doubao-seed-evolving)。
这也是我选择它来做这次测试的主要原因。
在真实的软件开发中,生成一段代码并不是最困难的部分。特别是在 Fluss 这样的项目里,模型需要先理解仓库结构,判断代码属于哪个模块,沿着调用链找到相关实现,再完成跨文件修改。
修改完成之后,它还要能够调用 Maven 执行测试,阅读编译错误或测试失败信息,并继续修复。如果工具没有成功执行,或者测试没有真正通过,它应该如实说明,而不是根据代码表面状态提前宣布任务完成。
换句话说,我想测试的并不是 Seed-Evolving 会不会写 Java,而是它能不能完成一条真实的工程链路:从理解需求开始,经过代码探索、方案设计、实现、测试和修复,最终交付一个能够被验收的结果。
这正好对应了 9 月 9 日版本所强调的长程任务执行和结果验收能力。
我如何设计这次测试
为了避免两项任务互相影响,我为新增 Feature 和修复 Spark Bug 分别准备了独立的代码环境。
两个环境都基于相同的 Apache Fluss 基准提交,保留项目原本的开发规范和 AGENTS.md,但不向模型提供已经完成的 PR、后续提交历史或者人工实现方案。
对于 Spark Bug,我只提供实际 POC 中的运行方式、错误现象和必要的环境信息,不告诉它根因,更不直接指出可疑文件。
我把“独立完成”的标准也提前固定下来:Seed-Evolving 不仅要生成代码,还要运行相关测试;Java SDK 必须能够返回预期的 Tablet Server 资源字段,正确处理多节点和信息缺失场景,并且不能破坏现有 API;Spark Bug 必须先被稳定复现,修复后还要通过额外的回归测试。
只有真实命令执行成功、相关测试通过,才算任务完成。
第一项任务:扩展 Java SDK,读取 Tablet Server 资源信息
第一个任务来自 POC 中的真实需求。
在 POC 环境中,数据能不能写进去、读出来只是第一步。随着 Tablet Server 上的数据持续增长,我还需要知道每台机器有多少磁盘空间、已经使用多少、还剩多少,以及 `【CPU、内存或其他实际需要的资源字段】`,才能进一步判断容量是否充足、节点之间是否失衡,以及后续应该如何扩容。
问题在于,这些信息即使存在于服务端或运行环境中,Java SDK 的调用方也未必能够通过一个稳定的公共接口直接获得。这个 Feature 因此不只是增加几个字段,它可能需要同时处理公开 API、客户端数据模型、RPC 消息、服务端信息来源、序列化兼容性和测试。
我给 Seed-Evolving 的需求大致是:
扩展 Apache Fluss Java SDK,使调用方能够查询集群中的 Tablet Server,并获取每个节点的机器资源与磁盘空间等信息。请根据现有架构自行确定公共 API、返回模型、客户端调用链和服务端数据来源;保持现有 API 兼容,明确资源信息不可用时的返回语义,并补充单元测试、必要的集成测试和文档。不要预先假设需要修改哪些文件。
进入仓库后,Seed-Evolving 没有立刻开始写代码,而是先阅读了项目说明和模块结构,随后围绕 Tablet Server、集群节点信息、Admin API 和资源上报等关键词查找已有实现。
它依次检查了 fluss-java、fluss-common,沿着 Java SDK 的公开接口、客户端请求、RPC 消息和 Tablet Server 端的信息来源继续向下追踪。这个过程很重要,因为新增 Feature 最容易出现的问题,不是代码写不出来,而是代码被放在错误的抽象层:资源信息应该由谁采集、通过什么协议返回、哪些字段可以成为稳定的公共 API,都需要先从现有架构中找到答案。
在完成第一轮代码阅读后,它给出的方案是:在 fluss-java 中增加 getServiceNodes,通过 gRPC 获取 Tablet Server 侧的 resourceInfo字段,并为旧客户端或资源信息暂不可用的情况保留明确、兼容的处理方式。
这个方案与我原本对项目结构的理解高度一致。
随后,它修改了 28 个文件,并补充了 SDK 单元测试/RPC 序列化测试/集成测试。第一次运行测试时,出现了gRPC编译报错。Seed-Evolving 没有把任务标记为完成,而是读取错误输出,重新检查了 `proto`,发现问题来自gRPC的proto文件没有编译。
经过 1 次调整后,Feature 的正常路径测试通过。
我又运行了模型看不到的验收测试,重点检查多台 Tablet Server 的结果是否完整、磁盘空间字段是否自洽、节点资源暂时不可用时是否能够稳定处理,以及现有 Java SDK 行为是否保持兼容。最终结果符合预期。
这项任务最能体现的不是代码生成速度,而是 Seed-Evolving 能否把一个新需求放进已有架构。它需要理解 Java SDK、RPC、服务端和 Tablet Server 状态之间的边界,还要判断哪些资源字段适合成为公共接口,以及新增能力会不会影响现有用户。
从最终 Diff 来看,Seed-Evolving 的实现与人工方案的差异基本上为0(我写代码设计、改动也是这个思路)。它完成了主要功能,但在文档、异常处理、兼容性或测试覆盖上仍然需要人工 Review。
代码修改记录如下:
最终PR如下:
改完后Fluss Manager Web效果达到预期目标。
第二项任务:修复 Spark 读取 Bug
第二项任务来自 POC 过程中真实发生的 Spark 读取问题。
在 primary 下,通过 Spark 读取 Fluss 的 时,任务会出现
从表面上看,问题发生在 iterator,但异常堆栈并不能直接说明真正的错误来自哪里。
这一次,我给 Seed-Evolving 的任务是:
请先复现这个 Spark 读取问题,再沿调用链定位根因并完成修复。不要只根据异常堆栈猜测修改位置。修复后需要补充回归测试,并运行受影响模块的相关测试。只有测试真实通过后,才能声明任务完成。
另外值得一提的是,Seed-Evolving的多模态能力还是不错的,我给他的错误堆栈信息是一张截图它也能完成立即
Seed-Evolving 首先根据 POC 的运行方式定位到 spark-common/spark/ut,随后继续检查 相关读取流程
它最初怀疑问题来自 迭代器使用错误,并查看了 【IcebergRecordReader。但在对照配置、数据类型和执行路径后,它发现第一次判断并不能解释 【某个关键现象】 没有数据这个迭代器就报错,迭代器有empty判断,于是继续向下追踪到 LogChangesIterator。
最终,它将根因定位为:
是由于查询下推offset信息错误,导致异常发生。
这个定位过程比最终的代码修改更有价值。因为如果只是针对异常位置增加判空或捕获异常,可能会让当前错误消失,却无法解决真正的数据读取问题。
确定根因后,Seed-Evolving 修改了 7个文件,并新增了一个能够稳定复现问题的测试。第一次修复 通过测试,随后在 Iterator为空判断下 下又暴露出 Offset异常问题。
它继续根据测试返回结果调整实现,最终使原始失败测试和相关模块测试全部通过。
整个过程中,我特别关注它有没有“提前宣布完成”。Seed-Evolving 在 某次命令失败或测试仍在运行 时 自动进一步排查。这一点与 9 月 9 日升级强调的工具执行可靠性和结果验收直接相关:一个 Coding Agent 是否可靠,很大程度上取决于它能不能区分“我已经写了代码”和“代码已经被证明可以工作”。
Seed-Evolving 真的能独立完成吗?
经过新增 Feature 和修复 Spark Bug 两项任务,我对 Seed-Evolving 的结论不是简单的“可以”或“不可以”。
在 Bug 修复任务中,它 完全独立完成。它能够从 Spark 的错误现象出发,阅读多个模块,沿调用链定位问题,并通过真实测试验证修复。这说明它处理的已经不只是局部代码补全,而是需要仓库理解、根因分析和持续验证的复杂工程问题。
在 Feature 任务中,它 少量人工介入完成。相比修复 Bug,新增 Feature 没有明确的错误堆栈可以追踪,需要模型自己判断架构位置、接口设计和兼容策略。Seed-Evolving 完成了 扩写了Java SDK新功能,但在 设计上还需要一点点人工判断的地方 上,Maintainer Review 仍然不可替代。
这次实测与 Seed-Evolving 9 月 9 日升级所强调的方向基本一致。
最明显的变化,不是它突然能够生成更多代码,而是它更像一个会持续推进任务的 Coding Agent:它能够在大型仓库中寻找上下文,围绕一个目标进行跨文件修改,调用终端工具验证结果,并在测试失败后继续修复。
尤其值得关注的是,它是否真正完成了“理解需求—修改代码—运行测试—检查结果—继续修复”这条端到端链路。对于复杂代码仓库来说,这比一次生成出看似正确的 Patch 更重要。
当然,两项任务也不能证明 Seed-Evolving 可以无需审查地向 Apache Fluss 主干提交代码。分布式系统中的并发边界、长期兼容性和架构选择,仍然需要熟悉项目的开发者作最终判断。
但它已经可以承担一部分过去需要开发者持续盯着完成的工作:代码探索、调用链分析、初步实现、测试补充和多轮修复。人的工作重心则开始从逐行编写代码,转向定义问题、设置验收标准、审查架构和判断最终结果。
所以,如果要回答标题中的问题,我的结论是:
在这次 Apache Fluss POC 中,Seed-Evolving 已经能够
在少量人工介入后完成真实的 Spark Bug 修复,并将一个新 Feature 推进到可测试/可 Review/可合并的状态。
但这次体验真正让我印象深刻的,并不是它一次写对了多少代码,而是它开始具备一种更接近真实开发者的工作方式。
面对 Apache Fluss 这样一个模块众多、调用链复杂、工程规范严格的开源项目,Seed-Evolving 没有停留在根据报错修改几行代码。它会先阅读仓库,理解不同模块之间的关系;会沿着 Spark 到 Fluss 的读取链路寻找上下文;会在方案不成立时推翻第一次判断;也会实际运行编译和测试,根据返回结果继续调整实现。
这种能力意味着,Coding 模型的价值正在从“帮开发者写代码”,向“和开发者一起完成工程任务”变化。
尤其是在 Spark Bug 的修复过程中,Seed-Evolving 展现出的并不是简单的代码补全能力。它需要从异常现象出发,跨越多个模块寻找真正根因,再通过回归测试证明修复有效。到了 Feature 开发阶段,它面对的甚至不再是一个已有答案的问题,而是需要自己理解需求、选择架构位置、处理兼容性并补齐测试。
能够同时应对这两种任务,说明 Seed-Evolving 对复杂代码仓库的理解已经不只是停留在文件和函数层面,而是开始进入模块关系、执行流程和工程约束的层面。
这也让我更直观地感受到 9 月 9 日这次升级的意义。
所谓长程任务能力,并不是模型能够输出一段更长的回答,而是它能否在长时间、多步骤的执行过程中记住目标,持续调用工具,处理失败,并把任务推进到最终验收。所谓工具调用更可靠,也不是多执行几条命令,而是它能否真正读取命令结果,在测试失败时承认失败,在证据不足时继续检查,而不是提前宣布完成。
在这次测试中,Seed-Evolving 把“理解需求—探索仓库—设计方案—修改代码—执行测试—处理失败—重新验收”连接成了一条相对完整的工程链路。对于开发者来说,这比单次生成一段看起来正确的代码更有价值。
当然,它仍然不能替代 Apache Fluss Maintainer 的最终判断。分布式系统里的并发边界、长期兼容性和架构演进,依然需要经验丰富的开发者把关。但 Seed-Evolving 已经能够承担大量高强度、重复而又需要上下文理解的工作,让开发者把更多精力放在需求定义、架构决策和最终 Review 上。
过去使用 Coding 模型,我经常需要不断告诉它“接下来做什么”;而这一次,我更多是在定义目标和验收标准,然后观察它如何把任务向前推进。
这是一个很明显的变化:开发者不再只是向模型索要代码,而是开始把一项完整工作交给模型。
Seed-Evolving 这个名字也很贴切。它不是一个发布后就停在原地的模型,而是通过统一 Model ID 持续吸收新的 Coding 和 Agent 能力。对于开发者而言,不需要反复迁移接口,也不用追逐一连串版本号,就能持续获得更新后的工程能力。
如果说过去的 Coding 模型更像一个随叫随到的代码助手,那么这次 9 月 9 日更新后的 Seed-Evolving,已经更接近一个能够进入真实仓库、使用真实工具、接受真实测试的工程协作者。
它最值得期待的地方,不是能替开发者多写多少行代码,而是开始帮助开发者真正把复杂的事情做完。
当模型能够读懂仓库、找到问题、完成修改,并用真实测试证明自己的结果时,Coding Agent 才真正从“代码生成工具”走向了“工程生产力”。而 Seed-Evolving,正在把这条路走得越来越扎实。

