为什么 ChatGPT 会遗忘你的指标定义
指标名称不等于指标
“毛利率”(Gross margin)这几个字可能代表六种不同的含义。AtScale 在其关于语义漂移成本的报告中,开篇就提到三个团队在回答“我们上季度的毛利率是多少?”时,分别给出了 30%、32% 和 31% 的答案——这是根据对收入成本的不同定义得出的三个完全说得通的数字。
你的助手继承了这种模糊性,却没有继承你对它的解决方案。当你提到“流失率”(churn)时,模型对流失率的一般含义有着强烈的先验认知,但完全不知道你的公司是基于收入而非账户、按月而非按年、且排除降级来衡量流失率的。在没有你的定义的情况下,它会使用先验认知。从狭义上讲,这并不是记忆失效——而是一种表现为自信回答的记忆失效。
定义存在于人脑中,而非数据中
这就是指标定义比模式(schema)更难处理的地方。表有一个你可以检查的形状;模型可以读取列名和类型。而定义是一个决定——在某个时间点,有人决定试用期不计算在内——这个决定被记录在 Slack 线程、仪表板的 SQL 或某个人的脑海中。
行业对此的共识异常直接。正如 AtScale 所说:“AI 系统不仅无法调和冲突的定义,还会通过自信地给出不一致的答案来使问题恶化。” 失败的原因并不是模型发明了数学,而是模型忠实地执行了它恰好重构出的你组织中的某一个定义。
注意这与 ChatGPT 丢失你的数据模式 有何不同。模式丢失会产生你能注意到的错误——不存在的列、失败的连接。而定义丢失会产生无法对账的数字,而你直到开会时才会发现。
没有任何机制能在会话之间传递定义
即使你在一次对话中把定义说对了,也不存在能将这种内容传递下去的机制。内置记忆只能保存几页关于你的简短事实;一个包含九个条款及排除条件的合格管道(qualified pipeline)定义,超出了它的承载范围。自定义指令在挤占其他内容之前,最多只能容纳两三个定义。项目文件有所帮助,但它们仅限于该项目和该工具。
因此,定义只能手动重新提供,这意味着它只能被近似地重新提供。你周四输入的版本比周一的要短,因为你是凭记忆输入的,而排除条件是最无聊的部分。偏差正是通过你自己的总结悄然引入的。
定义会发生变化,且旧版本不会被撤回
更复杂的问题是:你在第三季度修改了定义,而之前的所有分析都是基于第二季度的版本计算的。基于聊天的日常工作流没有地方记录某个定义在某个日期取代了另一个定义。因此,你最终得到的数字是在不同规则下计算出来的,而且没有任何东西能告诉你使用的是哪套规则——这相当于分析领域中没有日期的文档。
人们的尝试
在每次对话的顶部粘贴定义。 这很有效,也是最常见的方法。但它也会退化:几周后粘贴的内容会变短,而且这是针对单个对话的,所以团队中的其他人都在粘贴他们自己的版本。
将定义放入自定义指令中。 对于你每天使用的两三个指标来说,这更好,也确实值得做。但随后空间就会不够用,你把指令额度花在了定义上,而不是你希望助手如何表现上。
使用附加了定义文档的项目(Project)。 这是产品内选项中最好的一个。不过它仅限于该项目,如果你还在编码智能体或 BI 工具中工作,该文档在这些地方是不可见的。
让助手读取 SQL。 聪明且部分有效——定义确实存在于查询中。但它遗漏的是意图和异常情况:SQL 显示了 WHERE status != 'internal' 子句,但没有说明该子句是因为审计结果而存在的,而且它显示的是某个仪表板的版本,却不告诉你这是一个有争议的版本。
构建语义层。 这是真正专业的答案,应该坦率地说:语义层——dbt 的 Semantic Layer、AtScale、Cube 以及该领域的其他工具——的存在正是为了将指标定义一次,并让每个工具以相同的方式进行计算。AtScale 将这一目标描述为:“当有人问‘我们的收入是多少?’时,只有一个答案,因为定义在所有地方都是一致应用的。” 如果你的组织依赖共享指标运行,这就是值得进行的投资,而记忆层并不能替代它。
AtScale 还报告称,直接查询数据库的 LLM 在业务问题上的准确率约为 20%,而当语义层提供受治理的定义、多维业务逻辑和上下文关系时,准确率基本上可以达到 100%。这个数据来自一个与该结论有利益关系的厂商,不应被视为独立的基准测试——但其方向是无可争议的,这也是支持受治理定义的最强有力论据。
语义层无法弥补的差距正是你实际所处的境地:你在下午 6 点将 CSV 粘贴给助手、从未通过建模层的临时问题、作为决定存在但尚未作为指标实施的定义,以及由没有 BI 访问权限的人进行的每一次分析。这正是定义丢失的地方,而这占了实际发生的大部分分析工作。
解决方法:给 ChatGPT 一个持久的指标定义
将定义保留在对话之外,保存在助手在每次请求时都会读取的存储库中。不是你用来复制粘贴的便签,而是一个在回答过程中提供定义的层。
使其发挥作用的不是存储,而是定义伴随着它的上下文一起提供。存储的定义可以包含排除条件、每个排除条件的原因、审批人、上次更改的时间以及以前的版本。这就是“活跃 = 90 天内付款”与一个真正可以让人负责的定义之间的区别。
MemoryLake 就是为此构建的记忆层——将你的定义、决策记录和源文档保存在一个存储库中,ChatGPT 通过 API 读取,而支持 MCP 的工具(如 Claude 和 Codex)则直接读取。因此,相同的定义可以传递到临时对话、编写查询的编码智能体以及上周刚入职的分析师。
明确说明两个界限,因为在这个领域,过度推销会造成真正的损害:
- 记忆层使定义可用、一致且可追溯。它并不强制执行它们。 强制执行是语义层的工作——通过一个定义计算每个查询。记忆层向提问者提供定义;它无法阻止模型被赋予原始表并进行自己的算术计算。如果一个数字要放入董事会简报或申报文件中,它应该通过你的受治理层,而不是来自对话。
- 定义需要它们的元数据,否则你只是转移了问题。 只有指标名称和公式的两列表格正是导致偏差的根源。必须传递的是粒度、时间窗口、排除条件及原因、所有者和生效日期。
步骤 1:创建 API 密钥
生成密钥并在大约 30 秒内发出你的第一次请求。将其保存在你的环境变量或机密管理器中,而不是内联在共享的配置或 notebook 中。

步骤 2:上传你的第一批记忆
放入你定义实际所在的文档、图像和文件——指标文档、仪表板规范、决定排除条件的 Slack 线程、导致该决定的审计记录。上传源文件,而不是整理好的摘要。整理好的摘要往往是“排除内部账户”悄然消失的地方。

步骤 3:连接你的 AI 和智能体
通过 MCP 或 API 授予 Claude、Codex、OpenClaw 和其他 AI 智能体访问记忆的权限。ChatGPT 没有 MCP 客户端,因此需要通过 API 检索相关定义并将其注入到提示词、自定义 GPT 或调用模型的日常工作流中。对于支持 MCP 的工具,将服务器添加到该工具'的配置中,它们就会读取相同的存储库——这就是重点:一个定义,多个消费者。

这在实践中带来了什么改变
周四的数字与周一的相匹配。这就是全部的核心,值得不加修饰地陈述:针对相同定义计算的相同问题会产生相同的答案,因为不需要重新输入定义。
第二个改变是分歧变得富有成效。目前,当两个数字不一致时,你会花一个小时来重构每个数字衡量的是什么。当定义与其排除条件和生效日期一起存储时,你比较的是定义,而不是对算术进行逆向工程——并且经常会发现这两个数字都是正确的,只是回答了不同的问题。
第三个是新员工入职。新分析师入职的第一个月主要花在了解试用期不计算在内上。当这些内容保存在他们的工具所读取的存储库中时,他们就可以直接从组织官方版本开始,而不是从仪表板中重新构建。
并且修订变得清晰易懂。带有生效日期的定义允许你说“此分析使用了 8 月之前的定义”,而不是寄希望于没人问起。这单一的属性——知道一个数字是在哪些规则下计算出来的——是使分析立得住脚的关键所在。
适合 AI 使用的指标定义最佳实践
写下排除条件和原因,而不仅仅是公式
“活跃 = 过去 90 天内已支付发票”只是半个定义。防止偏差的另一半是:排除试用(它们在 2025 年价格调整前虚增了数字)、排除内部账户(3 月审计结果)、按账户级别而非席位级别计算。 原因很重要,因为它们能阻止人们每个季度都对排除条件重新进行争论。
为每个定义标注日期并保留旧版本
当定义发生变化时,添加带有生效日期的全新版本,并将前一个版本标记为已废弃。删除旧定义会破坏你解读上季度数字的能力。这是整个实践中价值最高、但也最容易被忽略的习惯。
指定所有者
每个定义都应该说明由谁来决定。这不是为了官僚作风——因为“这仍然正确吗?”这个问题需要一个接收人。没有所有者的定义会默默发生偏差;有所有者的定义会得到纠正。
保持受治理层作为单一事实来源
使用记忆层使定义无处不在,并保持你的语义层或数据仓库模型作为实际计算报告数字的工具。当两者不一致时,以受治理层为准,并修正记忆条目。颠倒这种层级关系会导致你得到一个记录详尽的错误数字。
结论
ChatGPT 会遗忘你的指标定义,因为定义是一个决定,而不是数据的属性,并且在基于聊天的日常工作流中,没有任何东西能在会话之间传递决定。相反,你得到的是模型对该指标名称通常含义的先验认知,并被自信地执行——这就是为什么失败表现为无法对账的数字,而不是你能看到的错误。
将定义保存在你的工具所读取的存储库中可以解决可用性问题:定义、其排除条件、其所有者和生效日期会随问题一起提供。保留你的语义层用于强制执行以及任何需要报告的内容。在这两者之间,你周一解释的“活跃客户”版本在周四仍然在使用,并且你可以证明任何给定数字使用的是哪个版本。