托管 AI Agent 上线前的判断口径,不是“平台能不能替我存”,而是“这份状态丢了以后,我还能不能把会话接回来、能不能说清谁在什么时候调用了什么工具”。按会话历史、工具调用入参与返回、长期记忆与向量、密钥与令牌、运行日志这五类分开看,通常前三类托管侧会默认保存一份,密钥和审计向的日志建议自己持有一份。先分类列全,再逐项到控制台核对默认行为,最后发一次真实调用核对落点。
托管平台一般会保存会话与调用记录,但这不等于你可以不存。判断口径:涉及密钥、审计追溯、跨平台迁移、以及需要长期保留的向量索引的状态,建议自己持有一份,托管侧只当作运行期副本。别靠猜,先用一次带工具调用的请求看清每条状态实际写到了哪,再写成一页责任表,上线后按表复查。适用场景是单 Agent 或多个工具并行调用;边界是平台行为随版本变化,结论需要结合你当前环境重新确认。
列出 Agent 运行时产生的全部状态类型
先把分类对象定死,避免漏项。建议按“谁产生、多久写一次、多久读一次、泄露或丢失的后果”四个字段来记,形成一份可复用的清单模板:
{
"name": "会话历史",
"produced_at": "每轮用户消息与模型回复后追加",
"write_freq": "每轮",
"read_freq": "每轮 + 排障时回放",
"sensitivity": "中(可能含用户隐私)",
"restore_required": true,
"hosted_default_known": false
}五类状态的产生时机与读写特征,可以先这样归:
| 状态类型 | 产生时机 | 典型读写频率 | 敏感级别 |
|---|---|---|---|
| 会话历史 | 每轮消息后追加 | 每轮读写 | 中 |
| 工具调用入参与返回 | 模型决定调用工具、工具返回时 | 每次调用读写 | 中到高(常含业务数据) |
| 长期记忆 / 向量 | 写入记忆、重建索引时 | 读多写少 | 中到高 |
| 密钥与令牌 | 初始化、轮换时 | 读频繁、写极少 | 高 |
| 运行日志 | 每次请求、异常、重试时 | 持续写、按需读 | 中(可能含参数片段) |
模板里的 hosted_default_known 先留 false,等下一步在控制台核对后再改,这样清单本身就能反映“哪些项还是未知”。
在控制台资源页确认托管侧默认保存哪些对象
不要凭印象判断平台默认行为。打开控制台的资源或存储相关页面,逐项对照:有没有会话记录、有没有对象/文件存储、有没有向量索引或记忆条目、有没有日志检索入口、环境变量或密钥是怎么配置的。每一项都记下两件事:默认是否开启,保留策略写的是什么。
- 能看到的项:记录页面路径、默认保留时长、是否可导出。
- 看不到的项:单独记成一列“平台未提供”,避免后面误以为已经存了。
- 只写结论会丢细节,建议用“页面位置 + 观察到的字段”两列记录,方便版本变化后复查。
这一轮核对完成后,把清单模板里的 hosted_default_known 逐项改成 true 或 false,责任边界就有了第一版事实基础。
用配置示例把密钥改为启动时从外部读取
密钥是最不该写进托管配置的值。通用做法是启动时从环境变量读取,代码里只出现变量名。下面的骨架与具体平台接口无关,可直接替换变量名后使用:
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 的状态"}'调用完成后,按两侧对照来核对:
- 请求输入侧:这条消息是否出现在托管侧的会话记录里,出现的位置和格式是什么。
- 预期写入位置:工具入参与返回应落在你自己那侧还是托管侧,清单里当初是怎么写的。
- 自有存储侧:自己的库或日志里是否真的多了这条记录,字段是否完整。
- 平台记录侧:托管控制台里能否用 request_id 检索到同一次调用。
只要有一侧对不上,说明归属判断需要修正,改完清单再重跑一次。这一步的价值在于把“以为”变成“看到”。
把结论写成一页责任表
最后把清单和核对结果收敛成一张表,作为上线决策依据。表列固定为:状态类型、存放位置、读取方、保留时长、失效后的处理动作。
| 状态类型 | 存放位置 | 读取方 | 保留时长 | 失效后的处理动作 |
|---|---|---|---|---|
| 会话历史 | 自建库 + 托管副本 | Agent、排障人员 | 按业务与合规确认后填写 | 从自建库回放,重建会话上下文 |
| 工具调用入参与返回 | 自建审计表 | 审计、排障人员 | 按合规要求填写 | 以自建审计记录为准,托管侧缺失不阻塞 |
| 长期记忆 / 向量 | 自建向量库 | 检索链路 | 按业务需要填写 | 从原始记忆条目重建索引 |
| 密钥与令牌 | 外部密钥管理,启动时注入 | 运行时进程 | 按轮换周期填写 | 轮换新值并重启,旧值立即作废 |
| 运行日志 | 自建日志存储 + 平台日志 | 排障人员 | 按排障需要填写 | 以自建日志为准,缺平台侧时缩短排查范围 |
表里凡是写“待确认”的格,上线前都应有明确结论;写不出结论的,就先按“自己存一份”处理,这是成本较低也较稳的选择。托管平台的行为可能随版本调整,建议把这张表连同核对日期一起放在团队文档里,每次升级后按同样的请求重跑一遍落点核对。