viatris-exam-cli
v2.2.0
Published
Agent-friendly CLI for the Viatris exam OpenAPI
Readme
Viatris Exam CLI
面向 Agent 的 Viatris 考试 OpenAPI 命令行客户端。运行时零第三方依赖,要求 Node.js 18 或更高版本。
安装
npm install -g viatris-exam-cli
export VIATRIS_API_KEY="replace-with-real-key"
viatris-exam login
unset VIATRIS_API_KEY开始任务前更新到最新版本:
npm install -g viatris-exam-cli@latest
viatris-exam --version默认连接线上环境:
https://apaaspsc.doubaoapps.com/app/app_17gbe211qq5/openapi/切换到开发环境:
export VIATRIS_API_ENV="development"开发环境地址:
https://apaaspsc-app_17gbe211qq5-1879207268486311.aiforce.run/app/app_17gbe211qq5/openapi/VIATRIS_API_ENV 支持 production、development,以及别名 prod、dev。如需临时连接其他部署,可设置 VIATRIS_API_BASE_URL;该变量的优先级高于环境预设。
login 将 Key 写入 ~/.viatris-exam/.credentials.json。隐藏目录权限为 0700,凭证文件权限为 0600。CLI 不接受 --api-key 参数,也不会输出 Key。
读取顺序:
- 优先读取隐藏凭证文件。
- 文件不存在时读取
VIATRIS_API_KEY。
默认认证格式:
Authorization: Bearer <API key>无需设置 VIATRIS_API_KEY_HEADER 或 VIATRIS_API_KEY_PREFIX。
Agent 接口约定
- API 成功响应以 JSON 写入
stdout。 - 错误以单行结构化 JSON 写入
stderr。 - POST/PUT 请求从文件、
stdin或--json读取 JSON 对象。 - API Key 优先从隐藏凭证文件读取,环境变量作为兜底。
- 默认使用线上环境,可通过
VIATRIS_API_ENV=development切换到开发环境。 VIATRIS_API_BASE_URL可覆盖当前环境地址。- GET 请求遇到网络错误、HTTP 429 或 5xx 时自动重试,POST/PUT/PATCH/DELETE 不自动重试。
describe返回机器可读的命令、参数、认证和退出码清单。- ID 路径参数自动进行 URL 编码。
- HTTP 401/403 使用专用退出码,方便 Agent 判断需要刷新认证。
viatris-exam describe --compact退出码:
| 退出码 | 含义 |
| --- | --- |
| 0 | 成功 |
| 1 | API 返回错误 |
| 2 | 命令、参数、校验或输入错误 |
| 3 | 环境配置错误 |
| 4 | 网络或超时错误 |
| 5 | 认证或授权错误 |
待确认操作
创建考试、整树回写、批量删除/审核题目,以及删除知识文档,均不会立即执行。接口返回 202 后,CLI 会在成功 JSON 中追加:
_cli.message:明确提示操作尚未执行。_cli.openUrl:管理员确认页绝对 URL,应直接展示给用户。_cli.expiresAt:确认过期时间。_cli.statusCommand:后续状态查询命令。
CLI 不会自动打开或确认网页。管理员确认后运行:
viatris-exam operations get "$OPERATION_ID"只有 status=executed 表示执行完成,并应读取 result;pending/executing 仍未完成,failed/canceled/expired 均为终态但不代表成功。
确认页 URL 由当前 API 环境自动生成:
- production:
https://apaaspsc.doubaoapps.com/app/app_17gbe211qq5/operations/<operationId> - development:
https://apaaspsc-app_17gbe211qq5-1879207268486311.aiforce.run/app/app_17gbe211qq5/operations/<operationId>
CLI 会将顶层 confirmationUrl 与 _cli.openUrl 同步规范化为对应环境地址。
命令
产品主数据
viatris-exam products list
viatris-exam products create --input product.json
viatris-exam products update "$PRODUCT_ID" --input verified-medical-data.json创建产品时仅中文名称 name 必填;code 和 nameEn 可省略,省略 code 时由服务端生成。创建会同步初始化规范知识树根节点。更新命令仅用于补充经资料核验的英文名、通用名、适应症、剂型规格和备注。
产品知识树
viatris-exam products get "$PRODUCT_ID"
viatris-exam products update-knowledge-tree "$PRODUCT_ID" \
--task-id "$KNOWLEDGE_TREE_TASK_ID" \
--input knowledge-tree.json产品主数据不属于业务知识树层级;详情和整树回写均接受产品编码、产品主数据 ID 或历史知识树根节点 ID,推荐使用稳定的产品编码。固定维度为 L1;知识树回写必须一次提交全部 15–2000 个 L2/L3/L4 动态节点,以及最多 200 个产品级文档。任务中心发起的流程必须通过 --task-id 携带任务 UUID,供服务端拒绝过期回写;直接更新可以省略,任务变化返回 409。
回写只登记 knowledge_tree_rebuild 待确认操作,返回 202、确认 URL 及 preview.before/after。预览按完整路径统计新增、移除和保留节点,按标题统计文档变更,并列出节点、文档引用和题目数量。管理员确认后才替换动态树、解绑原题目并自动保存 knowledge_tree_version 版本快照;after.questionCount 为 0。通过 operations get 确认 executed 后,再用 knowledge tree 回读验收。
新版契约已移除整树和节点删除接口,对应 CLI 命令已撤下;历史删除操作仍可通过 operations get 查询。
知识节点与文档
viatris-exam knowledge tree <product-code>
viatris-exam knowledge nodes by-path --input path.json
viatris-exam knowledge nodes create --input node.json
viatris-exam knowledge nodes get <node-id>
viatris-exam knowledge nodes update <node-id> --input changes.json
viatris-exam knowledge nodes move <node-id> --input move.json
viatris-exam knowledge documents list <node-id>
viatris-exam knowledge documents create <node-id> --input document.json
viatris-exam knowledge documents upsert <node-id> --input documents.json
viatris-exam knowledge documents update <document-id> --input changes.json
viatris-exam knowledge documents get <document-id>
viatris-exam knowledge documents link <node-id> <document-id> --input reference.json
viatris-exam knowledge documents unlink <node-id> <document-id>
viatris-exam knowledge documents delete <document-id>产品根和固定维度受保护,不能改名或移动。文档删除需要网页确认,预览包含引用数量和节点路径。
/knowledge CRUD 响应中的 level 是物理存储层级(产品根为 1、固定维度为 2);产品生成接口使用业务层级(产品隐藏、固定维度为 L1、动态节点为 L2-L4)。
产品级文档只保存标题,不再保存或返回原文和 URL。L4 节点通过 documentRefs 引用文档,并携带原样落库、可对外披露的 markedExcerpts。关联与解除关联只改变节点引用,不删除文档本体。
所有文档写入都会在请求发出前从 title、url、summary、content 和 markedExcerpts 中移除“小荷”“小荷医疗”和“小荷 AI 医生”及其空格变体。新版写接口只发送 title 和适用场景下的 markedExcerpts;单文档更新只发送 title,节选通过创建、upsert 或关联命令更新。兼容字段 url、summary、content 仍执行净化,但统一从出站载荷移除。该规则覆盖文档创建、批量 upsert、单文档更新、文档关联和整树回写;标题或节选清洗后为空会直接返回校验错误。
出题规则与任务
viatris-exam gen-rules list
viatris-exam gen-rules list --scope global --enabled true
viatris-exam gen-rules list --product lipitor --enabled true
viatris-exam gen-rules create --input rule.json
viatris-exam gen-tasks list --status generating --limit 20
viatris-exam gen-tasks get "$TASK_ID"
viatris-exam gen-tasks submit "$TASK_ID" --input examples/generated-questions.jsongen-rules list 默认返回通用与指定产品的全部规则;--scope 接受 global/product,--enabled 接受 true/false。--product 只筛选绑定该产品的产品规则,不能与 --scope global 同时使用。只有启用规则参与实际出题。
gen-rules create 必填 name 和 content,支持 scope、products(最多 20 个产品编码)、兼容单值 product 和布尔值 enabled。省略范围时,带产品字段按产品规则,否则按通用规则;同时提供两种产品字段时优先使用 products。同名、同范围、同产品集合命中时更新内容并返回原 ID,created=false。省略 enabled 时,新建默认启用,幂等更新保留原状态。
externalRef 是题目回写的幂等键。Agent 重试 POST 前应复用原值。
题目级 difficulty 使用 easy/medium/hard。普通任务省略时,服务端按 basic→easy、medium→medium、advanced→hard 映射任务难度。产品全节点任务的 dimension 为 all,不返回任务难度,因此应为每道题显式指定难度;同时将任务总 quantity 分配到 knowledgeContexts,并通过 knowledgeNodeIds 至少绑定一个任务上下文节点。其余绑定项也必须是同产品 L4 节点。上下文只包含具有可披露 excerpts 的证据文档。
题目 tags 可直接传混合数组,服务端会剥离产品、知识维度、难度和题型等结构化值,将第一个剩余值归入单值 businessTopic,其余保存为自由标签。
考试记录
viatris-exam exam-records get "$RECORD_ID"
viatris-exam exam-records scoring-rules "$RECORD_ID"第二个命令返回答卷绑定版本的完整评分规则及用于回写的 taskId。
每个评分项同时返回 status、归一化后的 businessTopic、questionType、tags、keyErrors 和可披露 excerpts。
按考试定位答卷并完成评分:
viatris-exam exams list --keyword "立普妥" --page 1 --page-size 100
viatris-exam exams answer-sheets "$EXAM_ID" --status submitted --is-retest false
viatris-exam exam-records scoring-package "$RECORD_ID"
viatris-exam exam-records scoring-task "$RECORD_ID"
viatris-exam exam-records scoring-results "$RECORD_ID" --input results.json
viatris-exam exam-records scoring-result "$RECORD_ID"考试列表和答卷列表均支持 --page、--page-size(1–100),应根据 total 读取全部分页。答卷列表默认只返回已提交及超时交卷的答卷;--status all 包含作答中答卷,--is-retest true|false 筛选复测或首考。
scoring-package 提供试卷绑定版本的逐题材料、考生原始答案及 itemId。scoring-task 接受可选 JSON,默认 reset=failed;{"reset":"none"} 只补建任务,{"reset":"all"} 清空已有评分以重跑。重置人工复核项还需 allowReviewOverwrite=true,仅在明确要求覆盖复核结果时使用。准备任务后核对评分项状态,再回写 pending 项;scoring-result 返回整卷状态、进度、总分与逐题明细。已评分项重复回写返回 409,任务缺失应先准备任务。
评分任务
viatris-exam scoring get "$TASK_ID"
viatris-exam scoring submit "$TASK_ID" --input examples/scoring-results.json仅对 status=pending 的评分项回写结果,不得重复提交 done、failed 或 reviewed 项。将 businessTopic 与 questionType 作为结构化评分上下文,并检查其余标签。评分规则 V2 使用稳定的评分点 ID、扣分规则 ID 和题目级封顶规则,由服务端计算最终得分;评分前必须逐项核对 keyErrors,引用来源依据时只能使用接口返回的 excerpts,不得编造封顶规则 ID。V1 pointResults 结构继续兼容。
考试与题库
viatris-exam exams create --input exam.json
viatris-exam questions list --product lipitor --status pending_review --page 1 --page-size 20
viatris-exam questions create < questions.json
viatris-exam questions batch-delete --input batch-delete.json
viatris-exam questions batch-review --input batch-review.json
viatris-exam questions set-knowledge-nodes "$QUESTION_ID" --input bindings.json
viatris-exam questions version "$QUESTION_ID" --input version.jsonquestions list 支持按产品、知识维度、难度、状态和生成任务筛选,状态包含用于生成异常的 anomaly。响应提供 items/total/page/pageSize,题干为摘要;执行 selectAll 批量操作前,应使用相同筛选条件分页核对命中范围。
题目创建、任务回写和版本追加均支持 easy/medium/hard 难度、可披露原文引用 excerpts、关键错误项 keyErrors、标签 tags 与参考关系 references;直接创建省略难度时默认为 medium,版本追加省略难度时保持原值。直接创建和任务回写优先使用 knowledgeNodeIds 绑定多个同产品 L4 知识点;兼容字段 knowledgeNodeId 与数组同时提供时由服务端合并去重。
questions set-knowledge-nodes 使用 {"nodeIds":[...]} 全量覆盖已有知识点绑定,按数组顺序提交;每项必须是与题目同产品的 L4 节点 UUID。{"nodeIds":[]} 解除全部绑定。该命令直接返回调整后的 questionId 和 knowledgeNodes,只改绑定,不修改内容或版本。整树重建后可用当前 L4 节点 ID 重新绑定题目。
创建考试时 assigneeIds 必须非空,每项使用 external:<账户 UUID>,仅支持已启用的系统账户且不再限制 20 人。CLI 会先校验 ID 格式,服务端再校验账户存在性和启用状态。命令返回考试创建预览与确认 URL;管理员确认并执行后,operations get 的 result 才返回 examId。
新考试使用非空且去重的 products 数组,例如 ["lipitor","norvasc"];旧单值 product 仍兼容。paperMode 默认为 fixed,所有考生共用试卷;per_candidate_random 为每位考生生成题目集合不重复的个人试卷,此时 questions 是示例卷及题序分值模板。候选题池合并所选产品下全部已审核题目,可由 randomDimensions 筛选维度。题量为 1–150,每题分值须为正整数且全卷合计 100 分;questions 与旧 questionIds 不可同时提交。
批量删除和审核支持指定 ids,或使用 selectAll:true 配合 filters。审核动作使用 approve/reject,其中 reject 必须提供 reason。两者都只登记待确认操作;被考试引用的题目在物理删除执行时会自动跳过。
医疗知识检索
医学检索 API 按调用收费。先检查本地材料,再将同一主题的产品名、通用名和多个知识点关键词合并到一次查询:
viatris-exam medical-search search "立普妥 阿托伐他汀 适应症 用法用量 禁忌 相互作用" \
--file-type drug \
--limit 20 \
--max-length 1200也可提交完整 JSON:
printf '%s' '{"query":"阿托伐他汀 适应症","limit":20}' |
viatris-exam medical-search search--file-type 或 JSON fileType 仅接受 guideline(诊疗指南、专家共识)、drug(药品说明书与药品知识)、doctor(医生资料)、hospital(医院或科室资料)。省略时不限定类型,不再默认限定为 drug;参数和 JSON 输入均会校验类型。
limit 允许 1–20,省略时服务端默认 20;maxLength 允许 100–5000,省略时服务端默认 5000。CLI 保留省略字段,由服务端应用默认值。响应为 {query, items},每项只包含已过滤来源品牌的 title 和可披露 excerpts;不返回上游原始 JSON、URL、ID、追踪信息或全文,上游异常时 items 为空数组。
每次成功响应自动保存到 ~/.viatris-exam/medical-search-cache/,JSON 包含查询参数、环境地址、获取时间 fetchedAt 和完整响应 response。相同环境、凭证和查询参数会直接复用有节选的本地结果;省略与显式提供默认 limit/maxLength 等价,不会重复收费调用。缓存目录权限为 0700,文件为 0600,不保存 API Key。可通过 VIATRIS_MEDICAL_SEARCH_CACHE_DIR 指定缓存目录。
缓存不自动过期。需要更新来源时显式添加 --refresh,这会重新调用收费接口并保存新结果:
viatris-exam medical-search search "立普妥 阿托伐他汀 适应症 用法用量 禁忌 相互作用" --file-type drug --refresh相关查询也应先读取缓存中的标题、节选和查询关键词,复用已覆盖的资料后再补充缺失主题。空结果仍会保存,但不会作为有效证据自动复用。写入目录不可用时 CLI 会在调用前报错;若调用后保存失败,错误的 details.response 保留已取得的结果,应先使用该结果,避免重复调用。
集中检索只使用一个 query 字符串和一个可选 fileType。多个关键词不会被 CLI 拆成多个请求,也不保证上游按 OR 搜索或逐词返回;应检查结果覆盖范围。跨类型检索省略 fileType。
错误格式
{
"error": {
"type": "http_error",
"message": "API request failed with HTTP 422.",
"details": {
"status": 422,
"method": "POST",
"path": "/openapi/questions",
"requestId": "request-id",
"response": {
"message": "validation failed"
}
}
}
}全局参数
--base-url <url> 覆盖当前环境地址
--key-header <name> 覆盖认证头,默认 Authorization
--key-prefix <value> 覆盖认证前缀,默认 "Bearer "
--timeout <ms> 超时时间,默认 30000
--retries <n> GET 重试次数,默认 2
--compact 输出单行紧凑 JSON地址选择优先级为 --base-url、VIATRIS_API_BASE_URL、VIATRIS_API_ENV 对应的预设地址。认证 Key 优先使用隐藏凭证文件,文件不存在时使用 VIATRIS_API_KEY。
项目结构
src/
├── cli.js # 入口与异常收口
├── app.js # 应用编排
├── commands.js # 领域命令路由
├── command-handlers/
│ └── *.js # 各领域到 OpenAPI 请求的映射
├── args.js # 参数解析与校验
├── input.js # JSON 文件、stdin 与内联输入
├── config.js # 环境、地址与认证配置
├── credentials.js # 隐藏凭证文件读写
├── http.js # HTTP、重试与响应处理
├── sanitizers/
│ └── documents.js # 文档永久净化规则
├── metadata.js # 版本、命令和环境元数据
├── help.js # 帮助文本
├── output.js # 标准 JSON 输出
└── errors.js # 错误类型
skills/
└── viatris-exam-cli/
├── SKILL.md
└── references/cli-reference.md可分发的 Agent Skill 位于 skills/viatris-exam-cli/,与 src/ 同级并包含在 npm 发布包中。skills/viatris-exam-cli.zip 是同步生成的独立分发包。.trae/skills/viatris-exam-cli 是指向规范目录的相对符号链接,仅用于本地自动发现。
变更规则
任何代码、命令、接口结构、环境地址或文档变化都必须:
- 更新
skills/viatris-exam-cli/SKILL.md及受影响的参考文件。 - 同步递增
package.json、src/metadata.js和 Skill frontmatter 中的版本。 - 保持
src/cli.js为薄入口,将能力放在职责单一的模块中。 - 重新生成 Skill ZIP 并执行验证:
npm run pack:skill
npm test
npm run check
npm run check:versions
npm run check:skill