koach 开发者文档

Agent 与记忆

Agent Harness 是 L2 的工程底座:多轮编排、工具调用、任务规划和可观测性开箱即用。 它最重要的部分是记忆大脑 —— 让 Agent 记住这个用户练了多久、伤过哪里、 上次为什么中断。没有这层记忆,Agent 就只是个每次都从头认识你的聊天框。

Agent 跑在你的品牌下

这套接口的所有产出物都属于你:用户关系、会话数据、记忆内容。 Keep 提供模型、组件和工程能力,不在你的产品里出现署名, 也不把你的用户数据用于我们自己的模型训练。这是写进合同的。

创建 Agent

POST /v1/agents

Agent 是一份可复用的配置:人设、可用的 Skill、可调用的你侧函数、记忆策略与安全边界。 创建一次,之后靠 agent_id 反复发起会话。

参数类型说明
namestring必填 Agent 名称,仅用于你自己识别
modelstring必填 驱动模型,可以是微调后的模型
instructionsstring必填 人设与行为准则。会在每轮自动注入,命中上下文缓存
skillsarray选填 允许该 Agent 自主调用的 Skill ID 列表
toolsarray选填 你侧的函数定义,格式同 tool calling
memoryobject选填 记忆策略,见下一节
safetystring默认 standard koach_safety
max_stepsinteger默认 8 单次运行的最大工具调用轮数,防止失控循环
agent = client.agents.create(
        name="晨跑营教练",
        model="ft:keepace-lite:acme:morning-run-v2:9dK2",
        instructions=(
            "你是「晨跑营」的带队教练,说话简短直接,不用感叹号。"
            "用户问训练相关的问题时,先查他最近的训练数据再回答。"
            "涉及伤病时不要自己判断,引导到线下门诊。"
        ),
        skills=[
            "training.plan.generate",
            "metrics.interpret",
            "injury.risk.screen",
        ],
        tools=[{
            "type": "function",
            "function": {
                "name": "get_camp_schedule",
                "description": "查询晨跑营本周的线下活动安排",
                "parameters": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        }],
        memory={"mode": "auto", "retention_days": 365},
        max_steps=6,
    )
    print(agent.id)   # agt_01JQ9K3R6W

发起运行

POST /v1/agents/{agent_id}/runs 支持 SSE 流式

一次 run 是一个完整的「用户说了一句话 → Agent 可能调用若干工具 → 给出最终回答」的过程。 Harness 负责编排,你不需要自己写工具调用循环。

run = client.agents.runs.create(
        agent_id="agt_01JQ9K3R6W",
        profile="usr_8f2a41",           # 关联记忆大脑
        thread="thr_weekly_checkin",     # 会话线程,用于多轮
        input="这周状态感觉一般,要不要减量?",
    )

    print(run.output_text)
    for step in run.steps:
        print(step.type, step.name, step.duration_ms)
curl "$KOACH_BASE_URL/agents/agt_01JQ9K3R6W/runs" \
      -H "Authorization: Bearer $KOACH_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "profile": "usr_8f2a41",
        "thread": "thr_weekly_checkin",
        "input": "这周状态感觉一般,要不要减量?"
      }'
{
      "id": "run_01JQ9M8T2X",
      "agent_id": "agt_01JQ9K3R6W",
      "thread": "thr_weekly_checkin",
      "status": "completed",
      "output_text": "该减。你连续三周加量,这周主观感觉下滑基本是累积疲劳,不是状态问题。\n这周把跑量砍到 24 公里,速度课只留一次,周日长距离缩到 8 公里。下周再看。",
      "steps": [
        {"type": "memory.read",  "name": "profile",              "duration_ms": 34},
        {"type": "skill",        "name": "metrics.interpret",    "duration_ms": 812,
         "summary": "近四周负荷 28 / 31 / 34 公里递增,HRV 较基线下降 12%"},
        {"type": "skill",        "name": "injury.risk.screen",   "duration_ms": 640,
         "summary": "急慢性负荷比 1.38,处于偏高区间"},
        {"type": "model",        "name": "final",                "duration_ms": 1420}
      ],
      "usage": {"tokens": 3210, "skill_calls": 2},
      "request_id": "req_01JQ9M8T2X"
    }
steps 是可观测性的核心

它记录了 Agent 这一轮到底查了什么、调了哪些 Skill、各花了多久。 排查「为什么它给了这个答案」时,先看 steps 而不是猜提示词。 控制台里有同样内容的可视化时间线。

流式运行

stream: true 后按事件推送。与纯模型流式不同, 这里会先推工具调用事件,让你可以在界面上显示「正在查看你的训练记录…」 这类中间状态,避免用户面对几秒钟的空白。

event: run.step.started
    data: {"type":"skill","name":"metrics.interpret","label":"正在分析最近四周的训练数据"}

    event: run.step.completed
    data: {"type":"skill","name":"metrics.interpret","duration_ms":812}

    event: run.output.delta
    data: {"delta":"该减。你连续三周加量,"}

    event: run.output.delta
    data: {"delta":"这周主观感觉下滑基本是累积疲劳,"}

    event: run.completed
    data: {"id":"run_01JQ9M8T2X","usage":{"tokens":3210,"skill_calls":2}}

查询运行

GET /v1/agents/{agent_id}/runs/{run_id}

运行记录保留 30 天(私有化下由你自己配置)。可用于事后审计、 质量抽检和构造微调数据。

记忆大脑

这是 Harness 里最难自己造、也最影响体验的部分。 它不是把历史对话原样塞回上下文 —— 那样几轮之后就爆了,而且噪音大于信号。 记忆大脑做的是结构化提炼:从训练数据、对话和行为里抽出稳定的用户事实, 按相关性在需要时召回。

三层记忆

档案(profile)
稳定属性:年龄段、体重区间、训练年限、既往伤病、长期目标、禁忌。 变化慢,每次调用都会注入
事件(events)
时序记录:每次训练、每次打卡、每次主诉。 不全量注入,按当前问题的相关性召回
洞察(insights)
系统自动提炼的中期结论,如「周三晚上的课经常缺席」 「一提到力量训练就回避」。这类信息用户自己不会说, 但对留存和转化影响很大

写入档案

PUT /v1/memory/{profile_id}/profile
client.memory.profile.update(
        "usr_8f2a41",
        data={
            "demographics": {"age_band": "30-34", "sex": "male", "height_cm": 176},
            "body":  {"weight_kg": 71.5, "resting_hr": 52},
            "history": {
                "training_years": 4,
                "injuries": [
                    {"site": "achilles_right", "year": 2024, "status": "recovered"}
                ],
            },
            "goals": [
                {"type": "race", "event": "marathon",
                 "date": "2026-10-18", "target_time_min": 230}
            ],
            "preferences": {"time_of_day": "morning", "dislikes": ["treadmill"]},
        },
    )

追加事件

POST /v1/memory/{profile_id}/events

把你侧已有的训练数据同步进来。支持批量,单次最多 500 条。 这一步做得越全,Agent 的回答就越像个真的认识用户的教练。

client.memory.events.append("usr_8f2a41", events=[
        {
            "type": "workout",
            "at": "2026-08-16T06:12:00+08:00",
            "data": {"sport": "running", "distance_km": 12.4,
                     "duration_s": 3720, "avg_hr": 156, "rpe": 7},
        },
        {
            "type": "note",
            "at": "2026-08-16T07:05:00+08:00",
            "data": {"text": "右脚踝有点紧,跑完拉伸了十分钟"},
        },
    ])

读取与召回

GET /v1/memory/{profile_id}/summary

多数情况下你不需要手动读取 —— 传 profile 给 Agent 或 Skill 时 会自动召回。这个接口主要用于在你自己的界面上展示「教练眼中的我」, 以及满足用户的知情权与查阅权要求。

{
      "profile_id": "usr_8f2a41",
      "updated_at": "2026-08-17T09:20:11+08:00",
      "profile": { "…": "同写入结构" },
      "insights": [
        {
          "text": "近四周负荷持续递增,急慢性负荷比升至 1.38,处于受伤风险偏高区间",
          "confidence": 0.88,
          "evidence": ["evt_9c21", "evt_9d04", "evt_9e77"],
          "generated_at": "2026-08-17T05:00:00+08:00"
        },
        {
          "text": "多次在计划包含跑步机课程时改期,明确偏好户外",
          "confidence": 0.74,
          "evidence": ["evt_8a12", "evt_8f33"]
        }
      ],
      "stats": {"events_total": 412, "first_event_at": "2024-11-02"}
    }

删除

DELETE /v1/memory/{profile_id}
这个接口你必须接

《个人信息保护法》规定用户有权要求删除其个人信息。 你的产品里需要有对应的入口,并在收到请求后调用这个接口。 删除是硬删除,包括档案、事件与洞察,不可恢复, 执行结果会写入审计日志备查。

client.memory.delete("usr_8f2a41", reason="user_request")

可观测性

Harness 自带的埋点覆盖每一次 run 的完整链路。除了控制台看板, 也可以把事件推到你自己的系统:

方式说明
控制台看板 成功率、P50 / P95 延迟、Skill 调用分布、token 消耗、安全边界触发次数
Webhook run 完成 / 失败 / 触发安全边界时回调你的地址,用于告警与工单
OpenTelemetry 导出为标准 OTLP,接进你现有的 APM。私有化部署下这是默认方式
日志导出 按天导出结构化日志到你的对象存储,用于离线分析与构造微调数据

私有化差异

Harness 与记忆大脑都可以完整部署在客户环境内。接口一致,有三点需要注意:

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

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