TypeSafe 兼容性
TypeSafe 闭源的 Jev 模型开创了「System One」这一决策模型类别。Ollaya 的 /v1/* API 与 TypeSafe 的线上格式完全一致 —— 以 typesafe-sdk 0.7.1 的线上 schema 和错误处理为准 —— 所以为 TypeSafe 写的代码能跑在你本机上的开放模型上。
把 SDK 指向 Ollaya
官方的 TypeSafe Python SDK 0.7.1 无需改动即可使用。设置这些环境变量:
export TYPESAFE_BASE_URL=http://localhost:11435
export TYPESAFE_API_KEY=local # the SDK needs a non-empty key; any value works
export TYPESAFE_DEFAULT_MODEL=winnow:e4b # otherwise the SDK sends its default, "jev-latest"
export NO_PROXY=localhost,127.0.0.1 # keep local requests off any system proxy
- 默认模型。
winnow:e4b最接近 Jev(类型化决策上 0.722,Jev 是 0.738),在 RTX 4090 上约 90 ms 作答。没有 NVIDIA GPU 就用laya,它在 CPU 上零点几秒就能回答。 - API key。 Ollaya 接受任何 key,除非服务器设置了
OLLAYA_API_KEY;那之后 SDK 的 key 必须与它一致。 - 请求 ID。 每个响应都带
x-typesafe-request-id,所以response.request_id可用。 - 重试。 SDK 在 10 秒后超时并重试。对某个模型的第一次请求会等它加载,而比请求活得更久的加载会继续,所以重试时模型已经是热的。
- 系统代理。 在带系统 HTTP 代理的 Mac 上,TypeSafe SDK(和
httpx一样)会把发往localhost的请求也走代理,无视系统的例外列表。于是你的状态会穿过代理,而 Ollaya 关着时,SDK 报的是502 status code (no body),而不是连接被拒。把NO_PROXY=localhost,127.0.0.1写在TYPESAFE_BASE_URL旁边。 - 预热与耗时。 想在第一次请求前加载模型,就向
/api/decide发送{"model": "winnow:e4b", "keep_alive": -1}(不带state)。/v1/*的响应不带耗时,和 TypeSafe 的一样;/api/decide会报告total_duration、load_duration和eval_duration。
端点
| 端点 | 说明 |
|---|---|
POST /v1/systemone |
做决策。请求:model、state(必填)和 questions。响应:恰好是 model、answers 和 usage。 |
POST /v1/decisions |
/v1/systemone 的别名 |
GET /v1/models |
本机上的模型:name、description、release_date |
请求与响应
curl http://localhost:11435/v1/systemone \
-H "Authorization: Bearer local" \
-d '{
"model": "laya",
"state": "Can I get an invoice for last month?",
"questions": {
"intent": {
"type": "choice",
"instructions": "What does the customer want?",
"criteria": {
"invoice": "Needs an invoice or receipt",
"refund": "Wants money back",
"other": "Anything else"
}
}
}
}'
{
"model": "laya:en",
"answers": {
"intent": {
"type": "choice",
"choice": "invoice",
"confidence": 0.9547,
"probabilities": {"invoice": 0.9698, "refund": 0.0172, "other": 0.013}
}
},
"usage": {"input_tokens": 43, "output_tokens": 0}
}
响应里的 model 是实际作答的 checkpoint:laya 是一个 router,这个英语请求发去了 laya:en。TypeSafe 的 schema 允许这样(“may differ from the alias supplied in the request”)。数值保留 4 位小数,probabilities 与 criteria 的顺序一致。
curl http://localhost:11435/v1/models -H "Authorization: Bearer local"
{
"models": [
{
"name": "laya:en",
"description": "English decision model (ModernBERT-large): guardrails, email and ticket triage.",
"release_date": "2026-09-23"
},
{
"name": "laya:latest",
"description": "Routes each request to laya:en or laya:multilingual by the text's script and language.",
"release_date": "2026-09-23"
},
{
"name": "laya:multilingual",
"description": "Decision model for 100+ languages (mmBERT-base).",
"release_date": "2026-09-23"
}
]
}
/v1/models 列出拉到本机上的模型,包括 router;不列出 registry。
错误
错误带 TypeSafe 的状态码,以及一个 SDK 能正确读取的响应体:一个字符串 error(SDK 会显示它)、一个机器可读的 code,以及在 422 上 TypeSafe 的 detail 校验问题列表。每个代码见错误。
{"error": "model \"jev-latest:latest\" not found, try pulling it first", "code": "MODEL_NOT_FOUND"}
哪里不一样
兼容覆盖的是 API,不是模型:
- 模型名是 Ollaya 的(
laya、laya:en),所以要设置TYPESAFE_DEFAULT_MODEL或传入model。 - 缺
instructions。 一个问题没有它时,模型会读取问题 id 来顶替,所以给问题起描述性的名字(is_urgent、tone)。 - 限制。 每个请求最多 256 个问题,2–255 个选项,2–10 个 score 档位。每个模型还有选项预算:
laya:en约 125 个选项,laya:multilingual是 250 个。 - 长状态。 TypeSafe 最多读 65,536 个 token;开放模型的上下文更短(
laya:en是 512 个 token,laya:multilingual是 1,024 个,含问题在内)。状态放不下时,/v1/*返回422 STATE_TRUNCATED,而不是拿它的一部分来作答。换一个上下文更长的模型、缩短状态,或调用/api/decide,它会截断并报告state_truncated。 /v1/*保持纯净。keep_alive、extras这类原生字段在那里会被忽略;路由、耗时和截断都在/api/decide上报告。- 质量来自开放模型,所以按任务不同而与 Jev 有差别:
laya:typed-decisions在类型化决策上得 0.766,Jev 1.13 公布的是 0.727。- 基础的 Laya checkpoint 在类型化决策上零样本接近随机(0.362)。
- 选项很多的 choice 问题(超过约 20 个)更弱:Banking77 上 0.425,Jev 是 0.870。
切换生产流量之前,先在你自己的数据上量一量。Laya 页面有细节。
没有关联
Ollaya 是一个独立的开源项目。它与 TypeSafe 没有关联,也未获 TypeSafe 认可。