koach 开发者文档

对话与向量

L1 的两个核心接口。结构与 OpenAI 一致,可以直接复用现有代码; 差异集中在 koach_ 前缀的几个扩展字段上,它们是这套 API 在运动健康场景里 真正有别于通用模型的地方。

创建对话

POST /v1/chat/completions 支持 SSE 流式

请求参数

参数类型说明
modelstring必填 模型 ID 或版本号,见型号清单
messagesarray必填 对话历史。每项含 rolesystem / user / assistant / tool)与 content
streamboolean默认 false 开启后以 SSE 逐帧返回,usage 只在最后一帧给出
temperaturenumber默认 0.7 0 到 2。训练计划、数据解读这类要求稳定的任务建议 0.2 以下
top_pnumber默认 1 核采样。与 temperature 二选一调整,不建议同时改
max_tokensinteger选填 输出上限。不传时由模型自行决定,上限为该型号的上下文余量
stopstring | array选填 最多 4 个停止序列
response_formatobject选填 {"type":"json_object"} 强制 JSON 输出; {"type":"json_schema","json_schema":{…}} 按 schema 约束
toolsarray选填 可供模型调用的函数定义,格式与 OpenAI 一致
tool_choicestring | object默认 auto none / auto / required,或指定某个函数
userstring选填 你侧的终端用户标识,用于滥用监测。不要传身份证号、手机号等个人敏感信息

运动健康扩展参数

这几个字段是 koach 独有的。用标准 OpenAI SDK 时通过 extra_body (Python)或直接放进请求体(Node / HTTP)传入。

参数类型说明
koach_profilestring选填 用户在记忆大脑里的 ID。 传入后模型会结合该用户的训练历史、身体状况与目标作答
koach_safetystring默认 standard 医疗边界策略。standard 常规;strict 更保守, 触及伤病即建议就医;research 仅限已签署额外协议的科研客户
koach_citeboolean默认 true 是否在响应的 koach.knowledge_refs 里返回引用的知识条目
koach_unitsstring默认 metric metric 公制(公里 / 公斤)或 imperial 英制(英里 / 磅)。 出海产品需要显式指定
koach_safety 不能关闭

没有「关闭安全边界」这个选项。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": "本周为减量周,长距离缩短"}
      ]
    }
注意最后一条的 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

创建向量

POST /v1/embeddings 1024 维

keepace-embedding 是在运动健康语料上训练的,对这个领域里的近义表达 比通用向量模型敏感得多 —— 比如「岔气」「侧腹痛」「跑步时肋下疼」会落在相近的位置, 而通用模型往往把它们分得很开。

参数类型说明
modelstring必填 固定为 keepace-embedding
inputstring | array必填 待向量化的文本,单次最多 512 条
encoding_formatstring默认 float floatbase64。后者体积更小,适合大批量传输
dimensionsinteger默认 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"}},
            ],
        }],
    )
动作分析建议走 Skill 而不是裸模型

直接问 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 是一句可以直接展示给用户的话术, 比你自己写「抱歉我无法回答」体验好很多。

本页内容属于 koach 商业化合作方案的一部分。接口定义可能在正式签约前调整, 以合同附件中的版本为准。

koach · AI by Keep 隐私政策 用户协议 联系我们