关于 terra-lab-reports
面向开发者的 Terra API Lab Reports 集成技能。该预发布服务从临床检验报告文件中提取并标准化生物标志物;技能涵盖 API 工作流、数据语义和实现指南。
主要功能
- 01临床报告 OCR 与 AI 提取
- 02生物标志物匹配与标准化
- 03异步处理和状态管理
- 04REST 端点与 Webhook 指南
- 05会话、结果及投递故障排查
适用场景
- 01构建临床报告上传流程
- 02读取标准化生物标志物结果
- 03排查报告投递或处理状态
MCP 相关
该技能说明如何在聊天助手中使用 Terra API 管理 MCP 服务执行管理命令。此处所述 MCP 工具不提供检验报告会话端点;需使用 CLI 的 terra data-api 或应用代码访问。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tryterra/ agent-skills --skill terra-lab-reports安装后在 Claude Code 中输入/terra-lab-reports确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.jsonREADME.mdreferences/api-reference.mdbiomarkers.mdwebhook-payload.mdrules/_sections.md_template.mdapi-poll-at-most-every-5s.mdapi-space-bulk-uploads.mddata-filter-ranges-by-demographics.mddata-keep-unmatched-biomarkers.mddata-parse-utf8.mddata-store-ids-as-strings.mdwebhooks-dedupe-event-id.md详细介绍
Terra API Lab Reports 最佳实践
使用 Terra API Lab Reports(预发布)进行开发的生产指南和 API 参考。它可将临床化验报告 PDF 和图像转换为结构化、标准化的生物标志物数据:先通过 OCR 和 AI 提取数据,再与包含 4,000 多种生物标志物的参考数据集进行模糊匹配,从而生成规范的生物标志物键、UCUM 单位代码和 LOINC 代码。
预发布:请假定接口约定可能会变更。 生成生产请求体或 Webhook 解析器前,请获取实时文档页面;发布前,请对照实时 API 进行验证。
从示例应用开始
对于新应用,请从已发布的化验报告上传和生物标志物趋势示例开始,并根据用户需求进行调整。运行 terra version;如果缺少 CLI,请主动提出安装(见下文)。然后列出当前目录并克隆最合适的示例:
terra examples list --select name,title,description
terra examples clone lab-reports-web-app my-app
这两项操作都无需登录。阅读下载的 README 和 AGENTS.md,并按照 next_steps 安装依赖、完成配置并运行示例,然后再基于它进行开发。克隆操作只会下载文件。对于现有应用,请将示例作为参考,并就地调整相关部分。在无法运行 CLI 的聊天助手中,请向用户提供这些命令,让他们在自己的终端中运行;或者提供源代码链接:https://github.com/tryterra/terra-examples/tree/main/examples/lab-reports-web-app。
账户工具:CLI 或 MCP
所有 Lab Reports 端点都可以手动调用,这是回答“那份报告去哪了”最快的方法:
terra data-api /lab-reports -q reference_id=<ref>
terra data-api /lab-reports/<session_id> # status and parsed results
terra data-api /lab-reports/<session_id>/deliveries # per destination: status, attempts, last error
terra data-api /lab-reports/<session_id>/files # the input files behind the session
如果报告已解析却始终未送达,首先应查看 deliveries:它可以区分“我们从未送达”和“我们已送达,但你的端点拒绝了”这两种情况,而它们对应的是不同的错误。一次上传可能会分发到多个会话,因此请从 Webhook 事件或 /lab-reports?upload_id=... 中获取会话 ID,不要假定一次上传就对应一个会话。
运行 terra admin-api list --data-api /lab-reports --format json,查看端点需要哪些参数。
以上每条命令都是 terra data-api,只有 CLI 提供此功能;通过 MCP 时,没有管理工具可以读取化验报告会话,因此如果没有 CLI,请从应用程序自身的代码中调用这些端点。
在编码 Agent(Claude Code、Codex、Cursor 等)中,无论它运行在用户的机器上还是云端,都应使用 CLI;如果缺少 CLI,请主动提出安装:在 macOS 和 Linux 上运行 curl -fsSL https://cli.tryterra.co/install.sh | sh,在 Windows PowerShell 中运行 irm "https://cli.tryterra.co/install.ps1" | iex,或者在用户已使用 Homebrew 或 npm 的情况下通过它们安装。在聊天助手(claude.ai、Claude Desktop、ChatGPT)中,即使能够运行代码,也应使用 Terra API 管理 MCP 服务,因为其沙盒无法安装 CLI 或登录。每个管理命令都是一个工具,其名称和 method 与命令对应(terra users list 对应 users_read,且 method: "list")。只有 CLI 提供 terra data-api、terra admin-api 和 terra examples;--select 和 --jq 没有对应的 MCP 功能。terra-cli 和 terra-mcp 技能包含安全防护指南(确认变更、避免在对话记录中泄露凭据)、错误说明,以及针对各项任务的操作手册。它们用于管理集成,并不能替代本技能所述的 API 调用。
产品功能
上传临床检验报告,即可获取结构化生物标志物结果——提取并标准化后,发送到指定目的地或通过 REST 提供。
- 输入: 每个请求上传一个文件,支持 PDF、PNG、JPEG、GIF 或 WebP,最大 20 MB。
- 提取: OCR 加 AI 解析会从页面中提取每项结果的名称、数值、单位、标记和参考范围。
- 标准化: 将每个提取出的名称与包含 4,000 多条记录的生物标志物数据集进行模糊匹配(阈值为 0.85),生成规范的生物标志物键、符合 UCUM 标准的
ucum_code,以及(针对具有 LOINC 映射的子集)loinc_code。 - 输出: 一个 Session,其中包含分层 Results(来源 / 生物标志物 / 测量 / 解读 / 参考范围),并按报告级 Panels 分组;结果以
lab_report.completed事件发送(若最终失败,则发送lab_report.failed)。
异步工作流与状态生命周期
处理完全异步。上传会立即返回 202 和一个 upload_id(current_status: "processing"),报告随后会依次经历:
processing → processed → standardizing → standardized → sending → sent
其他状态包括:retry_scheduled、retrying、cancelled、deleted 和 failed。终态包括 sent、failed、cancelled 和 deleted。
Session 达到 standardized 后即可查询结果,无需等到发送完成。你可以通过 webhook 事件(成功时为 lab_report.completed,最终失败时为 lab_report.failed)或轮询来了解处理结果。处理通常需要 30 秒到 3 分钟。
端点
基础 URL:https://access.tryterra.co/api。每个请求都需要同时包含 dev-id 和 x-api-key 两个标头。
| 方法 | 端点 | 说明 |
|---|---|---|
| POST | /v2/lab-reports | 多部分上传;字段 MUST 为 file(单数),每个请求上传一个文件。202 会返回 upload_id + current_status: "processing"——不会返回 session_id(一次上传可能分发到多个会话)。 |
| GET | /v2/lab-reports | 列表/筛选(按 reference_id、upload_id、report_date_from/_to、uploaded_at_from/_to)。上限为 500 条,请使用筛选条件。 |
| GET | /v2/lab-reports/{session_id} | 会话:元数据、upload_id、状态历史记录、分层的 results[]、panels[]。不会嵌入文件、处理产物和交付状态——请使用子资源。 |
| GET | /v2/lab-reports/{session_id}/files | 输入文件和缩略图,以预签名 URL 的形式返回,并附带响应级别的 expires_at。 |
| GET | /v2/lab-reports/{session_id}/deliveries | 各目标的交付状态(destination_id、status、attempt_count、last_error)。 |
| GET | /v2/lab-reports/{session_id}/artifacts | 处理产物;仅限特权密钥——标准密钥会收到 404。 |
| POST | /v2/lab-reports/{session_id}/reprocess | 重新运行提取/标准化;异步返回 202。会发出一个新的事件(新的 event_id),但使用相同的 session_id。 |
| DELETE | /v2/lab-reports/{session_id} | 软删除;返回 204。 |
references/api-reference.md 会将各项目标对应到其端点,并说明规范页面一笔带过的语义;实现任何端点调用前请先阅读。有关完整的请求/响应/错误规范(RFC 7807 格式、状态码),构建调用时请获取实时页面:API 参考(Markdown 版本请在 URL 后附加 .md)。
数据模型
层级结构:Session → Results[] + Panels[],其中每个 Result 分为多个层。
- Session –
session_id(snowflake 字符串)、upload_id、可选的reference_id、current_status、report_type、报告日期和时间/采集日期和时间、report_locale、lab_name、patient_sex、patient_age_at_collection、status_history[]、results_count、file_count、input_bytes、output_bytes、report_notes、results[]、panels[]。 - Panel – 报告级别的分组:
{ id, name, key }。Result 通过biomarker.panel_id引用它。 - Result – 四层结构,在 webhook 负载和 GET 响应中完全相同:
source– 报告中实际打印的内容:name、panel、value(原始字符串)、units、flag(原样保留)、method、notes、reference_text(仅 webhook 副本包含collection_date/collection_time;GET 将它们放在 session 中)。biomarker– 规范化后的标识:key(未匹配时为 null)、display_name、loinc_code、panel_id、panel_key、specimen。measurement– 一个类型化数值:type用于指明已填充的同级字段(numeric、bounded{operator, value}、qualitative{text, code}、text,或者缺省并带有absent_reason),另有units和ucum_code。interpretation– 异常判定层:flag(编码值,可为 null)、flag_raw、source、applied_range{lower, upper}(用于判定 flag 的范围)。
- Reference Range –
lower、upper、type(描述范围类型的标签,而非判定结果),以及context(sex、age_lower/age_upper、pregnancy_status、cycle_phase、gestational_week_lower/_upper、reference_population、modifiers[])。
Webhook 封装格式的语义见 references/webhook-payload.md;如需查看字段级类型和枚举表(枚举是开放的,会不断扩展),请获取实时的 Core Concepts 页面(添加 .md 可获取 Markdown 格式)。
关键数据语义
- 未匹配时,
biomarker.key存在但值为 NULL – 这是唯一的未匹配信号。绝不要依据loinc_code判断(即使匹配成功,它也可能为 null)。请回退使用source.name/biomarker.display_name,并保留该结果。 - 根据
measurement.type分支,并读取相应字段。 不要按优先级依次检查多个数值字段——扁平的value/value_gt/value_lt/qualitative_value字段已不存在;类似<0.5的边界值会以bounded: { "operator": "lt", "value": 0.5 }的形式传入。 - 两个 flag,各有不同含义。
source.flag是实验室的原始字符串("H"、"↑"等);interpretation.flag是编码后的信号(可为 null——null 表示无信号),flag_raw会保留原始形式,source则标明其来源。 - 枚举是开放的。
current_status、report_type、measurement.type、specimen、范围type、patient_sex可能会在不提升主版本号的情况下新增值。请妥善处理未知值(归入默认/未知类别,绝不要抛出异常)。 - 所有枚举值都是规范的小写字符串(
"sent",而非"REPORT_STATUS_SENT"或6)。所有时间戳均为 ISO-8601 UTC。
注意事项
- 上传返回
upload_id,而不是session_id。202响应体为{ "upload_id": "...", "current_status": "processing" }。一次上传可能分发到多个会话;从 webhook 的data.session_id或GET /v2/lab-reports?upload_id=...获取会话 ID。较旧的会话可能没有upload_id——请将其视为可选字段。 - 有两种 webhook 事件;根据封套中的
type分支处理。 成功时为lab_report.completed,最终失败时为lab_report.failed。每个目标的选择加入仍使用单一的粗粒度类型"lab_report",并通过destination_event_types配置——两种事件共用该类型。 - 根据
event_id去重。 同一已存储负载的重发会携带相同的event_id;重新处理会生成一个新的event_id,但session_id相同。请参阅 rules/webhooks-dedupe-event-id.md。 - 失败响应包含结构化错误。
data.error的格式为{ code, message, retriable },错误代码为file_unreadable、extraction_failed、standardization_failed、internal。retriable: true表示重新提交相同输入可能成功;false表示应先修正输入。 - 即使
reference_ranges已填充,interpretation.applied_range也可能为 null。 只有在恰好有一个范围明确适用于患者时才会设置该字段;如果为 null,请自行按上下文筛选reference_ranges(请参阅 rules/data-filter-ranges-by-demographics.md)。 - 预签名文件 URL 位于子资源中,且会过期。
GET .../files(以及具备特权的.../artifacts)会返回预签名 URL,并在响应级别提供expires_at(大约一小时后过期)。这些 URL 不会嵌入 webhook 或会话响应中。再次获取子资源以重新生成 URL;请勿在expires_at之后继续保存 URL。 - 制品仅限具备特权的用户访问,其他请求会得到
404。 标准密钥调用GET .../artifacts会得到404,而不是空列表。 - 超大上传: 超过 20 MB 的文件通常会由字节限制读取器拒绝,并返回
400(“invalid multipart form or file too large”);只有当 multipart 部分声明的 Content-Length 超出上限时才会返回413。请预期收到400(有时为413)。
规则
编写相关代码前,请先阅读 rules/ 中的对应规则。每个规则都是独立文件,并附有错误和正确示例。
Webhook 与投递(高优先级)
webhooks-dedupe-event-id– 使用event_id实现幂等;重发会复用该 ID,重新处理会生成新的 ID,但session_id相同。api-poll-at-most-every-5s– 生产环境使用 webhook(成功和失败事件均适用);开发或回退场景使用轮询;轮询间隔不得短于 5 秒,并在状态变为终态后停止。
数据处理与 API 使用(高至中优先级)
data-keep-unmatched-biomarkers–biomarker.key为 null 在临床上仍有意义;切勿丢弃结果,应回退使用source.name并标记以供审核。data-filter-ranges-by-demographics– 存在interpretation.applied_range时使用该字段;否则在解读前按性别、年龄和上下文筛选reference_ranges;谨慎处理measurement.bounded。data-store-ids-as-strings– Snowflake 的session_id用作 JS 数字会丢失精度;请始终将其作为字符串处理。data-parse-utf8– 数据包含µ、×、±和上标;请始终按 UTF-8 解析。api-space-bulk-uploads– 每个请求上传一个文件,上限为 20 MB,每个文件需 30 秒至 3 分钟;批量上传之间应留出间隔,并添加reference_id标签。
参考资料
加载以下资料以查看完整规范(每份资料均自成一体):
- references/api-reference.md – 目标到端点的路由,以及规范页面未详细说明的语义。调用任何端点前请先阅读;获取链接中的实时页面以查看完整的请求/响应格式。
- references/webhook-payload.md – 事件信封(
type、event_id、occurred_at、upload_id、data)、幂等键和失败事件。构建 webhook 处理程序时请阅读。 - references/biomarkers.md – 标准化、UCUM 映射、LOINC 覆盖范围,以及按类别划分的常见生物标志物表。处理键、单位或 LOINC 代码时请阅读。
完整的生物标志物数据集(4,000 多条,约 700 KB)未随附;请从 Biomarker Reference 页面下载。
在线文档
获取页面前,请先使用 terra docs ask(或通过 MCP 使用 docs_ask)提问:它会根据文档作答并注明来源。为任何文档 URL 添加 .md 即可获取 Markdown 格式。