跳转到内容
快速开始

③ 问答

内置工具

引擎随包发布的四个 MCP 工具:术语、健康记录与基因;以及 DeepAgent 从它的 harness 额外获得的能力。

下面每一个工具都是一个普通的 Python 方法,由运行期发现捡起来的。这里没有任何部分被引擎特殊对待,也没有任何一个是编译进去的:找到它们的规则,和找到你写的那个是同一套。

MCP 工具面刻意做得很小。随包一共四个工具,而权威清单永远是你自己那台服务报出来的,直接问它:

Terminal window
curl -X POST http://localhost:18080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

四个工具分三组提供:术语解析(resolve_indicatornormalize_unit)、健康记录读取(query_health_indicators)与基因数据读取(get_genetic_data)。四个里有两个什么都不需要:不要账号、不要网络、不要 key;另外两个绑定调用者自己的记录:

工具做什么需要什么
resolve_indicator任意语言的指标名 → 规范 LOINC什么都不需要(离线,不碰用户数据)
normalize_unit自由文本单位 → 规范 UCUM + 可比性族什么都不需要(离线,不碰用户数据)
query_health_indicators调用者自己的记录:检索、读取与聚合在一次调用里完成账号
get_genetic_data按 rsID 查调用者的变异账号

这两个工具让模型能把一个名字放到与编码同等的位置上。「LDL cholesterol」「低密度脂蛋白胆固醇」和「LDL-C」是同一项测量的三种写法,它们都能被归到同一个规范身份上。两个工具都不读用户数据,所以匿名调用者也能使用,不会泄露任何信息。

解析运行在随包分发的词表上,客户端即便断网也照样答得出来,这正是健康数据应有的性质。

names string[] required

按打印出来的原样传名字。整批一次调用传完。

按输入顺序,每条返回:name 原样、resolvedloinc(例如 718-7,未解析时为空)、canonical(LOINC long common name),以及 candidates:有多少条语料命中。candidates 很大意味着确实存在歧义,而系统挑了一个合理默认;在精度要紧的场合要把这件事讲出来。

有三条性质是明确写给模型看的,因为它们决定了答案该怎么写:

  • 未解析是一次诚实的「没有」。 就报告这个名字没匹配上,绝不要编一个编码出来。
  • 套餐名刻意不解析。 blood pressure血圧 指的是套餐而不是观测项,正确的反应是反问要哪一项(收缩压还是舒张压)。
  • 两个名字获得同一个编码,就是同一项检查。 决定两条读数能不能比较的是这个,而不是字符串相等。

units string[] required

按打印出来的原样传单位串,例如 ["mg/dL", "毫摩尔每升", "次/分"]。单次最多 200 个。

返回 unit 原样、ucum(规范形式;为空表示没认出来)与 family(也就是 LOINC PROPERTY,例如 SCnc)。

"MG/DL"
ucum "mg/dL" · family "MCnc"
"毫摩尔每升"
ucum "mmol/L" · family "SCnc"

族才是重点:同一族内的单位可以互换,跨族换算是范畴错误,不是算术。

该工具将检索、读取与聚合合并为单次调用,而且每条结果都带着它的规范身份。

keywords string[]

模糊词,任意语言。缩写请把两种写法都给上,例如 ["MCHC", "Mean Corpuscular Hemoglobin Concentration"]

indicators string[]

上一次调用返回的精确名字。用它替代 keywords,而不是和猜的词混着用。

start_time string

起始日期(含),YYYY-MM-DD

end_time string

结束日期(含),YYYY-MM-DD

aggregate string default: none

nonestatsdayweekmonth 之一:它在 schema 里被声明成 enum,所以非法取值在引擎代码运行之前就会被拒。stats 按指标返回 count/min/max/avg/first/last/change;给一个时间桶则每桶返回一个点。趋势类问题应该用它们,而不是把原始读数全拉下来。

limit integer default: 50

aggregatenone 时,每个指标最多返回多少条读数。上限 500 写在 schema 本身里。

返回结构是按「让模型不用靠猜就能继续」来设计的:

字段是什么
indicators每个命中项:indicator(精确名字,可以直接回填给 indicators)、system / code(规范身份:编码相同就是同一项检查,不管名字怎么写)、count,以及 rows(竖线分隔的表格)。开头那行 (constants: k=v) 装的是每行都相同的列,通常就是单位。
catalog在没给任何过滤条件时、以及什么都没匹配上时,代替 indicators 返回:列出这个用户实际有什么,好让模型从现实里挑,而不是重新猜关键词。
truncated指标 → 实际总量,当某个序列被 limit 截断时出现。正确的处理是缩窄时间窗或改用聚合,而不是把 limit 调大。

rsid string | string[] required

dbSNP 标识符,例如 "rs4988235"["rs1801133", "rs429358"]。逗号分隔的字符串也行。

limit integer default: 100

最多返回多少个变异。

include_nearby boolean default: true

同时返回每个命中点 nearby_range 范围内的变异,每个命中最多 20 个。只要精确查询就设 false

nearby_range integer default: 1000000

半窗宽度,单位是碱基对。

它读的是用户自己上传的基因型文件,不是参考数据库。消费级芯片只检测基因组的一小部分,所以没有 ≠ 阴性:结果里缺了某个 rsID,只说明它没被检测,对等位基因什么都没说。

DeepAgent 从 harness 获得的额外工具

Section titled “DeepAgent 从 harness 获得的额外工具”

上面那张表对 DeepAgent 而言并不是全部:它的 deepagents harness 还会额外提供一些能力,而那些不是 MCP 工具,外部 MCP 客户端看不到它们。

来自骨架是什么
ls · read_file · write_file · edit_file · glob · grep原生文件工具,作用在由 PostgreSQL 支撑的虚拟文件系统上。对着上传的 PDF 调 read_file,交给模型的是原始文档本身(多模态),而不是一份有损的抽取结果。
eval来自 langchain-quickjs 的持久进程内 JavaScript REPL,模型就是靠它对取来的数据做真正的计算。
Agent Skills不是工具:SKILL.md 写的流程,以 frontmatter 注入,只在任务需要时才读全文。见 Agent Skills

delete 被按名字排除:PostgreSQL 文件系统后端没有实现它。没有 task 子代理,也没有 write_todos