尽管,如过去构建 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 。