本节摘要:本节用最少的封装跑通第一个 Jev 调用:先 curl 看
POST /v1/systemone的协议原貌——state 是一条客服消息,questions 里一个 Noul 问"是否表达紧迫性";再给完整的 Python 脚本(内嵌于本节,即 01_hello_jev.py),用requests发送同样的请求、读取answers.<id>.noul并按概率分支。裸调协议的价值:一切 SDK 与框架报错时,最后都要回到这一层排障;同时它能让你确信——Jev 就是一个普通的 HTTP 函数调用,没有任何魔法。
阅读完本节,你应当能够:
noul 字段。answers.问题ID.类型字段)。curl https://api.typesafe.ai/v1/systemone \ -H "Authorization: Bearer $TYPESAFE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "jev-latest", "state": "Hi, I'"'"'ve been trying to connect my Stripe account for 3 days now and customers can'"'"'t pay. This is costing me money every hour.", "questions": { "is_urgent": { "type": "noul", "instructions": "The message conveys urgency or time-sensitivity" } } }'
(这是 LangChain 官方博文用的第一个例子。)响应的核心:"noul": 0.999——这段话几乎确定是紧急的。
注意请求里只有四样东西:model、state、questions、每个问题里的 type + instructions。没有系统提示词、没有对话历史、没有采样参数——Jev 不是聊天模型,没有这些概念。
以下脚本即本教程的 01_hello_jev.py,完整内嵌于此,拷出即可运行(pip install requests):
# 01_hello_jev.py —— 第一个 Jev 调用(原生 REST,零 SDK 依赖) import json import os import sys import requests API_URL = "https://api.typesafe.ai/v1/systemone" def main() -> None: api_key = os.environ.get("TYPESAFE_API_KEY") if not api_key: sys.exit("请先设置环境变量 TYPESAFE_API_KEY(console.typesafe.ai 申请)") payload = { "model": "jev-latest", # state:模型看到的"程序状态",这里是客服工单原文 "state": ( "Hi, I've been trying to connect my Stripe account for 3 days now " "and customers can't pay. This is costing me money every hour." ), # questions:你起名的问题 ID(不发给模型),每个问题一个类型 "questions": { "is_urgent": { "type": "noul", # 是非题:返回命题为真的概率 # 指令写"判别标准",命题方向 = 高概率代表"是" "instructions": "The message conveys urgency or time-sensitivity", } }, } resp = requests.post( API_URL, headers={"Authorization": f"Bearer {api_key}"}, json=payload, timeout=10, ) resp.raise_for_status() result = resp.json() print(json.dumps(result, indent=2, ensure_ascii=False)) # Noul 的答案字段就是 noul(0~1 概率),没有 confidence urgency = result["answers"]["is_urgent"]["noul"] if urgency > 0.8: print(f"\n>>> 紧急(p={urgency:.3f}):插队到队首并通知值班人员") elif urgency > 0.5: print(f"\n>>> 偏紧急(p={urgency:.3f}):优先处理") else: print(f"\n>>> 不紧急(p={urgency:.3f}):常规排队") if __name__ == "__main__": main()
答案按 answers → 问题ID → 类型字段 三层寻址:
result["answers"]["is_urgent"]["noul"] # Noul → 概率 result["answers"]["route"]["choice"] # Choice → 胜出项 result["answers"]["route"]["probabilities"] # Choice → 全选项分布 result["answers"]["severity"]["score"] # Score → 加权连续分
问题 ID 是你在请求里起的——它不发给模型,只是你代码里的变量名。这就是"Jev 是函数调用"的直接体现:请求是参数,响应是带名字的返回值。
分支逻辑的写法就是普通的 if——概率作为工程契约直接进不等式(第 5 章展开"为什么敢这么写"):
if urgency > 0.8: # 校准含义:长期来看 ~80% 以上命中时才走这条路 ...
💡 排障提示:401 查 Key;422 拿响应体里的校验错误对照附录 B(最常见的 422 是 Choice 忘写 criteria);429/529 指数退避重试即可——调用是纯函数,重试无副作用。
answers.问题ID.类型字段;问题 ID 是你的变量名。if 不等式;裸 REST 是一切封装的排障底线。协议看懂了,日常开发不必每次手写 HTTP——4.2 节换成官方 SDK,让类型系统帮你守住字段名。