昨天写了《给 AI 打分之前,先检查一下尺子》,讲评分这件事本身也需要验证。
今天想往前挪一步,看看打分之前,我们到底给 AI 发了什么。
最近排查作文辅导的输入,在一个长历史样本里看到了一个数字:逐字坐标表,占了总输入字符的 87.3%。
接近九万个字符,八成多都在告诉模型:每个字在哪里。
先把输入摊开
先交代范围。这是 10 月 15 日用本地模型替身跑的一次输入尺寸观测,材料是构造的合成样本,没有向外部模型发请求。
它能让我看见程序准备发送什么,不能告诉我模型实际读得怎样。
其中一个长历史、进入落笔阶段的样本,拆出来是这样:
| 内容 | 字符数 |
|---|---|
| 总输入 | 86,988 |
| 其中的逐字坐标表 | 75,920 |
| 坐标表占比 | 87.3% |
这里统计的是字符,不能直接当作 token,也不能按这个比例计算费用。它也只是一个样本,不能代表所有对话。
但这个样本已经足够让我停下来,重新看看这张表。
坐标表有它的用处
做作文辅导,有一件事我一直很在意:AI 引用孩子的话,得找到出处。
孩子说过什么、AI 建议过什么、孩子真正写下了什么,要分开。尤其到了修改阶段,不能只说“这句话改好了”,还得知道改的是哪条消息里的哪一段。
于是输入里除了原话,还附了一张逐字的位置表。
举个简化的例子,原话是“爷爷爱下棋”,旁边再给一份:
1 | 0:爷 |
模型引用时,就可以同时返回文字和起止位置,后端再核验它有没有指对地方。
这个设计的出发点很明确:让引用更容易检查。可当原话变长、历史消息变多,每个字都要带着编号和格式再展开一遍,辅助信息也跟着膨胀了。
原本用来帮助定位的一张表,最后占了大部分输入篇幅。
越怕遗漏,越容易加东西
这张表让我想起做这个项目时经常遇到的取舍。
希望 AI 记住孩子前面说过的话,就带上历史;希望它知道现在该做什么,就带上任务;希望它别把建议当成事实,就带上来源;希望它别提前往下走,就补充推进条件。
每一项单独看,都有理由。
但把它们放到同一次请求里,还需要再问一遍:这些内容在这一轮分别起什么作用?有没有重复表达同一件事?哪些要交给模型理解,哪些只需要程序保存和检查?
以前关注得更多的是“还缺什么”。这次把输入拆开,才看见另一个工作:检查已经加进去的东西。
那 87.3% 暂时不能证明模型因此漏掉了事实、回答慢了,或者出现了什么压缩问题。它首先暴露的是一个很具体的工程现象:为了说明原文的位置,我们用了很多篇幅。
这部分值得单独拿出来改,也值得单独验证。
我想先调整一下分工
目前考虑的一个方向,是让模型返回消息编号、精确原文,以及必要的消歧线索,再由程序去定位和核验。
另一个方向,是只给当前任务相关的片段提供局部坐标,需要时再映射回原消息。
这两种都还是候选方案。
定位也没有“搜一下原文”那么简单。同一句话可能出现两次,孩子可能改口、撤回,也可能在修改稿里保留了原句。程序找到第一次匹配,不代表找到了这次要引用的地方。
表情和组合字符的计数也要对齐。输入短了,引用却指错了,省下来的篇幅就没有意义。
所以接下来要保留的,是准确找到原话、分清来源、识别修改的能力;至于要不要继续把每个字的位置都交给模型,可以试着换一种做法。
这次想调整的是分工:模型判断要引用什么,程序负责把位置核准。
短了之后,还要重新跑一遍
真正比较时,我准备先固定同一批材料、任务和模型,分别跑原输入与精简输入。
先看引用:有没有漏、有没有串消息、重复片段能否区分、修改和撤回后是否仍然正确。
再看辅导:有没有重复追问、忽略刚补充的材料、把 AI 给的建议算成孩子自己的表达。
最后记录实际 token、响应时间和成本。短历史、长历史,以及不同阶段,也要分别看,不能用一组顺利的结果替其他情况作答。
如果同时换模型、改教学策略、删掉一批约束,即使结果变了,也很难知道是哪一步起了作用。这一轮想先把输入这件事看清楚。
目前完成的是观测和方案,精简还没实施,真实调用的前后对照也没跑。所以这篇暂时没有“省了多少费用、效果提升多少”的结论。
只记下一个新的检查习惯:以后再往输入里加一块内容,除了问它有没有用,也问问它应该由谁来处理。
先从这张坐标表开始。