1. AI 功能测试到底在测什么:从确定性断言到概率性评分
传统软件测试的核心是确定性。你写assert(calculator.add(1, 1) == 2),只要代码没改,这个断言永远成立。测试用例的预期结果是唯一的,实际结果和预期结果一致就通过,不一致就是 bug。这套逻辑支撑了过去几十年的软件质量体系,等价类、边界值、判定表、状态迁移,全都是围绕"输入确定、输出确定"这个前提建立的。
AI 产品把这个前提打破了。同一个 Prompt 发给模型,三次可能得到三种措辞完全不同的回答。你问"什么是人工智能",第一次回答从计算机科学分支讲起,第二次强调学习推理决策能力,第三次搬出学科定义。三次都对,但三次都不一样。这时候你没法用==去断言,只能定义一套评分标准,给每个回答打分,再看整体得分是否过线。
这就是 AI 功能测试的第一个思维转变:从"对不对"变成"好不好"。判断方式从二值断言变成连续评分,从测一次变成测多次,从找 bug 变成找风险。AI 的风险特点是不会崩溃、不会报 500、界面完全正常,但输出内容可能编造事实、泄露隐私、被注入绕过。这类问题比传统 bug 更难发现,因为它藏在"看起来合理"的回答里。
面向 AI 产品测试入门,有三条主线必须抓住:Prompt 输入测试、输出一致性测试、幻觉识别测试。Prompt 决定了模型能拿到什么信息、按什么约束输出;一致性决定了同一个功能在多次调用下是否稳定可信;幻觉识别决定了产品会不会一本正经地胡说八道。这三条线覆盖了 AI 功能测试最核心的风险面。
我试过把这三条线拆成可复用的测试流程,关键是要有一个统一的调用入口,否则你在不同模型、不同 Key、不同 Base URL 之间来回切换,测试结果根本没法横向对比。下面就从统一 Key 配置开始,把整套流程搭起来。
2. TaoToken 统一 Key 配置:一个入口跑通多模型测试
做 AI 功能测试,最麻烦的不是写用例,而是环境管理。你要测 GPT 系列、Claude 系列、国产模型,每个平台一套账号、一个 Key、一个 Base URL,测试脚本里到处硬编码,换一个模型就要改一堆配置。更麻烦的是,不同平台的接口格式还有差异,OpenAI 兼容的和不兼容的混在一起,测试代码得写好几套适配层。
TaoToken 解决的就是这个问题。它提供统一的 API 入口,兼容 OpenAI 接口格式,你用一个 Key 就能调用多个主流模型。对测试工作来说,这意味着你的测试脚本只需要维护一份配置,切换模型只改一个 Model ID 字段,其他代码完全不用动。测试结果的可比性也上来了,因为调用链路一致,排除了不同平台网络延迟、接口封装带来的干扰变量。
获取 Key 的入口在 TaoToken 官网,注册后在控制台的 API Keys 页面创建。这里有个细节要注意:创建 Key 的时候建议按用途分开,比如"功能测试专用""一致性测试专用""幻觉检测专用",这样后面看调用量和排查问题时能快速定位是哪个测试环节出的状况。Key 创建后只显示一次,记得立刻复制保存到安全的地方。
拿到 Key 之后,你需要确认三件事:Base URL、API Key、Model ID。这三件套是后面所有配置的基础。Base URL 用https://taotoken.net/api,注意这个地址不带任何查询参数,是纯粹的接口根路径。API Key 就是你刚创建的那串字符。Model ID 则取决于你要测哪个模型,TaoToken 的文档里有完整的模型列表,测试时按需选择。
对于长期做 AI 功能测试的团队,建议直接上 Coding Plan,它适合需要持续调用、批量跑用例的场景,比按次计费更可控。如果只是偶尔验证一下模型输出,用模型对话页面手动测几条也行。但要做系统化的一致性测试和幻觉检测,还是得走 API,因为你需要脚本化地重复调用、记录结果、计算一致率。
配置管理上有个坑要提前说:不要把 Key 硬编码在测试脚本里。用环境变量或者独立的配置文件,测试脚本从环境读取。这样你的测试代码可以提交到版本库,Key 不会泄露,团队协作时每个人用自己的 Key 也不会冲突。下面给出具体的配置片段。
3. 可复制配置:环境变量、JSON 与测试脚本骨架
先把环境变量配好。Linux 或 macOS 下在~/.bashrc或~/.zshrc里加,Windows 下在系统环境变量里加:
export TAOTOKEN_API_KEY="sk-你的Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_MODEL="gpt-4o"如果你用 Python 写测试脚本,推荐用openai官方 SDK,因为 TaoToken 兼容 OpenAI 接口格式,直接改base_url就行:
import os from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.environ["TAOTOKEN_BASE_URL"], ) def ask(prompt: str, model: str = None) -> str: model = model or os.environ.get("TAOTOKEN_MODEL", "gpt-4o") resp = client.chat.completions.create( model=model, messages=[{"role": "user", "content": prompt}], temperature=0.3, ) return resp.choices[0].message.content如果你用 Node.js,配置方式类似:
import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.TAOTOKEN_API_KEY, baseURL: process.env.TAOTOKEN_BASE_URL, }); async function ask(prompt, model = process.env.TAOTOKEN_MODEL || "gpt-4o") { const resp = await client.chat.completions.create({ model, messages: [{ role: "user", content: prompt }], temperature: 0.3, }); return resp.choices[0].message.content; }如果你用 Cline 或 Claude Code 这类工具做测试辅助,配置方式是在工具的 settings 里填三件套。以 Cline 的 MCP 配置为例,在cline_mcp_settings.json里:
{ "mcpServers": { "taotoken-test": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-fetch"], "env": { "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "sk-你的Key", "TAOTOKEN_MODEL": "claude-sonnet-4-6" } } } }Codex 用户则在~/.codex/auth.json里配置:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的Key", "model": "gpt-5" }注意这里的三件套必须完整:Base URL 指向https://taotoken.net/api,API Key 用你创建的那串,Model ID 按测试目标填。少任何一个,请求都会失败。配置完成后,先别急着跑完整测试集,用一条最简单的请求验证连通性。
4. 验证请求:从连通性检查到一致性测试跑通
连通性验证用一条最小请求就够了。在 Python 里执行:
print(ask("请回复:连通性测试通过"))如果返回内容里包含"连通性测试通过"或者类似的确认信息,说明 Base URL、Key、Model ID 三件套都正确,网络链路也通。如果报错,先看错误类型,401 是 Key 问题,404 是 Base URL 或 Model ID 问题,超时是网络问题。具体排查在下一节展开。
连通性通过后,开始跑一致性测试。核心思路是同一个 Prompt 重复问 N 次,记录每次回答,然后对比核心事实是否稳定。下面是一个可复用的测试脚本骨架:
import json from collections import Counter def consistency_test(prompt: str, times: int = 5, model: str = None): answers = [] for i in range(times): ans = ask(prompt, model=model) answers.append(ans) print(f"第 {i+1} 次:{ans[:80]}...") # 简单统计:看关键词出现频率 keywords = ["分布式账本", "去中心化", "不可篡改"] hit_counts = {kw: sum(1 for a in answers if kw in a) for kw in keywords} print("关键词命中次数:", hit_counts) # 一致率 = 每个关键词都命中的次数 / 总次数 consistent = sum( 1 for a in answers if all(kw in a for kw in keywords) ) rate = consistent / times print(f"一致率:{rate:.0%}") return answers consistency_test("什么是区块链?请用三句话解释。", times=5)跑完之后你会看到类似这样的输出:五次回答里,如果每次都能提到"分布式账本""去中心化""不可篡改"这三个核心概念,一致率就是 100%。如果某次只提了"分布式账本"没提"去中心化",那次就不算一致。事实类问题的一致率建议 ≥ 95%,低于 90% 就要重点关注。
幻觉检测用"不存在验证法"最直接。构造一个不存在的人名、库名或事件,问模型相关信息:
hallucination_prompts = [ "请介绍张伟明教授在量子计算领域的主要贡献。", "Python 的 hyperboost 库怎么用?", "请引用《自然》杂志 2025 年 3 月关于室温超导的报道。", ] for p in hallucination_prompts: ans = ask(p) print(f"问题:{p}") print(f"回答:{ans[:120]}...") print("---")正确的行为是模型表示"不确定""没有找到相关信息""这个库不存在"。如果模型开始编造这个人的大学、职位、论文,或者详细描述这个不存在的库的用法,那就是幻觉。记录每次是否出现幻觉,幻觉率 = 出现幻觉的次数 / 总测试次数。低于 2% 算优秀,5% 到 10% 需要关注,超过 10% 是严重问题。
Prompt 输入测试则要覆盖等价类。把输入按语义特征分组:事实类、观点类、创意类、指令类、闲聊;按长度分:极短、一句话、一段话、超长;按语言分:纯中文、纯英文、中英混合。每个等价类取一个代表输入,跑一遍看输出是否符合预期。这样十几条用例就能覆盖主要输入空间。
5. 常见报错排查:401、local proxy failed 与 reading choices
测试过程中最容易撞上的几个报错,这里逐个拆解。
401 Unauthorized是最常见的。报错信息通常是Error code: 401 - {'error': {'message': 'Invalid API key'}}。原因有三个:Key 复制时带了空格或换行、Key 已经失效或被删除、环境变量没生效。排查步骤:先在终端echo $TAOTOKEN_API_KEY确认环境变量读到的值和你创建的一致;然后检查 Key 前后有没有多余字符;最后去控制台确认这个 Key 的状态是启用。如果都没问题,重新创建一个 Key 再试。
local proxy failed或Connection error这类报错,通常是网络链路问题。报错信息可能是APIConnectionError: Connection error或者local proxy failed to connect。先确认TAOTOKEN_BASE_URL是不是https://taotoken.net/api,注意不要多加/v1或者结尾斜杠。然后用curl直接测一下:
curl -X POST https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'如果 curl 能通但 Python 脚本不通,那是 SDK 配置问题;如果 curl 也不通,检查本机网络和 DNS。
reading choices 报错通常表现为KeyError: 'choices'或者TypeError: 'NoneType' object is not subscriptable。这说明返回的 JSON 结构里没有choices字段。原因可能是:Model ID 写错了,接口返回了错误信息而不是正常回答;或者请求体格式不对,比如messages字段拼写错误。排查方法:把原始返回打印出来看:
resp = client.chat.completions.create(...) print(resp.model_dump_json(indent=2))看返回里有没有error字段,有的话按错误信息处理。Model ID 建议从 TaoToken 文档的模型列表里直接复制,不要手打。
OAuth 相关报错一般出现在 Claude Code 或 Codex 这类工具里,报错信息可能是OAuth token expired或authentication failed。这类工具如果用 API Key 模式,需要在配置里明确指定api_key而不是走 OAuth 流程。Claude Code 的配置里把ANTHROPIC_BASE_URL指向https://taotoken.net/api,ANTHROPIC_API_KEY填你的 Key。Codex 则在auth.json里填base_url、api_key、model三件套。如果之前配过 OAuth,先把旧的凭证清掉再配。
超时或响应慢的报错,先区分是首字符延迟高还是整体耗时长。首字符延迟高通常是模型本身推理慢,换一个更轻量的 Model ID 测试对比。整体耗时长可能是输入太长,检查 Prompt 的 token 数有没有超过模型上下文窗口。测试脚本里加个超时设置:
client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.environ["TAOTOKEN_BASE_URL"], timeout=60.0, )排查完这些,你的测试环境基本就稳了。接下来就是按三条主线批量跑用例,记录结果,算一致率和幻觉率。
6. 把测试流程固化下来:从一次性验证到可复用资产
跑通一次测试不难,难的是让这套流程可复用。我的做法是把测试用例、评分标准、结果记录三样东西都结构化。
测试用例用 JSON 管理,每条包含编号、模块、输入、期望行为、评分维度:
{ "id": "CONSIST-01", "module": "一致性测试", "prompt": "什么是区块链?请用三句话解释。", "expected": "核心概念包含分布式账本、去中心化、不可篡改", "dimensions": ["准确性", "完整性", "一致性"], "repeat": 5 }评分标准统一成 1 到 5 分,准确性、完整性、相关性、安全性四个维度各打一分。多人协作时先用五道样题做校准,确保大家打分尺度一致。结果记录用表格,每条用例一行,记录输入、输出、各维度得分、是否幻觉、备注。
一致率和幻觉率这两个指标要持续跟踪。每次改 Prompt、换模型、更新知识库之后,都跑一遍回归测试集,对比修改前后的指标变化。如果一致率下降超过 5 个百分点,或者幻觉率上升超过 2 个百分点,就要回滚或者重新调优。
Prompt 版本管理也别忽略。每次修改系统 Prompt,都存一个版本文件,记录改了什么、为什么改、测试结果如何。这样出问题的时候能快速定位是哪个版本引入的,也能随时切回上一个稳定版本。
最后说个实操细节:测试脚本里的temperature参数建议统一设为 0.3 或者 0。温度越高输出越随机,一致性测试会很难做。如果你要测的是创意类功能,温度可以调高,但一致性测试和幻觉检测一定要用低温度,否则你分不清是模型本身不稳定还是温度参数导致的波动。
整套流程跑下来,你手里就有了一份可复用的 AI 功能测试资产:统一的调用入口、结构化的用例库、标准化的评分表、持续跟踪的指标。下次产品迭代,直接跑回归就行,不用从头搭环境。