大模型应用实战

LLM 驱动的自动化测试系列(11):API 测试为什么反而是 LLM 最保守的战场

18.5k star 的 Keploy 首页写着'Expand API Coverage using AI',但把整个开源 Go 代码库翻遍,找不到一行调用大模型的代码——那个 AI 功能只存在于闭源的云端 SaaS。3.6k star 的 Schemathesis 则完全不用 LLM,靠 Hypothesis 这套纯粹的基于属性测试(property-based testing)的模糊测试引擎就能找到真实的服务端 500 错误。反倒是两个不到 100 star 的小项目——AutoRestTest 和 api-automation-agent——才是真正调用大模型 API 的实现。这篇要说清楚:结构化的 API 输入输出天然更适合传统 fuzzing,那 LLM 到底能在这个赛道里做什么传统工具做不到的事,为什么它目前只敢做,不敢像 UI 自动化那样 all-in。

·约 14 分钟阅读·AI Engineering

API 测试相比 UI 测试的天然优势,恰好是 LLM 落地的天然阻力

这个系列前几篇看到的 UI 自动化(无论是自愈定位还是移动端智能体)都有一个共同的驱动力:UI 是非结构化的,屏幕截图和 DOM 树都需要"理解"才能操作,这正是 LLM 的强项。API 测试恰好相反——OpenAPI/Swagger schema 本身就是结构化、机器可读的规范,参数类型、约束、枚举值全部写在 schema 里,不需要"理解",只需要"枚举"。这意味着传统的基于规则、基于属性的模糊测试工具(property-based fuzzing)在这个场景里效率极高,天花板也不低。这篇要验证的核心问题就是规划里提出的:API 测试相比 UI 测试的这个天然优势,为什么反而让 LLM 在这个赛道里落地得更保守?

先给一个反直觉的发现:star 数最高的两个"看起来很智能"的 API 测试工具,一个把 AI 功能完全锁进了闭源云端,另一个压根不用任何大模型。 真正调用大模型 API、把 LLM 用在测试生成核心逻辑里的开源实现,反而是两个不到 100 star 的小项目。这个反差比文章 10 里 Healenium 的情况更极端——Healenium 至少承认自己需要 AI 只是把它做成付费服务,这里有个项目干脆连"我需要 AI"这句话都只印在营销文案里,代码里一行都没落地。


Keploy:18.5k star,AI 功能存在于 README 里,不存在于代码里

Keploy(keploy/keploy,18,480 star,最近提交 2026-09-24,是这三个项目里体量最大、最活跃的一个)的核心机制跟 LLM 完全无关:用 eBPF 在网络层录制真实的 API 调用、数据库查询、消息队列流量,再把这些录制结果原样回放成确定性的测试和 mock。这是一套基于流量录制/回放的传统机制,跟 API 测试生成的"智能"程度关系不大,但它做得很扎实——支持跨 Postgres/MySQL/MongoDB/Kafka/RabbitMQ 的完整基础设施虚拟化,而不只是 mock HTTP 端点,这是它 18k+ star 的真实原因。

README 里单独有一节叫"🤖 Expand API Coverage using AI",写着"Keploy uses existing recordings, Swagger/OpenAPI Schema to find: boundary values, missing/extra fields, wrong types, out-of-order sequences, retries/timeouts",并把这个功能的链接指向 app.keploy.io——这是他们的闭源云端产品,不是开源仓库的一部分。为了验证这句营销文案背后有没有对应的开源实现,我对整个 Go 代码库做了全文搜索:

$ grep -rn "openai\|gpt-4\|anthropic\|claude\|LLM\b" --include="*.go" . | grep -vi test
pkg/agent/proxy/supervisor/supervisor.go:165: // (matches invariant: long-poll, LLM response, pg_sleep(45) are OK).
pkg/agent/proxy/supervisor/supervisor.go:278: // ...long LLM replies, pg_sleep)...

这两处命中跟"用 LLM 生成测试"毫无关系——它们出现在网络代理的超时容忍逻辑里,说的是"如果被测系统本身在调用 LLM API,允许更长的响应等待时间",是把 LLM 当作被测对象的下游依赖来兼容,不是 Keploy 自己在用 LLM。整个开源代码库里,"AI 扩展覆盖率"这个功能没有任何对应的实现代码——不是隐藏得深,是根本不在这个仓库里。这跟 Healenium 的付费墙不是同一种情况:Healenium 的付费墙至少在开源代码里留了一个显式的调用接口和一句诚实的报错文案,Keploy 则是把整个能力完全搬到闭源产品里,开源仓库只保留了一句 README 广告语。 对于想要通过读源码验证"这个工具到底怎么用 AI"的开发者来说,这是一个值得记录的落差:星标数量和活跃度不能替代直接读代码这一步。


Schemathesis:3.6k star,完全不用 LLM,靠基于属性的模糊测试就能找到真实 bug

Schemathesis(schemathesis/schemathesis,3,622 star,2019 年创建,仍在活跃维护)是这个赛道里另一个极端——它不是"AI 宣传大于实际",而是从头到尾都没打算用 LLM,靠纯粹的基于属性测试(property-based testing)就撑起了完整的产品。它构建在 Python 的 Hypothesis 库之上(代码库里 55 个文件直接依赖 hypothesis),核心思路是从 OpenAPI/GraphQL schema 里推导出参数的类型约束,用 Hypothesis 的策略(strategy)机制生成大量边界值、非法值、极端值组合,再根据服务端的真实响应做"适应性测试"(README 原文用词是 adaptive testing——"learns constraints, ids, and auth from responses")。

这套机制能捕获的 bug 类型很具体:500 错误、schema 违反(返回的数据跟文档不一致)、验证绕过(本该被拒绝的非法数据被接受了)、有状态操作链失败(单独测试都通过但组合起来失败)。这些都是可以由 schema 结构直接推导出来的、不需要"理解业务语义"的缺陷——比如一个整数参数的边界值测试(0、负数、INT_MAX、字符串类型的数字),Hypothesis 引擎能穷举出比人类测试工程师想到的还多的组合,而且这套推导完全是确定性的、可复现的、不需要任何外部 API 调用。这恰好印证了规划里提出的问题的答案:结构化的 schema 让"边界值挖掘"这类任务不需要语义理解,传统模糊测试在这里的性价比远高于让 LLM 去猜"这个参数应该填什么"。


真正用 LLM 的两个小项目:AutoRestTest 和 api-automation-agent,分别代表两种落地方式

AutoRestTest(selab-gatech/autoresttest,53 star,佐治亚理工软件工程实验室出品,MIT 协议,GitHub topics 明确标注 llm/multi-agent/reinforcement-learning)是我读过的对"LLM 该用在测试生成的哪一层"回答得最清楚的一个项目。它把 API 测试生成拆成了三个独立的技术层,每一层用不同的技术手段,边界划得很干净:

  1. 测试执行顺序和参数组合的选择——用纯粹的强化学习(OperationAgent/ValueAgent/ParameterAgent/DependencyAgent,各自维护一张 Q-table),奖励函数直接从 HTTP 状态码算出来。比如 determine_bad_response_reward():非成功请求收到 4xx/5xx 反而给正奖励(+1/+2),因为这代表模糊测试成功触发了预期的错误处理路径;determine_good_response_reward() 则反过来,成功请求收到 2xx 才给正奖励。这一层跟 LLM 完全没关系,是标准的表格型 Q-learning。
  2. 跨接口的参数依赖推断——用词向量的余弦相似度(scipy.spatial.distance.cosine 对比参数名和响应字段名的 embedding),判断"这个接口的响应字段是不是应该作为另一个接口的输入参数"。这也不是 LLM 调用,是一套独立的、更轻量的语义相似度技术。
  3. 参数取值和请求体内容的语义生成——这才是真正调用 LLM API 的部分(SmartValueGenerator,基于 OpenAI 接口)。系统提示词和 few-shot 示例(FEWSHOT_PARAMETER_GEN_PROMPT、FEWSHOT_REQUEST_BODY_GEN_PROMPT)指导模型根据字段名和 schema 约束生成"看起来真实"的值——一个叫 email 的字段该填合法邮箱格式而不是随机字符串,一个叫 country_code 的字段该填 US/CN 这类真实枚举值而不是随机字母。更值得记录的是它的失败重试闭环:generate_retry_parameters() 和 generate_retry_request_body() 会把上一次请求失败时服务端返回的真实 HTTP response 对象连同失败的参数原样传回给模型,让模型根据"服务端实际报了什么错"重新生成参数——这是真正的语义级错误反馈,不是靠随机数换一批值再试。

这个三层分工本身就是对"LLM 该用在哪里"这个问题的一个具体答案:"要不要往这里发一个请求"和"这两个字段之间有没有依赖关系",这类决策问题交给强化学习和向量相似度去做,效率更高、更确定;只有"这个字段该填什么样的值才像真实业务数据"这种需要常识和语言理解的任务,才交给 LLM。 README 里给出的实际成本数据也印证了这套分层设计的克制:"testing an average API with ~15 operations using GPT-4o-mini, the cost was approximately $0.1"——LLM 调用被限制在真正需要语义理解的窄环节,所以整体测试一次 API 的成本才能压到几毛钱。

TestCraft-App/api-automation-agent(77 star,MIT 协议)走的是另一条路:它不做黑盒模糊测试,而是直接把 OpenAPI 规范喂给 LLM,让模型一次性生成完整的 TypeScript 自动化测试框架(基于 api-framework-ts-mocha 模板)。LLMService 支持 Anthropic/OpenAI/Google/AWS Bedrock 四种 provider,走的是 LangChain 的工具调用(tool-calling)范式——generate_models() 让 LLM 调用 FileCreationTool 生成 TypeScript 类型模型,generate_first_test() 让 LLM 生成第一版测试文件,generate_additional_tests() 再让 LLM 基于已有测试和模型信息补全覆盖面。它的 prompt 里直接写着行为约束("Create tests for every status code listed in the OpenAPI definition section"、"For non-successful status codes, do not use try/catch blocks... assert directly against the status code"),并给了完整的 few-shot 测试代码范例作为风格锚点。它的生成结果会经过 TypeScript 编译检查和 ESLint 校验,编译失败时触发 fix_typescript() 把报错信息连同问题文件再喂回给模型修复——跟 AutoRestTest 的重试闭环是同一个设计哲学:LLM 的输出不是终点,是需要被确定性工具校验、并在失败时拿着真实报错重新喂给模型的中间产物。

这两个项目分别代表了 API 测试里两种不同的 LLM 落地方式——AutoRestTest 是"黑盒模糊测试 + LLM 只管生成语义合理的取值",api-automation-agent 是"白盒代码生成 + LLM 直接产出整份测试框架"。前者更接近传统 fuzzing 工具的增强版,后者更接近文章 03 讨论的单元测试生成模式在 API 场景下的变体。两者的共同点是:star 数都不到 100,都是学术/个人项目性质,没有一个进入到"高星、被企业广泛采用"的阶段。


为什么这个场景的 LLM 落地反而更保守

把三个项目并排看,答案已经很清楚:API 测试的输入输出高度结构化,这意味着"生成一个合法请求"这件事本身不需要语言理解——只要有 schema,传统的类型驱动模糊测试就能穷举出比人类想到的更多边界情况,而且是确定性、零成本、可无限重跑的。 LLM 真正有增量价值的地方,缩小到了一个很窄的环节:当"合法"不等于"真实"的时候——schema 只能告诉你一个字段是 string 类型、长度 1-50,但不能告诉你这应该是一个人名还是一个 SKU 编码;只能告诉你一个字段是 integer,不能告诉你这是年龄(应该在 0-120 之间才有业务意义)还是订单号(可以是任意正整数)。这正是 AutoRestTest 把 LLM 严格限定在 SmartValueGenerator 这一层、而把顺序决策和依赖推断都留给更便宜的传统技术的原因。

这也解释了为什么 API 测试里没有出现像 Midscene(文章 04)或 MobileRun/AppAgent(文章 06/08)那种"整个决策链路都交给 LLM/VLM"的高星项目:UI 自动化里,"下一步该点哪个元素"本身就是一个需要理解页面语义的问题,没有办法绕开语言/视觉理解;API 测试里,"下一步该调哪个接口、传什么参数"这个决策问题,绝大部分情况下可以由 schema 结构和统计规律(强化学习)解决,只有极少数"字段该填什么才算真实"的子问题需要语言模型。 这种任务本身的结构差异,而不是技术不成熟,才是 API 测试场景 LLM 落地保守的根本原因——这也是为什么高星项目(Keploy、Schemathesis)反而更愿意押注在传统机制上,把 AI 当作锦上添花的功能,而不是核心卖点。


总结

  1. Keploy(18.5k star)README 宣传的"Expand API Coverage using AI"功能完全不在开源 Go 代码库里——对整个仓库的全文搜索确认,代码中出现的"LLM"字样跟测试生成无关,是网络代理对被测系统调用 LLM API 场景的超时兼容逻辑;这个 AI 功能只存在于闭源云端产品 app.keploy.io。
  2. Schemathesis(3.6k star)是一个从设计上就没有使用 LLM 的反例——基于 Hypothesis 的基于属性测试(property-based testing)引擎,靠 schema 驱动的边界值枚举就能发现 500 错误、schema 违反、验证绕过等真实缺陷,印证了结构化输入输出场景下传统模糊测试的性价比优势。
  3. AutoRestTest(53 star)把测试生成拆成三层技术栈:强化学习负责操作顺序和参数组合决策,词向量余弦相似度负责跨接口依赖推断,LLM 只负责生成"看起来真实"的字段取值——三层边界划分清晰,且有失败重试闭环(把真实 HTTP 报错喂回模型重新生成参数)。
  4. api-automation-agent(77 star)走的是白盒代码生成路线:直接让 LLM 基于 OpenAPI 定义生成完整的 TypeScript 测试框架,用工具调用范式驱动文件生成,用 TypeScript 编译和 ESLint 结果反馈驱动错误修复循环,是文章 03 单元测试生成模式在 API 测试场景下的对应形态。
  5. API 测试场景 LLM 落地保守的根本原因是任务结构本身:schema 能穷举"合法",但不能定义"真实"——LLM 的增量价值被压缩到"字段该填什么样的值才符合业务语义"这一个窄环节,绝大部分测试生成决策(顺序、依赖、覆盖率)可以由更便宜、更确定的传统技术(强化学习、词向量相似度、基于属性的模糊测试)完成,这跟 UI 自动化里"每一步都离不开语义理解"的任务结构形成了鲜明对比。

欢迎访问 PrimeSkills —— 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页