尽管,如过去构建 AutoDev 的 AutoCRUD、精准测试功能一样,我们有意去构建一个完全自动化的 API 开发智能体。但是依旧的,我们会遇到一些问题:
- API 设计是需要人类参与的,因为它需要考虑到业务逻辑、数据结构等等。
- API 文档是结合上下文与业务背景的。
- 一次生成大量 API 代码存在大量的安全风险。
- AI 生成大量的代码,需要人类参与进行代码审查。
- 大量的测试可以提升 API 的质量,但是测试的覆盖率、测试的准确性等等,都是需要人类参与的。
- ……
也因此,在当前阶段,我们预期的一个智能体变为了 10+ 个智能体,以降低人的心智负担。也因此,我们开始思考三个问题:
- 过去的流程中,AI 可以参与到哪些环节?
- 如何在 AI 自动化与人类参与之间取得平衡?
- 如何确保生成的 API 和文档符合高质量标准?
也由此,这有了这篇文章的内容。
回顾:经典 API 开发流程
在构建 API 时,通常我们会有两个阶段:商业战略阶段与技术实现阶段。在商业战略阶段,我们会考虑到 API 的业务价值、API 的商业模式等等。在技术实现阶段,我们会考虑到 API 的设计、API 的文档、API 的测试等等。
在技术实现阶段,我们会有以下几个步骤:
- 设计阶段:
- API 上下游的契约设计:确定 API 的输入输出格式,使用开放 API 规范(如Swagger/OpenAPI)定义契约,确保接口清晰一致。
- API 文档编写:编写易于理解的文档,涵盖使用示例、错误码及认证信息,使开发者快速上手。
- 实现阶段:
- 编码实现 API:根据设计文档进行编码,遵循编码规范与最佳实践,注重错误处理和日志记录。
- 开发者手动测试:初步测试 API 的基本功能,确保接口能正常响应请求并返回正确的数据。
- API 单元测试:编写单元测试验证 API 各组件的正确性,确保代码在不同情况下的稳定性与可靠性。
- 集成与联调阶段:
- 应用间集成:确保 API 能与其他系统或服务有效集成,进行端到端测试验证数据流和交互正常。
- 前后端联调:开发团队与前端工程师合作,进行接口联调,确保前端能正确调用 API 并处理响应数据。
- 测试阶段:
- API 功能测试:验证 API 每个功能是否按照设计要求正常工作,确保接口逻辑正确。
- API 性能测试:测试 API 在高负载下的响应时间与稳定性,包括压力测试与负载测试,确保满足业务需求。
- API 安全测试:进行安全性审查与测试,检测潜在安全漏洞,如认证、授权、数据加密等,确保API不易受到攻击。
- 发布阶段:
- API 发布与文档更新:在测试通过后,准备 API 的生产环境部署,更新 API 文档,确保相关方获取最新使用信息。
- 监控与反馈:上线后持续监控 API 使用情况与性能表现,通过用户反馈和日志分析不断迭代与优化 API。
这是一个非常完美的 API 开发流程,但是在实际开发中,我们会遇到大量的问题。毕竟,白天你和各个上下游的人员沟通完,只剩下下班前的半小时,又或者是 晚上的时间来写代码。在你加班加点干完活后,你的代码写完了,但是文档没写完,测试没写完,甚至是你的代码写完了,又或者你的代码不符合规范。
那 AI 可以吗?
试验:API 开发的 10+ 个本地智能体
最近,我们在 Shire 语言中开发了 API 开发相关的智能体包,以支持开发者更好地构建 API。在这个过程中,我们结合了标准 API 开发的流程与 AI 智能体的能力,以向开发者提供更好的 AI 辅助 API 开发体验。
我们创建了 10+ 个智能体,以支持 API 开发的各个阶段,如需求分析、API 设计、API 文档生成、API 代码生成、API 测试等等。当然,对于联调来说, 我们暂时没有很好的设计,除此在发布阶段,暂时也不需要 AI 的参与。
设计阶段:3 个智能体
设计阶段主要由远程(Dify)需求 Agent、本地 Swagger 生成、 Mock 代码生成三个智能体组成。
- 需求 Agent:采用的是远程 Dify 来辅助需求分析,即结合内部的需求信息,生成 API 设计所需要的信息。
- Swagger 生成:根据需求信息,生成 Swagger API 文档。
- Mock 代码与服务生成:根据 Swagger API 文档,生成 WireMock 代码与服务。
在这里,事实上,我们还欠缺了一个设计:结合内部的 API 文档规范和现有的代码库设计。我们在 Shire 中引入了 mock
函数,以直接运行 Mock 服务, 示例: mock("docs/mock_v0-stubs.json")
。
开发阶段:3 个智能体
开发阶段主要由三个智能体组成:结合需求的代码生成、开发测试 API 代码、API 代码测试。
- 结合需求的代码生成:同样的采用的也是在 Dify 中的需求信息,只是在粒度上更细一些,会自动修改 Controller 和 Service 代码。
- 开发测试 API 代码:开发阶段我们经常会采用 Postman 来测试,而在 IDE 中,我们可以使用 Http Client 来测试。所以,我们的智能体会生成 Http Client 手动或者自动进行测试,以检查 API 的正确性。
- API 测试代码生成:根据 Mock API 文档,生成 REST Assured 测试代码。
为此,我们还在 execute 函数中,支持了原先的 Gradle 任务方式,即通过 execute(":bootRun")
可以直接启动 Spring Boot 项目。当然,我们还支持了 commit
、 push
函数,以支持 Git 操作。
测试阶段:2 个智能体
在测试阶段,我们主要结合了四不同的测试框架,以支持 API 的测试:ab 测试、Python 语言的 Locust 测试、JavaScript 语言的 K6 测试、Playwright 测试。
- ab 测试:使用 Apache Benchmark 进行 API 性能测试。
- Locust 测试:使用 Python 语言的 Locust 进行 API 性能测试。
- Grafana k6 负载测试:使用 JavaScript 语言的 K6 进行 API 性能测试。
- Playwright 测试:使用 Playwright 进行 API 功能测试。
虽然这里的四个智能体吹得有点过,但是实际上只是 API 流程中的两个步骤。
遗留文档生成:2 个智能体
而针对于应用缺少 Swagger API 文档的情况,我们构建了四个智能体来解决这个问题:
- SpringDoc OpenAPI 方式
- 添加 SpringDoc OpenAPI 依赖,采用 patch 方式添加 Gradle 依赖。
- 在 Controller 中批量添加 Spring REST Docs 注解。
- Spring REST Docs 方式
- 添加 Spring REST Docs 依赖,同样的也是,采用 patch 方式添加 Gradle 依赖。
- 在测试中批量添加 Spring REST Docs 注解。
我们在 Shire 中添加了 batch
函数,以便于批量添加 Spring RestDocs 注解,示例: batch("add-annotation-to-controller-test.shire)
脚本。
试验思考与总结
结合我们过往在辅助需求与 AutoDev 的开发经验,我们总结了三个思考,以在未来更好的构建 AI 编程智能体:
- 结合流程细化上下文,获得最大可用性与潜力
- 过去的阻塞点依旧在,只是转换为决策点
- 构建多轮自动检验,以确保质量
思考 1:结合流程细化上下文,获得最大可用性与潜力
AI 辅助研发的两种模式是:增强现有与创建新范式。在当前生成式 AI 还不够强大的情况下,我们可以通过增强现有的 API 开发流程,以提升我们的效率与质量。
生成式 AI 绝对不是一句:请生成一个 xxx 的 API。而是结合:
- 设计规范,以确保生成的设计符合规范
- 业务上下文,以获得背景信息
- 开发规范,以确保生成的代码符合质量要求
这就意味着,我们需要打开 API 的开发流程,获得更多的上下文信息,以确保生成的 API 符合我们的预期。
思考 2:过去的阻塞点依旧在,只是转换为决策点
在开发 API 时,我们会按阶段来划分的原因是,每个阶段都需要与不同角色的人员进行沟通,因而会变成一个阻塞点。哪怕有了 AI 的参与,这些阻塞点依旧在, 只是有些可以转换为决策点,有些依旧是阻塞点:
- 设计阶段,需要与产品经理、架构师沟通,以确保 API 的设计符合业务需求与架构规范。
- 集成与联调阶段,需要与前端工程师、下游服务团队沟通,以确保 API 能与其他系统有效集成。
- 测试阶段,需要与测试工程师、安全工程师沟通,以确保 API 能通过各种测试。
AI 可以帮助我们做的是:提供更多的信息,以支持我们的决策。但是,AI 不能帮我们做决策,因为决策是需要人类参与的。
思考 3:构建多轮自动检验,以确保质量
在大部分团队中,你只需要实现业务代码,而不需要实现测试代码等。但是,在结合生成式 AI 代码的背景下,生成的业务代码可能是错的。为了避免出现质量、 返工等问题,最好的方式是:构建多轮自动检验,以确保质量。
- API 设计校验:结合内部 API 设计规范,以确保生成的 API 符合规范。诸如于,我们过去采用的 ArchGuard,便支持这种方式的检查。
- 设计校验:结合 WireMock 来生成 Mock 服务,以确保与 Swagger API 文档一致。
- 自动 API 测试:生成 IDEA 中的 HttpClient(类似于 PostMan) 代码,并自动运行和检查。
- API 输入和输出检验:生成 Rest Assured 测试代码等,以确保 API 的输入输出正确。
除此,我们可以由多个不同的模型来生成两个不同的代码,来进行相互检验。如:一个模型生成的代码用于测试,另一个模型生成的代码用于生产。
总结
在 AI 辅助研发火热的今天,经典的 API 开发模式依旧是不可替代的 —— AI 并不能帮你设计出一个完美的 API,也不能帮你背锅。但是呢,我们可以借由 AI 的能力,来提升我们的效率,提升我们的质量与开发体验。
PS:Shire 相关的 API 设计与开发 AI 智能体实现见:
- 从 Shire IDE 插件的 Shire Marketplace 下载和使用《API 设计、生成与文档》智能体包,即可体验。
- GitHub 阅读示例代码:https://github.com/shire-lang/shire-spring-java-demo 。