Qoni 托管 AI Agent 上线前,先分清哪些状态必须自己存

文章导读
托管 AI Agent 上线前的判断口径,不是“平台能不能替我存”,而是“这份状态丢了以后,我还能不能把会话接回来、能不能说清谁在什么时候调用了什么工具”。按会话历史、工具调用入参与返回、长期记忆与向量、密钥与令牌、运行日志这五类分开看,通常前三类托管侧会默认保存一份,密钥和审计向的日志建议自己持有一份。先分类列全,再逐项到控制台核对默认行为,最后发一次真实调用核对落点。
📋 目录
  1. 壹 列出 Agent 运行时产生的全部状态类型
  2. 贰 在控制台资源页确认托管侧默认保存哪些对象
  3. 叁 用配置示例把密钥改为启动时从外部读取
  4. 肆 发一次带工具调用的请求,核对状态落点
  5. 伍 把结论写成一页责任表
A A

托管 AI Agent 上线前的判断口径,不是“平台能不能替我存”,而是“这份状态丢了以后,我还能不能把会话接回来、能不能说清谁在什么时候调用了什么工具”。按会话历史、工具调用入参与返回、长期记忆与向量、密钥与令牌、运行日志这五类分开看,通常前三类托管侧会默认保存一份,密钥和审计向的日志建议自己持有一份。先分类列全,再逐项到控制台核对默认行为,最后发一次真实调用核对落点。

托管平台一般会保存会话与调用记录,但这不等于你可以不存。判断口径:涉及密钥、审计追溯、跨平台迁移、以及需要长期保留的向量索引的状态,建议自己持有一份,托管侧只当作运行期副本。别靠猜,先用一次带工具调用的请求看清每条状态实际写到了哪,再写成一页责任表,上线后按表复查。适用场景是单 Agent 或多个工具并行调用;边界是平台行为随版本变化,结论需要结合你当前环境重新确认。

列出 Agent 运行时产生的全部状态类型

先把分类对象定死,避免漏项。建议按“谁产生、多久写一次、多久读一次、泄露或丢失的后果”四个字段来记,形成一份可复用的清单模板:

{
  "name": "会话历史",
  "produced_at": "每轮用户消息与模型回复后追加",
  "write_freq": "每轮",
  "read_freq": "每轮 + 排障时回放",
  "sensitivity": "中(可能含用户隐私)",
  "restore_required": true,
  "hosted_default_known": false
}

五类状态的产生时机与读写特征,可以先这样归:

状态类型产生时机典型读写频率敏感级别
会话历史每轮消息后追加每轮读写中
工具调用入参与返回模型决定调用工具、工具返回时每次调用读写中到高(常含业务数据)
长期记忆 / 向量写入记忆、重建索引时读多写少中到高
密钥与令牌初始化、轮换时读频繁、写极少高
运行日志每次请求、异常、重试时持续写、按需读中(可能含参数片段)

模板里的 hosted_default_known 先留 false,等下一步在控制台核对后再改,这样清单本身就能反映“哪些项还是未知”。

Qoni 托管 AI Agent 上线前,先分清哪些状态必须自己存

在控制台资源页确认托管侧默认保存哪些对象

不要凭印象判断平台默认行为。打开控制台的资源或存储相关页面,逐项对照:有没有会话记录、有没有对象/文件存储、有没有向量索引或记忆条目、有没有日志检索入口、环境变量或密钥是怎么配置的。每一项都记下两件事:默认是否开启,保留策略写的是什么。

  • 能看到的项:记录页面路径、默认保留时长、是否可导出。
  • 看不到的项:单独记成一列“平台未提供”,避免后面误以为已经存了。
  • 只写结论会丢细节,建议用“页面位置 + 观察到的字段”两列记录,方便版本变化后复查。

这一轮核对完成后,把清单模板里的 hosted_default_known 逐项改成 true 或 false,责任边界就有了第一版事实基础。

用配置示例把密钥改为启动时从外部读取

密钥是最不该写进托管配置的值。通用做法是启动时从环境变量读取,代码里只出现变量名。下面的骨架与具体平台接口无关,可直接替换变量名后使用:

Qoni 托管 AI Agent 上线前,先分清哪些状态必须自己存
import os

REQUIRED = ["AGENT_MODEL_KEY", "TOOL_API_TOKEN"]

def load_config():
    missing = [k for k in REQUIRED if not os.environ.get(k)]
    if missing:
        raise RuntimeError("missing env: " + ", ".join(missing))
    return {k: os.environ[k] for k in REQUIRED}

def mask(v):
    return v[:2] + "*" * 6 + v[-2:] if len(v) > 4 else "****"

for k, v in load_config().items():
    print(k, mask(v))

验证方式:启动后看输出是否只有脱敏值;再回控制台的配置页和 Agent 提示词里搜一遍密钥明文,确认没有残留。如果平台支持“引用密钥名称”而不是填值,优先用引用方式。注意密钥不要出现在工具描述、示例提示词和日志打印里,这是容易被忽略的泄露路径。

发一次带工具调用的请求,核对状态落点

配置改完之后必须用一次真实调用验证,而不是看文档推断。请求输入建议包含:一条用户消息、一个会触发工具调用的意图、一个可识别的标记值(例如自定义 request_id)。

curl -s -X POST "$AGENT_ENDPOINT" \
  -H "Authorization: Bearer $AGENT_MODEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"request_id":"chk-001","message":"调用工具查询订单 chk-001 的状态"}'

调用完成后,按两侧对照来核对:

Qoni 托管 AI Agent 上线前,先分清哪些状态必须自己存
  • 请求输入侧:这条消息是否出现在托管侧的会话记录里,出现的位置和格式是什么。
  • 预期写入位置:工具入参与返回应落在你自己那侧还是托管侧,清单里当初是怎么写的。
  • 自有存储侧:自己的库或日志里是否真的多了这条记录,字段是否完整。
  • 平台记录侧:托管控制台里能否用 request_id 检索到同一次调用。

只要有一侧对不上,说明归属判断需要修正,改完清单再重跑一次。这一步的价值在于把“以为”变成“看到”。

把结论写成一页责任表

最后把清单和核对结果收敛成一张表,作为上线决策依据。表列固定为:状态类型、存放位置、读取方、保留时长、失效后的处理动作。

状态类型存放位置读取方保留时长失效后的处理动作
会话历史自建库 + 托管副本Agent、排障人员按业务与合规确认后填写从自建库回放,重建会话上下文
工具调用入参与返回自建审计表审计、排障人员按合规要求填写以自建审计记录为准,托管侧缺失不阻塞
长期记忆 / 向量自建向量库检索链路按业务需要填写从原始记忆条目重建索引
密钥与令牌外部密钥管理,启动时注入运行时进程按轮换周期填写轮换新值并重启,旧值立即作废
运行日志自建日志存储 + 平台日志排障人员按排障需要填写以自建日志为准,缺平台侧时缩短排查范围

表里凡是写“待确认”的格,上线前都应有明确结论;写不出结论的,就先按“自己存一份”处理,这是成本较低也较稳的选择。托管平台的行为可能随版本调整,建议把这张表连同核对日期一起放在团队文档里,每次升级后按同样的请求重跑一遍落点核对。