跳到主要内容

2 篇博文 含有标签「schema-evolution」

查看所有标签

智能体记忆 Schema 演进:Protobuf 的困难模式

· 阅读需 12 分钟
Tian Pan
Software Engineer

第一次痛苦的智能体记忆(agent-memory)迁移总是教会我们同一个教训:存在两个模式(schema),而你只迁移了其中一个。存储层没问题 —— 每一行都已重写,每个键(key)都是新的形态,回填(backfill)作业也记录了成功。但智能体还是坏了。它继续向 user.preferences.theme 写入,却检索不到任何内容,然后从上下文中煞有介事地合成一个默认值,就好像这个键从未存在过一样。迁移操作手册显示一切正常。用户却报告记忆过时。

这种不对称是结构性的。一个依赖于重命名列的传统服务会收到硬错误,然后你进行修复。而一个依赖于重命名记忆键的智能体则会遇到软缺失,并围绕它进行胡编乱造。模式存在于两个地方 —— 你的存储和模型的上下文 —— 而你只能通过 SQL 脚本迁移其中的一个。

Protobuf 在二十年前通过规范化“仅限增加”的准则解决了这类问题的一个变体:字段是永恒的,数字是永恒的,网络类型永远不变,删除被弃用(deprecation)所取代。这一准则是智能体记忆的一个良好起点,但有一个额外的约束使其变得更加困难。Protobuf 接收者在设计上会忽略未知字段。智能体则不会。

工具 Schema 弃用:为什么你不能直接重命名参数

· 阅读需 13 分钟
Tian Pan
Software Engineer

你在一个工具 schema 中将 query 重命名为 search_query。变更日志写着:“非破坏性更名:更清晰的命名”。PR 通过了评审。三天后,你的支持队列里塞满了关于助手“搜索结果为空”的报告。发生的事情并不是讨论帖里任何人会告诉你的。智能体(Agent)并没有失败。它们提交了旧的字段名称,你的工具服务器忽略了未知的 key,将 search_query 默认设置为空字符串,并返回了零条结果。模型看到一个看起来很正常的空响应,便自信地向用户解释为什么他们的查询没有返回任何相关内容。

这是智能体工程(Agent Engineering)中不符合从 REST API 版本管理借鉴来的心理模型的部分。发送已重命名字段的 REST 客户端会收到 400 错误和清晰的报错——该字段要么存在于验证器中,要么不存在。而发送已重命名字段的智能体得到的则是静默接受、一个毫无意义的结果以及一段幻觉式的合理解释。失败不在于线路传输(the wire);而在于运行时 schema 与模型关于工具外观的上下文心理模型(in-context mental model)之间的脱节。

工具 schema 存在于两个地方。第一个是运行时规范(runtime spec)——即你发布到 MCP 服务器或函数调用注册表的 JSON schema。第二个是该规范在模型中的上下文表示,它通过系统提示词(system prompt)中的 few-shot 示例、智能体在多轮任务中看到的序列化工具历史记录,以及模型在预训练期间已经吸收的关于你 API 的知识来在每一轮对话中不断强化。你可以原子化地更新前者,但你无法原子化地更新后者。这种不对称性就是问题的核心,这也是为什么“仅限添加,永久保留”——protobuf 和 GraphQL 运营商在十年前就已经内化的原则——现在需要迁移到工具 schema 层了。