ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI提效:用 skills 生成 Locust 压测脚本与数据准备实战

AI提效:用 skills 生成 Locust 压测脚本与数据准备实战 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_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_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/apiAPI 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/apiAPI Key 填控制台创建的 keyModel 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, headersheaders, jsondata, timeout30) def fire_success(name, response_time): events.request.fire( request_typelocust, namename, response_timeresponse_time, response_length0, exceptionNone, ) def fire_failure(name, response_time, exc): events.request.fire( request_typelocust, namename, response_timeresponse_time, response_length0, exceptionexc, ) 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(fHTTP {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验证单个创建成功再批量执行。整套流程跑顺之后一次完整的性能测试从数据准备到出报告基本能控制在半小时内。相比之前手动造数据、手写脚本的方式效率提升是实打实的。
返回列表