☰
AI提效:用 skills 生成 Locust 压测脚本与数据准备实战
2026/10/1 7:33:47 网站建设 项目流程

1. 性能测试场景里,为什么我劝你先搭一个 Locust skills

性能测试这件事,做过的人都懂:真正花时间的不是跑压测,而是压测之前那一堆数据准备。你要先建空间、建应用、建用户、把用户拉进空间、上传文档、发布应用,等这些前置条件都齐了,才轮到 Locust 上场。而每次客户需求还不一样,有的要 500 个空间 1 万个用户压查询接口,有的要压知识问答对话统计 TTFT 和吐字率,有的要 2 万个知识库加 10 万份 PDF。如果每次都靠人肉写脚本、手动造数据,一周都跑不完一轮。

我最近在做私有化项目的性能测试时,把这套流程沉淀成了一个 AI skills,核心思路是:让大模型不要每次自由发挥,而是按照固定的目录结构和参考手册来生成可运行的 Locust 压测脚本,同时把数据准备也脚本化。这样不管是查询类接口压测,还是对话类流式压测,都能在半小时内跑通一次完整流程。

这篇文章面向的是需要做性能测试、但又不想每次从零写脚本的测试和开发同学。我会把 skills 的目录结构、SKILL.md 的写法、Locust cookbook 的关键内容、数据准备脚本的调用方式,以及本地压测验证的完整动作都拆开讲。你跟着做,能拿到一套可复制的 Locust 脚本骨架和数据准备配置,直接在自己环境里跑起来。

核心检索词先明确:Locust 压测脚本生成、性能测试数据准备、AI skills 编写。这三个词贯穿全文,你如果是搜这几个方向进来的,下面的内容应该对得上。

先说清楚一个前提:Locust 本身是 Python 写的开源压测工具,用pip install locust就能装,它通过定义 User 类和 task 来描述压测行为,支持分布式和 headless 模式。我们要做的,是让 AI 按照一套规范去生成这些 User 类和配套的数据准备脚本,而不是每次让它凭空写。

为什么强调 skills 而不是直接让大模型写?因为直接对话生成脚本,每次风格、依赖、指标命名都不一样,跑出来的结果没法对比,出了问题也不好排查。skills 的价值在于把「历史验证过的最佳方案」固化下来,让大模型在生成时参考固定的 cookbook,输出稳定可控的脚本。

下面从目录结构开始,一步步拆。

2. TaoToken 前置准备:给 skills 接上稳定的模型能力

在讲 Locust 脚本之前,得先解决一个现实问题:skills 要调用大模型来生成脚本、分析报错、动态组装代码,这背后需要一个稳定的模型接入层。我这边用的是 TaoToken 来做模型接入,它提供统一的 API 入口,兼容常见的对话和代码生成场景,配置起来不复杂。

TaoToken 官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数,直接用它做 Base URL 就行。

为什么性能测试场景需要它?因为 skills 在执行过程中会有几类模型调用:一是根据自然语言需求生成 Locust 脚本骨架,二是读取 cookbook 后按规范补全签名、SSE 解析、指标上报这些细节,三是在脚本报错时分析错误原因并给出修复建议。这些调用如果走不稳定的通道,生成到一半断了,脚本就是半成品,反而更麻烦。

配置上,你需要准备三样东西:Base URL、API Key、Model ID。Base URL 填https://taotoken.net/api,API Key 在控制台的 API Keys 页面创建,Model ID 根据你用的模型填对应的标识。这三件套在后面的 Cline、Claude Code、Codex 这类工具里都会用到,先记下来。

如果你用的是 Claude Code 这类编码工具,接入时通常需要配置一个 settings 文件,把 Base URL 和 Key 写进去。具体路径和字段名各工具略有差异,但核心就是这三件套。我实测下来,把 Base URL 指向 TaoToken 的 API 入口后,skills 在生成 Locust 脚本时的稳定性明显好于直连,尤其是需要多轮对话补全 cookbook 细节的时候。

这里提醒一句:API Key 不要硬编码在脚本里,也不要提交到代码仓库。Locust 脚本里涉及环境的 SecretId、SecretKey 同样通过环境变量传入,这一点后面讲脚本结构时会再强调。

配好之后,你可以先用模型对话功能验证一下连通性,确认能正常返回再往下走。验证模型对话的入口在 https://taotoken.net/api-keys 旁边的对话页,或者直接进控制台看调用记录。确认没问题,我们再进入 skills 的目录设计。

3. skills 目录结构与可复制配置:SKILL.md、scripts、references 三件套

一个能稳定跑的 skills,目录结构是基础。我用的结构是这样的:

.codebuddy/skills/perf-test/ ├── assets/ # 测试数据文件 │ ├── apps.json # 应用数据 │ ├── perf_docs_list.jsonl # 文档列表(压测用) │ ├── shared_kbs.json # 共享知识库数据 │ ├── spaces.json # 空间数据 │ └── test_full.json # 完整测试数据 ├── references/ # 参考文档 │ ├── api-notes.md # API 接口说明 │ └── locust-cookbook.md # Locust 使用手册 ├── scripts/ # 脚本文件 │ ├── common/ # 公共工具模块 │ │ ├── __init__.py │ │ ├── asset_store.py # 资产存储管理 │ │ ├── batch_runner.py # 批量执行器 │ │ └── cli_utils.py # 命令行工具 │ ├── add_users_to_space.py # 添加用户到空间 │ ├── create_apps.py # 批量创建应用 │ ├── create_shared_kbs.py # 批量创建共享知识库 │ ├── create_spaces.py # 批量创建空间 │ ├── create_users.py # 批量创建用户 │ ├── gen_doc_variants.py # 生成文档变体 │ ├── locust_create_users_and_join_space.py │ ├── locust_describe_space_list_perf.py │ ├── locust_list_app_perf.py │ └── locust_list_shared_knowledge_perf.py └── SKILL.md # Skill 说明文档

三个目录各司其职。SKILL.md 是大脑,规定工作流程和入口判断;scripts 是手脚,把历史验证过的方案固化成脚本,保证重复执行稳定;references 是手册,当需要动态生成代码时,让大模型参考 cookbook 而不是自由发挥。

SKILL.md 的头部用 YAML front matter 声明名称和描述,描述里要写清楚触发时机,这样大模型在用户提到「性能测试」「压测」「压力测试」时能自动加载。下面是一个可复制的 SKILL.md 骨架:

--- name: perf-test description: This skill should be used when users mention performance testing, stress testing, load testing, or benchmarking (性能测试、压测、压力测试). It covers the full workflow including data preparation, assembling Locust scripts, and running performance tests. disable-model-invocation: false --- # 私有化性能测试 Skill ## 使用时机 当用户提到以下场景时加载本 skill: - 性能测试:用户说"做性能测试"、"压测" - 数据准备:批量创建空间/应用/用户/加入空间 - 组装压测脚本:用户说"组装一个性能测试脚本" ## 流程入口判断 ### 入口 A:用户说"我要做性能测试" 先询问是否需要数据准备,根据回答分流。 ### 入口 B:用户说"组装一个性能测试脚本" 直接进入流程 2。 ### 入口 C:用户说"做数据准备" 直接进入流程 1。

scripts 目录下的公共模块要统一资产读写和批量执行逻辑。asset_store.py负责 JSON 资产的读写,统一结构如下:

{ "run_id": "20260324_143501", "spaces": [], "users": [], "apps": [], "failed": [] }

batch_runner.py负责批量执行、重试和节流,cli_utils.py负责命令行参数解析。这三个模块是数据准备脚本的基础,所有 create_* 脚本都复用它们。

references 目录下的locust-cookbook.md是动态生成脚本的关键。它从项目里已有的标准压测脚本中提取知识,包含 TC3-HMAC-SHA256 签名、S3V4 签名加 MinIO 上传、SSE 流式解析、各业务接口调用 Demo、指标统计方法、Locust User 编写模式、文件驱动数据压测等章节。没有这份 cookbook,大模型每次生成的脚本风格都不一样,指标命名也乱,根本没法对比。

配置层面,环境变量是统一入口。Locust 脚本里所有连接信息通过os.getenv()读取,提供合理默认值。比如:

import os ADP_HOST = os.getenv("ADP_HOST", "https://your-private-host.com") ADP_SECRET_ID = os.getenv("ADP_SECRET_ID", "") ADP_SECRET_KEY = os.getenv("ADP_SECRET_KEY", "")

这样本地调试可以用默认值,生产环境通过环境变量覆盖,密钥不进代码仓库。数据准备脚本同样通过命令行参数传入账号、数量、输出路径,不硬编码。

如果你用 Cline 或 Claude Code 这类工具,接入 TaoToken 时需要在配置里写全三件套:Base URL 填https://taotoken.net/api,API Key 填控制台创建的 key,Model ID 填对应模型标识。Cline 的 MCP 配置里如果涉及模型调用,同样走这个 Base URL。Codex 的 auth.json 里也是这三样,路径按工具文档来。

目录和配置搭好,接下来就是让 skills 真正生成一个能跑的 Locust 脚本。

4. 生成 Locust 压测脚本并本地验证:从需求到 headless 跑通

这一步是整个流程的核心。用户说「组装一个性能测试脚本」,skills 会先收集需求,再参考 cookbook 生成独立脚本,最后询问是否执行。

需求收集阶段要问清楚几件事:压测场景是什么(标准模式全流程、纯对话、创建应用、文档上传、自定义)、目标环境的 Host 和密钥、并发用户数和运行时长、是否需要特殊指标。这些信息通过ask_followup_question工具收集,避免大模型瞎猜。

脚本生成阶段,核心原则是「完全独立」:一个文件包含所有依赖,不能 import 项目内其他模块,仅依赖pip install locust requests可安装的标准库。所有连接信息通过环境变量覆盖,TC3-HMAC-SHA256 签名和 S3V4 签名必须内嵌在脚本中。

一个可复制的 Locust 脚本骨架长这样:

""" 场景:查询应用列表压测 指标:ListApp 响应时间 依赖:pip install locust requests 运行:locust -f locust_list_app_perf.py --headless -u 10 -r 2 -t 5m 环境变量:ADP_HOST, ADP_SECRET_ID, ADP_SECRET_KEY """ import os import time import requests from locust import User, task, events ADP_HOST = os.getenv("ADP_HOST", "https://your-private-host.com") ADP_SECRET_ID = os.getenv("ADP_SECRET_ID", "") ADP_SECRET_KEY = os.getenv("ADP_SECRET_KEY", "") def get_tc3_headers(action, payload): """生成 TC3-HMAC-SHA256 签名头""" # 签名逻辑参考 cookbook 3.1 节 ... def post_yun_api(action, data): """调用云 API 封装""" headers = get_tc3_headers(action, data) url = f"{ADP_HOST}/cgi/capi" return requests.post(url, headers=headers, json=data, timeout=30) def fire_success(name, response_time): events.request.fire( request_type="locust", name=name, response_time=response_time, response_length=0, exception=None, ) def fire_failure(name, response_time, exc): events.request.fire( request_type="locust", name=name, response_time=response_time, response_length=0, exception=exc, ) class ListAppUser(User): @task def list_app(self): start = time.time() try: resp = post_yun_api("ListApp", {"PageSize": 15}) elapsed = (time.time() - start) * 1000 if resp.status_code == 200: fire_success("1_list_app", elapsed) else: fire_failure("1_list_app", elapsed, Exception(f"HTTP {resp.status_code}")) except Exception as e: elapsed = (time.time() - start) * 1000 fire_failure("1_list_app", elapsed, e)

这个骨架里,get_tc3_headers和post_yun_api是基础设施层,fire_success和fire_failure是 Locust 上报工具,ListAppUser是压测行为定义。指标命名用数字前缀表示步骤顺序,1_list_app对应第一步。

对话类压测要复杂一些,需要处理 SSE 流式解析,统计 TTFT(首 Token 延迟)和吐字率。cookbook 里给了process_response_sse()的实现,核心是逐行读取响应,记录第一个 token 到达的时间,再统计总 token 数除以耗时得到吐字率。

数据准备脚本的调用方式很直接。先建空间:

python3 .codebuddy/skills/perf-test/scripts/create_spaces.py \ --account Master_Default \ --count 5 \ --output .codebuddy/skills/perf-test/assets/spaces.json

再建用户:

python3 .codebuddy/skills/perf-test/scripts/create_users.py \ --account Master_Default \ --count 20 \ --user-prefix perf_u \ --password-encrypted <加密密码串> \ --output .codebuddy/skills/perf-test/assets/users.json

把用户加入空间:

python3 .codebuddy/skills/perf-test/scripts/add_users_to_space.py \ --account Master_Default \ --space-id <space_id> \ --users-file .codebuddy/skills/perf-test/assets/users.json \ --output .codebuddy/skills/perf-test/assets/membership.json

在空间建应用:

python3 .codebuddy/skills/perf-test/scripts/create_apps.py \ --account Master_Default \ --space-ids <space_id1,space_id2> \ --count-per-space 30 \ --app-prefix perf_app \ --output .codebuddy/skills/perf-test/assets/apps.json

数据准备好后,跑压测脚本。headless 模式适合 CI 和自动化:

locust -f .codebuddy/skills/perf-test/scripts/locust_list_app_perf.py \ --headless -u 10 -r 2 -t 5m

-u 10是 10 个并发用户,-r 2是每秒孵化 2 个,-t 5m是跑 5 分钟。跑完后 Locust 会输出汇总报告,包含请求数、失败数、平均响应时间、P95、P99 等。

验证成功的标志是:脚本能正常启动,没有 import 错误,请求能打到目标接口,指标能上报到 Locust 统计里。如果接口返回 200 但指标没数据,检查fire_success是否被调用;如果启动就报错,多半是依赖没装或环境变量没设。

我试过在本地用默认环境变量跑,先确认脚本能起来,再切到真实环境。这样排错范围小,不会一上来就被网络问题干扰。

脚本跑通后,如果用户需要长期做性能测试,可以考虑用 Coding Plan 来管理多轮脚本生成和优化,入口在 https://taotoken.net/coding-plan 。如果是单次验证模型生成效果,用模型对话就够了。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

压测脚本和数据准备脚本跑起来后,最容易撞上的几类报错,我按实际遇到的整理一下。

401 Unauthorized。这个最常见,通常是 SecretId 或 SecretKey 没传对,或者签名时间戳过期。检查环境变量ADP_SECRET_ID和ADP_SECRET_KEY是否设置,签名里的X-TC-Timestamp是否是当前时间。如果用的是 TaoToken 的 API Key,确认 Key 没有过期,Base URL 填的是https://taotoken.net/api而不是带 UTM 的地址。

local proxy failed。这个报错一般出现在请求发不出去的时候,可能是 Host 地址写错,或者本地网络策略拦截。先确认ADP_HOST是可达的,用 curl 直接打一下接口看通不通。如果是模型调用侧报这个,检查 Base URL 配置,确认没有多余的路径后缀。

reading choices 相关报错。这类错误通常出现在解析模型返回时,返回结构里没有choices字段,可能是模型调用失败返回了错误信息,或者响应格式和预期不一致。排查方法是把原始响应打出来看,确认返回的是正常对话结构还是错误对象。如果是 skills 在生成脚本时调用模型报这个,检查 Model ID 是否填对。

OAuth 相关报错。如果工具走 OAuth 流程接入,报错多半是 token 过期或 scope 不对。重新走一遍授权流程,确认回调地址和配置一致。用 API Key 方式接入的话一般不会碰到这个,所以如果频繁遇到 OAuth 问题,可以考虑换成 Key 方式。

除了这几类,还有几个脚本层面的坑。一是 import 错误,Locust 脚本必须独立,不能 import 项目内模块,如果报ModuleNotFoundError,检查是不是引用了外部文件。二是指标不上报,检查events.request.fire的参数是否完整,name和response_time必填。三是数据准备脚本写文件失败,检查输出路径的目录是否存在,asset_store.py不会自动建目录。

排查顺序建议:先看报错原文,定位是网络层、鉴权层还是脚本层;网络层用 curl 验证连通性;鉴权层检查密钥和时间戳;脚本层看 import 和指标上报。这样一层层缩小范围,比盲目改代码快得多。

如果报错涉及模型调用,可以对照 TaoToken 的接入文档确认配置,文档入口在 https://taotoken.net/doc 。API Key 管理在 https://taotoken.net/api-keys ,控制台在 https://taotoken.net/console 。Claude Code 接入相关的问题,参考 https://taotoken.net/ClaudeCodeAnthropic 。

6. 把 skills 用起来:从一次压测到可复用的性能测试流程

走到这里,你应该已经能跑通一次完整的压测流程了:数据准备脚本建好空间、用户、应用,Locust 脚本在 headless 模式下跑出报告,指标正常上报。但 skills 的价值不止于跑一次,而在于把这次的经验固化下来,下次换个场景还能快速复用。

我的做法是,每次压测完把新的场景脚本和 cookbook 补充进去。比如这次压了知识问答对话,统计了 TTFT 和吐字率,就把 SSE 解析和指标计算的代码片段补进locust-cookbook.md。下次客户要压类似的对话场景,skills 直接参考 cookbook 生成,不用重新摸索。

数据准备脚本也是同理。第一次写create_spaces.py可能只支持指定账号和数量,后来发现需要支持从资产 JSON 读取已有空间 ID,就加上--from-file参数。这些改进都沉淀在 scripts 目录里,下次直接调用。

如果你要长期做性能测试,建议把 skills 纳入版本管理,SKILL.md、scripts、references 都提交到仓库。这样团队里其他人也能用同一套规范,压测结果可对比,问题可追溯。模型调用侧用 Coding Plan 管理多轮生成和优化,比每次手动对话效率高。

最后给一个实用技巧:跑压测前先用小并发验证脚本正确性,比如-u 1 -r 1 -t 30s,确认请求能通、指标能上报,再放大到目标并发。这样能避免一上来就压出问题,排查起来也简单。数据准备脚本同理,先用--count 1验证单个创建成功,再批量执行。

整套流程跑顺之后,一次完整的性能测试从数据准备到出报告,基本能控制在半小时内。相比之前手动造数据、手写脚本的方式,效率提升是实打实的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询