关于 cekura-infra-test-suite
cekura-infra-test-suite 是为语音 Agent 仓库构建 Cekura CI/CD 测试套件的技能,适用于将 Agent 代码纳入持续集成的团队。它生成供 CI 提交的 JSON 规格,并限制操作范围,不会直接运行测试或拨打真实电话。
主要功能
- 01检查仓库中的 Agent 调用路径
- 02生成 Tests-as-Code JSON 规格
- 03配置 Cekura CI 工作流
- 04验证测试规格而不创建记录
- 05限制文件修改并保留现有变更
适用场景
- 01为语音 Agent 仓库添加 CI 测试套件
- 02更新已有的 Cekura 测试规格
- 03在提交前验证套件定义
MCP 相关
通过 Cekura MCP 读取 Agent、启用的指标、个性配置和规格架构;仅使用规格验证写入类请求,不创建场景或运行测试。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cekura-ai/ cekura-skills --skill cekura-infra-test-suite安装后在 Claude Code 中输入/cekura-infra-test-suite确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/cekura.tests.jsonreferences/case-catalog.mdci-wiring.mddiscovery.mdpreview-deploy.mdscripts/lint_suite.pyrun_suite.py详细介绍
Cekura 语音 AI 基础设施 CI/CD 套件
采取任何操作前,请调用 mcp__cekura__cekura_skill_started,并设置 skill_name="cekura-infra-test-suite"、verification_tag="ack:cekura-infra-test-suite:2h6r7k" 和 plugin_version="0.19"。该工具会立即返回,让 Cekura 了解正在使用哪些技能;如果无法使用该工具,请继续操作。
在语音 Agent 仓库中构建一套精简且便于审查的 Cekura 测试套件。交付物是一个 JSON 规范,由 CI 提交到 Cekura 的 Tests-as-Code 端点。它不是一组持久化的仪表板评估器。
当仓库、部署目标和 Cekura Agent 都在范围内时,使用此技能。对于一次性仪表板评估器或自适应质量场景,请改用 cekura-eval-design。
运行方式——两种上下文,同一套流程
以下步骤在两种上下文中完全相同;不同之处在于代码的来源、已有的信息以及结果的去向。请自行判断,不要询问:仓库已经是当前工作目录 → 终端。必须通过 mcp__github__github_checkout_repo 获取代码 → 从 Cekura 仪表板启动。
| 终端 | 仪表板 | |
|---|---|---|
| 仓库 | 已经是当前工作目录 | 通过 github_checkout_repo 获取 |
| Agent | 从配置中推断,或询问 | 在启动消息中指定 |
| 凭据 | 可能确实缺失——此时应当询问 | MCP 会话已完成身份验证;绝不要询问 |
| 结果 | 工作树,供用户提交 | 通过 github_open_pull_request 创建一个拉取请求 |
交互约定
每次运行只问一个问题,并在首次回复中提出,就是下面这个问题:
这将仅通过手动触发运行——从 Actions 选项卡中针对某个分支启动,并拨打真实电话;也可以勾选
dry run框进行验证。是否还要添加其他触发器:推送、PR、定时计划,或者cekura-test标签(将每个带标签的 PR 部署为独立预览环境,并针对该环境运行套件)?
仅当 references/preview-deploy.md 指出机器人符合条件时,才提供标签选项。若启动消息已指定触发器,就表示这个问题已得到回答——不要再问。否则,在告知用户你发现的情况时提出该问题,然后继续工作。不要等待答复——如果到步骤 6 时仍未收到答复,就配置为手动触发,并在交接说明中告知如何添加触发器。除终端中的凭据缺失情况(步骤 7)外,不要提出任何其他问题——不要询问要创建哪些文件、将文件放在哪里,或是否继续;在仪表板中,绝不要询问凭据。
API 访问——Cekura MCP 服务
在发现目标之前,先对 MCP 服务进行身份验证,并优先使用 MCP 读取数据。Tests-as-Code 验证使用下方的公共 HTTPS 端点;从环境变量或 CI 密钥中获取其基础 URL 和密钥,绝不要从源代码管理中获取。如果端点不存在,请报告这一情况,不要改用仪表板评估器。
安全性与范围
- 在提出覆盖方案前,先检查代码仓库。不要仅凭框架名称推断服务提供商、传输方式、工具或流水线行为。
- 将 Cekura 视为只读。你可以
GETAgent、已启用的指标、个性设定、测试配置文件、架构和导出数据。唯一允许的类写入请求是scenarios_validate_json——验证操作,不会创建任何内容,也不会拨号。绝不能调用scenarios_run_json:它会消耗额度。 - 绝不要创建、编辑、删除、复制或导出后重新导入场景、测试配置文件、个性设定、指标、Agent 或文件夹。除非用户另行要求,并在审阅规格后接受费用,否则绝不要在线运行测试套件。
- 绝不要在规格或已提交的工作流中放入 API 密钥、电话号码、生产客户数据或部署密钥。使用 CI 密钥和不敏感且兼容暂存环境的配置文件数据。
- 保留现有且无关的代码仓库改动。编辑范围仅限下方 交付内容 中确定的文件列表。扩展现有的 Cekura 工作流,而不是新增第二个工作流。
- 如果目标、已启用的指标、个性设定或暂存环境测试数据未知,请将该用例标记为受阻,而不是改用较弱的检查。
- 如果覆盖某项行为需要改动该范围以外的内容——运行时代码、Dockerfile、部署配置、Cekura 记录或不存在的指标——请停止并报告阻碍。 不要为了让自己的测试能够运行而做出改动,无论差异多小、理由多充分。说明哪些内容无法测试、需要做什么,并由用户决定。有两项不算范围变更:专门用于监管此测试套件的防护措施(例如用例数量检查,添加用例时同步更新);以及
references/preview-deploy.md中的预览步骤。
两种不同的内容都被称为“基础设施测试”
在步骤 0 之前先确认这一点——理解错了会多做一轮调研:
| 请求 | 内容 | 操作 |
|---|---|---|
| “添加 Cekura 的预定义基础设施套件” | Cekura 提供的 18 个以上现成延迟/中断/噪声/丢包/保持场景 | MCP 工具无法访问。 引导用户前往 Evaluators → Infrastructure Suite → Add to my Project(或使用 add_infrastructure_suite API);并说明它还会添加一条 AI Interrupting user = 0 评分规则,并给副本添加 infrastructure-suite 标签,以便 CI 选择。不要手动构建副本,也不要执行以下步骤。 |
| “为我的机器人构建基础设施/CI 测试” | 根据客户自己的流水线代码派生的测试 | 执行以下步骤。 |
如果请求可能指其中任意一种,请在步骤 0 之前只问一次——用一个简短问题确认。这种情况只会出现在终端中:通过仪表盘启动时会指定代码仓库和 Agent,因此无需确认。
交付物——三个文件,在动笔前确定
基线,以及几乎所有代码库都会采用的方案:
cekura.tests.json the suite
.github/workflows/cekura-tests.yml the CI gate (created, or the existing Cekura job extended)
README.md a section: what runs, which secrets, which permissions
先确定准确的文件列表,再开始写任何内容,并在首次回复中列出。 三个文件是基线,不是上限;重要的是预先敲定列表,因为写到一半才发现还需要第四个文件,就会让一次迭代变成四轮来回沟通。只有在代码库自身的惯例要求时,才添加或替换,并说明原因:
- CI 不是 GitHub Actions →
.gitlab-ci.yml、Jenkinsfile 阶段或 Makefile 目标。替换,不是添加。 - 文档不放在 README 中 → 将章节放在该代码库存放文档的位置。
- 两个可独立部署的机器人 → 如果一个规范无法覆盖两者,就编写两个规范。
绝不能作为附加项:覆盖率说明(应放在 README 章节和 PR 正文中)、随代码库引入的 lint_suite.py 或 run_suite.py,或此技能臆造的配置文件。每增加一个文件,客户就多一项需要永久维护的内容——如果说不出是哪条惯例要求它存在,那它就不该存在。在试运行前一次性写出完整列表;代码检查器从此技能自身的目录运行,工作流则通过 Cekura 发布的 run-suite 操作运行测试套件。
如果目标是提交拉取请求,提出方案前先列明所需的 GitHub App 权限:Contents 和 Pull requests 需要读写权限;此外,负载会写入 .github/workflows/,因此还需要 Workflows 读写权限。仅在 App 上授予最后这项权限还不够——组织管理员必须在安装中接受此项变更。
工作流
0. 判断这是新建还是更新
先运行此步骤;后续所有步骤都由此决定。
grep -rl 'schemas/test-suite' --include='*.json' . # definitive: a spec's $schema line
git ls-files | grep -Ei '(cekura|tests?).*\.json$' # candidates
git ls-files '.github/workflows/*' '.gitlab-ci.yml' 'Jenkinsfile' | xargs grep -ln 'cekura' 2>/dev/null
- 不存在规范 → 新建。按顺序完成步骤 1–8。
- 规范已存在 → 原地更新;对于规模相当于一个拉取请求的更新,
cekura-bot-test-writer才是适用的技能。完整阅读该技能,保留每个key,从步骤 5 开始,绝不要重新生成:现有测试套件是经过审核的源代码,只有在其key保持不变时,结果才具有可比性;而更新时最常见的正确结果就是不做任何更改。 从步骤 5 开始并不意味着跳过其他步骤。 你编写的任何内容仍须通过步骤 1b、步骤 4 的预期结果约定以及步骤 7 的试运行。更新只是更小的改动,不是降低标准——如果测试用例遵循旧文件的编写风格,而不是评判器的约定,那它反而更糟。此处不需要修复未触及用例中原本就存在的代码检查警告。 - 已有工作流调用 Cekura → 在步骤 6 中扩展该文件,而不是新增第二个文件;沿用其密钥名称和触发约定。
1. 阅读实际的 Agent 调用路径
从运行时入口开始,追踪调用路径,而不是只搜索提供方名称。结合源码引用,梳理以下内容:
- 入站/出站方向和传输方式(电话、WebSocket、WebRTC、SIP、LiveKit、Pipecat 等);
- STT、LLM、TTS、VAD/轮次检测、缓冲、端点检测和打断处理器;
- 提示词/配置加载和每个会话的变量;
- 工具、转接/结束通话行为、DTMF/IVR、语音信箱、空闲/超时、重试和错误处理;
- 支持的语言,以及切换语言/提供方的代码路径;以及
- 测试夹具、模拟对象、预发布环境依赖项,以及现有的 Cekura JSON 或工作流文件。
references/discovery.md 提供问题集——说明每一层需要查找什么,以及每个答案能支持哪项断言。它的规则是:记录每个阈值和每句引用的 Agent 原话,并附上 file:line。有来源支撑的数字,能把“空闲计时器最终会触发”具体化为“8s 时触发,并说 你还在吗?”;没有来源支撑的数字只是猜测,不仅无法通过测试套件,也无法证明机器人的行为。
对于每个候选行为,都要记录其参与方和传输方式。模拟来电方和被测 Agent 可能执行不同的代码。只覆盖其中一方的测试,不能证明另一方的回归也已覆盖。
1b. 选择指标或个性前,先读取 Agent 记录
发现工作分为两部分。代码仓库说明 Agent 的功能;**Cekura 则说明套件可以依据什么进行断言。**如果有密钥或已认证的会话,请在编写前读取以下内容。这些都是读取操作,而且每一项都能让猜测变成事实:
- **目标 Agent 启用的指标。**规范只能引用该 Agent 已存在且已启用的指标,因此这份列表限定了套件可测量的范围。将数值类指标——延迟、中断——与
expected_outcome一并关联。它们能测量逐字稿审查型判定器无法测量的内容;对于基础设施套件来说,这正是大部分价值所在。 - **可用的个性。**通过 ID 固定一个个性,以便跨提交比较结果;并确认它是否包含内联个性无法设置的选项(网络模拟、讲话计划、消息计划)——这决定了应按 ID 引用,还是使用内联个性。
- Agent 本身——提供商、通道、呼入或呼出、联系人号码、最长时长。在接入 CI 之前,这能确认 CI 作业应使用的通道,避免运行因 Agent 从未配置过该通道而被拒绝。
- 当前的规范架构,其优先级高于本技能中的任何示例。
**如果 Agent 与代码仓库不一致,编写任何内容前都要说明。**如果代码仓库构建的是一个 Pipecat 药房热线,但 Agent 却是另一家提供商上一个单纯的“乐于助人的助手”,那么每个值得编写的用例都会失败——而首次运行时满屏报错,看起来像是套件坏了,而不是 Agent ID 错了。在首次回复中指出不匹配,并在交接时将其放在首位,同时在拉取请求正文顶部说明。仍然要依据代码仓库编写套件:代码仓库才是正确依据;修正 Agent ID 后,套件自然就会生效。
没有凭据时,请明确说明:只使用 expected_outcome,不固定任何个性,并将套件标记为未经验证。绝不要为了填补空缺而臆造指标 slug 或个性 ID——未启用的 slug 会在试运行时被直接拒绝;在那里发现问题正合适,但猜错只会白白浪费一轮往返。
2. 编辑前先制作覆盖矩阵
编辑前先制作覆盖表。这不是一个文件——它要放进 README 章节和拉取请求正文中,让审阅者无需在代码仓库中翻找一份会逐渐过时的文档,也能看到推理过程:
| 代码路径 / 来源证据 | 要验证的行为 | 坐席 + 传输方式 | 可从逐字稿观察到的断言 | 用例键 | 状态 |
|---|
只纳入套件能够执行并判定的行为。例如,断言预期的口头回复会在中断后出现;不要断言音量标签、环境音或内部处理器本身已运行。若某一行需要不同的传输方式、测试夹具、指标或后端能力,则标记为 uncovered,并说明缺少什么。
references/case-catalog.md 列出了 9 种经过验证的用例模式,每种都说明了序列级断言与阈值级断言的区别,以及会让测试失去意义的删除条件。从这里开始,再根据该代码仓库自身的缺陷历史补充用例。若某个用例触发了删除条件,就不要移植它——覆盖真实流水线的 6 个用例,胜过包含 6 个无效测试的 12 个用例。
除非用户要求分档,否则优先制作一个包含 10–12 个用例、可用于部署的套件。如果还需要快速 PR 套件,就保持精简(通常为 4–6 个用例),并确保它是完整套件的子集。将兼容的轮次合并为一个用例;只有在涉及不同的子系统、坐席、传输方式、提供商或终端调用生命周期时,才新增用例。
3. 选择规范形状
以目标环境返回的实时架构为准。v1 规范通常如下:
{
"$schema": "https://docs.cekura.ai/schemas/test-suite/v1.json",
"version": "1",
"suite": { "name": "…", "description": "…" },
"defaults": { "frequency": 1, "language": "en", "max_duration": 180 },
"scenarios": []
}
保持 key 值稳定且具有描述性。只有在每个用例确实共享可复用默认值时,才将其放在套件级别;任何 defaults 字段都可以在单个用例上覆盖。在每个条件操作用例中显式设置 language。tools 指定模拟调用方具备的能力:
dtmf、receive_dtmf、end_call、end_call_only_on_transfer、send_sms、call_hold。
仅在用例需要时提供测试数据:
"test_profile": {
"name": "returning-caller-gold-tier",
"agent_variables": { "order_id": "ORD-4471" },
"caller_variables": { "user_name": "Maria" }
}
agent_variables 会在通话时作为动态变量传递给受测 Agent,因此只有当 Agent 已读取同名变量时,某个键才会生效。发现过程会告知你有哪些变量;凭空编造键只会生成一份 Agent 悄然忽略的配置。caller_variables 根本不会传递给 Agent,它们是模拟调用方的上下文,也是脚本步骤中 {{test_profile.key}} 替换的来源。
不要在两个部分之间移动字段,也不要为了让 JSON 看起来自成一体而凭空创建配置。
**一个例外,但并非常见情况:**如果某个机器人在自己的源代码中启用了明确的测试框架模式,并通过传入的变量获取提示词、提供方和限制,从而按通话自行配置,那么它会通过 agent_variables 接收完整配置。如果仓库中有这种模式,请原样保留该配置块。若没有,agent_variables 就只是动态变量,仅此而已。
内联个性配置有意受到限制。如果所需的已保存个性配置使用网络模拟、说话计划、消息计划、生成配置、背景音量或打断级别,请保留按 ID 引用的个性配置,并说明此依赖。不要为了让内联对象通过验证而删除这些设置。
4. 编写确定且可观测的用例
使用 type: "conditional_actions" 覆盖确定性基础设施和回归测试。脚本格式为 {role, first_message, conditions: [{when, say, then}]}:如果由 Agent 先发言,first_message 为 "";then 列出调用方后续轮次的跟进步骤。双方的每一步都必须是原文——绝不能使用 <ai_generated>;CI 门禁中不得包含由大模型生成的调用方回复。较旧的基于 id 的格式(id、condition、action 等)仍可通过验证,但已弃用。
编写时请使用公开的 cekura-eval-design 技能及其 conditional-actions 参考:
<interruption time="Xs" />必须作为then步骤的开头。 在问候语或引入语之后使用正数时间;仅当语音已在进行时才使用0s。<ivr text="…" />和<voicemail text="…" />必须是自闭合标签,并独占整个步骤——不接受块形式<voicemail>…</voicemail>。后续发言应放入then步骤。<silence>可以被打断;<hold>则不能。测试代码路径实际选择的行为。<speed ratio="N" />(0.1–2.0)和<volume ratio="N" />(0–2.0)必须是自闭合标签,并从标签出现处开始生效,直到遇到下一个同类标签。也可以添加text="...",将作用范围限定为指定词语。使用它们来覆盖某条路径;绝不要将不可听见的属性作为断言。<network_simulation … />接受packet_loss(0–100)、jitter和latency(毫秒),并且必须是自闭合标签。它会降低音频质量——但其本身不能证明任何内容。- 不要引用已存储的音频片段。录音通过 id 引用场景的
condition_audio映射,而规范会实例化没有此类映射的临时场景,因此已提交套件中的<audio>id 无法解析到任何内容。(仪表板评估器支持通过名称引用录音;详情请参阅cekura-eval-design。只有规范路径不支持。)
验证前先运行 lint。 scripts/lint_suite.py 会离线免费检查上述所有内容,以及规范结构、重复键和内联个性限制:
python3 <skill>/scripts/lint_suite.py cekura.tests.json --strict
它与服务器自身的标签验证器一致,因此 lint 通过就意味着 dry run 失败的原因只可能是本地检查确实无法发现的问题——例如未启用的指标,或缺少相应渠道的 Agent。
预期结果就是评判者的提示词——将其写入指定格式
expected_outcome 不是给读者看的备注。LLM 评判者会读取调用记录,并将其中的每条陈述单独评为 yes、no 或 blocked。用叙述性文字撰写的评估标准,得分会低于将相同标准写入指定格式的情况,因此首次撰写前,请先阅读
cekura-eval-design/references/expected-outcomes.md。 以下是 CI 套件最常违反的规则:
- 每条陈述都以 “The main agent should” 开头,每行一条。 不要写成编号文章,也不要写成一段文字。每个案例写 2–6 条原子化陈述;不要为了凑数而添加内容。
- “main agent” 和 “testing agent” 是唯一允许使用的说话者标签。 不要使用 “the agent”、“the bot”、“the caller”、“the user” 或 “the assistant”——评判者读取的是带有说话者标签的对话记录,在评估标准中更改这些标签会降低每次运行的准确性。
- 不要写测试设置的理由。 为什么要这样构建案例、标签的作用、阈值是多少——这些都不属于这里。应告诉评判者要关注什么,而不是为什么要关注。
- 不要使用主观描述词,例如 “promptly”、“briefly”、“warmly”、“clearly”、“appropriately”。将每个词替换为 main agent 可观察到的言语或行为。
- 不要评估告别语,也不要评估是谁结束了通话,除非终止通话就是该案例明确声明的测试目标。始终需要评估的是 main agent 是否继续互动:当 testing agent 表示已完成(“that's everything I needed”)后又提出一个问题时,如果 Agent 已经停止互动,就无法通过有效检查。评估回答,不要评估告别。
- 每条陈述都必须由脚本中的某个轮次触发。 如果脚本从未产生某条陈述的触发条件,那么每次运行都会得到
blocked——这是无用的负担,不是严格的测试。如果轮次列表确实允许两种可接受的行为,就写成一条二选一陈述,而不是只要求其中一种。
始终保持范围明确且可通过对话记录验证:口头内容、是否泄露字面的标签文本、轮次顺序。不要为了让真正的失败显示为通过而弱化断言。
scripts/lint_suite.py 会以警告形式标记其中可机械检测的部分——标签泄露、缺少 “The main agent should”、主观描述词、结束通话评估。请使用 --strict 运行。
指标
只有在检查目标 Agent 后,才能根据已启用指标的 slug 或 ID 选择指标。缺失或未启用的指标属于需要修复的验证错误,不是从案例中移除该指标的理由。
expected_outcome 必须附加 Expected Outcome 指标,才能进行评分。对于基础设施套件,请读取 Agent 已启用的指标,并一并附加数值型指标——延迟和打断指标可以测量 LLM 评判者读取对话记录时无法测量的内容。
5. 安全地审查更改
更新时,应根据 PR 的合并基点确定更改,而不只是比较上次提交:
git fetch origin main
BASE_REF="${PR_BASE_REF:-origin/main}"
MERGE_BASE="$(git merge-base "$BASE_REF" HEAD)"
git diff --name-status "$MERGE_BASE" HEAD
git diff "$MERGE_BASE" HEAD -- <runtime paths> <existing suite paths>
开始编辑前,请为每个更改过的运行时符号填写覆盖矩阵中的对应行。如果没有可观察到的行为变化,那么结论可以是 No suite change。不要修改无关案例、放宽预期结果,也不要仅仅因为附近文件发生更改就添加通用提供商测试。
6. 一次性写入文件
现在所有事项都已确定,包括文件列表。请一次性写入所有文件,然后再进行验证——不要先写一个文件、接着提问、再写另一个文件。这一步就是为了避免这种反复循环。
工作流
经过验证的规范还不足以充当门禁。运行是异步的:POST 请求一入队就会立即返回,因此如果作业在 curl 处结束,那么在单次调用接受评估之前,它就会报告成功——这样的门禁无法失败,比没有门禁更糟,因为它看起来像是覆盖了测试。因此,工作流会通过已发布的 run-suite action 运行测试套件,该 action 会轮询直到运行进入终态,并在未全部通过时失败。请从 references/ci-wiring.md 复制模板(标签预览则使用 references/preview-deploy.md),不要凭记忆编写 YAML。
有两点是确定的,不容与用户商议:
- 使用
workflow_dispatch,并设置一个默认未勾选的dry_run复选框。 手动触发是有意执行调用的行为;设置这个复选框,是为了在不想执行时使用。 - 除手动运行外,其他所有触发器都只做验证,除非用户明确要求该触发器执行实际调用——选择标签预览就表示提出了这一要求。实际调用会消耗额度;推送代码时悄悄产生费用,不应成为任何人默认同意的行为。
默认只使用 workflow_dispatch,不添加其他触发器——从 Actions 选项卡启动,并使用用户选择的分支。你已在首次回复中询问触发方式;如果用户给出了答复,就将其加入模板的 on: 区块;否则只配置手动触发,并在交接说明中注明如何添加其他触发器。不要让运行一直等待答复。
如果仓库中已有调用 Cekura 的工作流,就扩展该工作流——绝不要再添加第二个。
README 部分
将 references/ci-wiring.md 中的模板附加到文档中并填写完整——说明测试套件能验证什么、如何触发、它读取的每个密钥和变量,以及第 2 步的覆盖率表(包括未覆盖的行)。
7. 先检查,再验证——验证不是可选项
只有当套件返回 valid: true 时,才算完成。 如果没有通过验证,就明确说明,不要交付一个看起来完整的文件。lint_suite.py 无法检查的内容都要在这里确认:每个指标 slug 是否存在且已为此 Agent 启用、人格是否可用、Agent 是否支持 CI 将使用的渠道,以及服务端的验证器是否接受每个标签。任何一项不通过的规格都不是较弱的套件——而是完全无法运行。
因此,顺序是:检查,然后验证,然后修复,再次验证,直到返回有效。
使用 MCP 工具 scenarios_validate_json 进行验证。 它接收 {agent_id, spec, channel},返回 {valid, plan},不会创建任何内容,也不需要密钥或 shell——沙盒没有终端不是交付未经验证内容的理由。绝不要使用 scenarios_run_json:它在 dry_run=true 时能回答同样的问题,但也会消耗额度并拨打电话,因此在无法使用破坏性工具的情况下,不提供该工具。
在终端中,如果会话没有凭证,请索取凭证——API 密钥和 Agent ID,或经过身份验证的 MCP 会话;不要悄悄跳过验证直接交付。在仪表板中,会话已通过身份验证,因此缺少密钥属于需要报告的错误,而不是要询问的问题。只有在用户无法提供凭证时,才可交付未经验证的内容——必须在交付说明和覆盖范围备注中都标明这一点,并附上下方的确切命令,同时说明手动运行工作流并勾选 dry run 也会执行同样的检查,因此首次检查可以发现本会话无法检查的问题。
验证会检查语法、指标、人格、配置文件、目标兼容性、计划运行情况和预估成本,不会创建对象或拨打电话:
python3 <skill>/scripts/lint_suite.py cekura.tests.json --strict # free, offline, first
CEKURA_API_KEY=… python3 <skill>/scripts/run_suite.py --dry-run --agent-id 123 --channel pipecat_v2
这两个工具都要从此技能所在目录运行——它们是创作工具,不是仓库需要保留的文件。
通过原始 HTTP 发送请求时,将相同的请求体 POST 到 $CEKURA_BASE_URL/test_framework/v1/scenarios/validate_scenarios_json/,并添加 X-CEKURA-API-KEY 标头。
验证工作流发送的每个请求,并为每个请求指定 channel——预览请求还要添加占位符覆盖(references/preview-deploy.md 中列出了可用项)。必须要求 valid: true,并仔细查看返回的计划,而不只是扫一眼标志:每个用例都必须列出预期的指标,且任何指定了内联 test_profile 的用例都必须报告 mode: "inline"。如果用例报告 existing,说明内联区块没有生效。
错误会按文件中的位置返回,例如 scenarios[2].metrics[0],并一次性全部列出,因此一次往返就能告诉你所有需要修复的内容。修复错误;绝不要删除指标或放宽用例来绕过错误。未启用的指标属于工作区的配置问题,不是套件缺陷。只有在验证响应不含凭证或敏感的调用方数据时,才保存该响应;如果验证似乎需要执行验证之外的写入操作,请停止并报告阻碍。
8. 交付
只有在验证返回 valid: true 后才能交付;如果无法获取凭据,则按步骤 7 的说明将测试套件标记为未验证。
仪表板 — 使用一次 github_open_pull_request 调用提交所有文件;绝不逐个提交,也绝不为未经验证的测试套件提交。正文应补充仓库中没有的信息:覆盖表、未覆盖的行及原因、试运行计划(用例、计划运行次数、估算成本)、工作流读取的每个密钥、变量、密钥集和标签及其创建位置;如果步骤 1b 发现 Agent 与仓库内容矛盾,则先说明这一不一致。
如果写入被拒绝——403 Resource not accessible by integration,或 422 … The permissions requested are not granted to this installation——原因是上文 交付物 中提到的 Workflows 权限,而不是仓库访问权限;检出操作已证明仓库访问正常。请明确说明这一点,不要暗示连接已损坏。
终端 — 将文件留在工作树中,然后停止。除非用户提出要求,否则不要提交、创建分支或推送;请提供提交说明,并在用户想创建 PR 时提供 gh pr create。报告 PR 正文原本会包含的内容。
交接
确保仓库中包含:
cekura.tests.json,格式正确并已纳入版本控制;.github/workflows/cekura-tests.yml——新建,或扩展现有的 Cekura 工作流;包含dry_run复选框,并且仅使用手动触发,除非用户要求更多触发方式;- 步骤 6 中的 README 章节;以及
- 验证结果——
valid: true及其计划;或者明确标记为未验证的测试套件,并注明用于验证它的命令。
报告用例数量、渠道/席位覆盖情况、依赖项、任何需要实际运行的事项;如果用户没有回答触发方式的问题,还要说明你配置了哪种触发方式,以及如何添加其他触发方式。试运行只能证明规范有效,不能证明部署可用。
随附资源
在相应步骤要求时阅读:
references/discovery.md— 技术栈问题,以及每个答案可支持哪些断言references/case-catalog.md— 九种经过验证的用例模式及其舍弃条件references/ci-wiring.md— 工作流和 README 模板、运行目标、触发方式references/preview-deploy.md—cekura-test标签预览,以及符合条件的机器人examples/cekura.tests.json— 包含三个用例的测试套件,可通过--strict检查
编写时从此技能目录运行;绝不要复制到用户的仓库中:
scripts/lint_suite.py— 离线规范和编写规则验证器;无需密钥,也不访问网络scripts/run_suite.py— 提交并轮询;在此用于试运行