对话与向量
L1 的两个核心接口。结构与 OpenAI 一致,可以直接复用现有代码;
差异集中在 koach_ 前缀的几个扩展字段上,它们是这套 API 在运动健康场景里
真正有别于通用模型的地方。
创建对话
请求参数
| 参数 | 类型 | 说明 | |
|---|---|---|---|
model | string | 必填 | 模型 ID 或版本号,见型号清单 |
messages | array | 必填 | 对话历史。每项含 role(system /
user / assistant / tool)与 content |
stream | boolean | 默认 false | 开启后以 SSE 逐帧返回,usage 只在最后一帧给出 |
temperature | number | 默认 0.7 | 0 到 2。训练计划、数据解读这类要求稳定的任务建议 0.2 以下 |
top_p | number | 默认 1 | 核采样。与 temperature 二选一调整,不建议同时改 |
max_tokens | integer | 选填 | 输出上限。不传时由模型自行决定,上限为该型号的上下文余量 |
stop | string | array | 选填 | 最多 4 个停止序列 |
response_format | object | 选填 | {"type":"json_object"} 强制 JSON 输出;
{"type":"json_schema","json_schema":{…}} 按 schema 约束 |
tools | array | 选填 | 可供模型调用的函数定义,格式与 OpenAI 一致 |
tool_choice | string | object | 默认 auto | none / auto / required,或指定某个函数 |
user | string | 选填 | 你侧的终端用户标识,用于滥用监测。不要传身份证号、手机号等个人敏感信息 |
运动健康扩展参数
这几个字段是 koach 独有的。用标准 OpenAI SDK 时通过 extra_body
(Python)或直接放进请求体(Node / HTTP)传入。
| 参数 | 类型 | 说明 | |
|---|---|---|---|
koach_profile | string | 选填 | 用户在记忆大脑里的 ID。 传入后模型会结合该用户的训练历史、身体状况与目标作答 |
koach_safety | string | 默认 standard | 医疗边界策略。standard 常规;strict 更保守,
触及伤病即建议就医;research 仅限已签署额外协议的科研客户 |
koach_cite | boolean | 默认 true | 是否在响应的 koach.knowledge_refs 里返回引用的知识条目 |
koach_units | string | 默认 metric | metric 公制(公里 / 公斤)或 imperial 英制(英里 / 磅)。
出海产品需要显式指定 |
没有「关闭安全边界」这个选项。research 也只是放宽了对训练强度极值的
讨论范围,涉及诊断与用药的问题在任何模式下都会拒答。
这条边界写进了合同的责任条款,不是可配置项。
示例:结构化输出一份训练计划
产品里要把计划渲染成卡片,就需要稳定的 JSON。用 response_format
配合低 temperature:
resp = client.chat.completions.create(
model="keepace-pro",
temperature=0.1,
messages=[
{"role": "system", "content": "你是训练计划编排引擎,只输出 JSON。"},
{"role": "user", "content": "为一位周跑量 30 公里的跑者安排下一周训练。"},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "weekly_plan",
"schema": {
"type": "object",
"properties": {
"week_load_km": {"type": "number"},
"sessions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"day": {"type": "string"},
"type": {"type": "string",
"enum": ["easy", "tempo", "interval", "long", "rest"]},
"distance_km": {"type": "number"},
"note": {"type": "string"},
},
"required": ["day", "type", "distance_km"],
},
},
},
"required": ["week_load_km", "sessions"],
},
},
},
extra_body={"koach_profile": "usr_8f2a41"},
)
curl "$KOACH_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KOACH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "keepace-pro",
"temperature": 0.1,
"messages": [
{"role": "system", "content": "你是训练计划编排引擎,只输出 JSON。"},
{"role": "user", "content": "为一位周跑量 30 公里的跑者安排下一周训练。"}
],
"response_format": {"type": "json_object"},
"koach_profile": "usr_8f2a41"
}'
{
"week_load_km": 33,
"sessions": [
{"day": "周一", "type": "rest", "distance_km": 0, "note": "完全休息"},
{"day": "周二", "type": "easy", "distance_km": 6, "note": "配速比轻松跑再慢 15 秒"},
{"day": "周三", "type": "interval", "distance_km": 8, "note": "6 × 800 米,组间慢跑 2 分钟"},
{"day": "周四", "type": "rest", "distance_km": 0, "note": "可做 20 分钟核心"},
{"day": "周五", "type": "easy", "distance_km": 6, "note": "保持心率在 2 区"},
{"day": "周六", "type": "tempo", "distance_km": 8, "note": "含 4 公里节奏跑"},
{"day": "周日", "type": "long", "distance_km": 5, "note": "本周为减量周,长距离缩短"}
]
}
「本周为减量周」这个判断来自 koach_profile —— 模型看到该用户已经连续
三周加量,主动安排了减量。不传 profile 时它只会按通用规则线性递增,
这正是垂类模型加记忆带来的差别。
示例:让模型调用你自己的函数
常见需求是让模型去查你侧的数据(会员等级、课程库存、设备状态)。 用标准的 tool calling:
tools = [{
"type": "function",
"function": {
"name": "get_recent_runs",
"description": "查询用户最近若干次跑步记录",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string"},
"limit": {"type": "integer", "description": "返回条数,默认 5"},
},
"required": ["user_id"],
},
},
}]
resp = client.chat.completions.create(
model="keepace-pro",
messages=[{"role": "user", "content": "我最近状态怎么样?"}],
tools=tools,
)
call = resp.choices[0].message.tool_calls[0]
print(call.function.name) # get_recent_runs
print(call.function.arguments) # {"user_id": "usr_8f2a41", "limit": 5}
拿到调用意图后自己执行,把结果以 role: "tool" 追加进 messages 再请求一次,
模型就会基于真实数据作答。完整的两轮流程见
示例 Demo。
创建向量
keepace-embedding 是在运动健康语料上训练的,对这个领域里的近义表达
比通用向量模型敏感得多 —— 比如「岔气」「侧腹痛」「跑步时肋下疼」会落在相近的位置,
而通用模型往往把它们分得很开。
| 参数 | 类型 | 说明 | |
|---|---|---|---|
model | string | 必填 | 固定为 keepace-embedding |
input | string | array | 必填 | 待向量化的文本,单次最多 512 条 |
encoding_format | string | 默认 float | float 或 base64。后者体积更小,适合大批量传输 |
dimensions | integer | 默认 1024 | 可降维到 512 或 256,检索精度略降但存储成本明显下降 |
emb = client.embeddings.create(
model="keepace-embedding",
input=["跑步时右侧肋下疼", "如何缓解岔气", "深蹲膝盖内扣怎么办"],
)
for item in emb.data:
print(item.index, len(item.embedding)) # 0 1024 / 1 1024 / 2 1024
curl "$KOACH_BASE_URL/embeddings" \
-H "Authorization: Bearer $KOACH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "keepace-embedding",
"input": ["跑步时右侧肋下疼", "如何缓解岔气", "深蹲膝盖内扣怎么办"]
}'
{
"object": "list",
"model": "keepace-embedding-20260401",
"data": [
{"object": "embedding", "index": 0, "embedding": [0.0121, -0.0384, 0.0917, "…"]},
{"object": "embedding", "index": 1, "embedding": [0.0118, -0.0351, 0.0903, "…"]},
{"object": "embedding", "index": 2, "embedding": [-0.0442, 0.0219, -0.0176, "…"]}
],
"usage": {"prompt_tokens": 34, "total_tokens": 34}
}
图像输入
keepace-vision 接受图像,用于动作与体态分析、饮食识别、器械识别。
图像放进 content 数组,支持 URL 或 base64:
resp = client.chat.completions.create(
model="keepace-vision",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "看看这个深蹲的姿势有什么问题"},
{"type": "image_url",
"image_url": {"url": "https://cdn.example.com/squat.jpg", "detail": "high"}},
],
}],
)
直接问 vision 模型拿到的是一段描述性文字。如果你要的是结构化的关节角度、
风险等级和纠正建议,用
motion.form.analyze
这个 Skill,它在 vision 模型之上封装了姿态估计与评分规则。
错误处理
本页所有接口共用同一套错误结构与重试建议,见 错误码与重试。 这里只强调一个运动健康场景特有的:
{
"error": {
"type": "safety_error",
"code": "safety_boundary_triggered",
"message": "请求涉及疾病诊断,已按医疗边界策略拒绝。",
"param": "messages[1].content",
"request_id": "req_01JQ8B4N2P",
"koach": {
"boundary": "medical.diagnosis",
"suggested_reply": "这个情况建议你到运动医学门诊做一次面诊,我可以先帮你准备一份要跟医生说明的训练史。"
}
}
}
遇到这个错误不要当成失败重试,它是预期行为。
koach.suggested_reply 是一句可以直接展示给用户的话术,
比你自己写「抱歉我无法回答」体验好很多。