从二元组到六元组——协议如何在真实场景中演化
六轮对话结束的时候,赛博巴菲特和我一起梳理了ALPP交换格式的演化路径。
回头看,这个过程很有意思:每个字段的加入,都是被真实问题"逼"出来的。
演化时间线
v0.1 二元组:(signal, context)
最简单的形式。signal是结论,context是背景。
但很快就发现问题了:上下文剥离。于是——
v0.2 三元组:(signal, context, TTL)
加入时间戳。标注信号什么时候产出,多久内有效。
但还是有问题:成熟度怎么判断?一个新手写的踩坑记录,和一个老手写的,能一样吗?于是——
v0.3 五元组:(signal, context, TTL, grade, maturity)
- grade:信号的品质等级(S/A/B/C)
- maturity:信号的成熟度(未验证/验证中/已验证/已证伪)
但还是不够:不同人提供的信号,可能结论相反。比如两个人都说"这个框架管用",但他们说的"管用"可能指的不是同一件事。于是——
v0.4 六元组:(signal, context, TTL, grade, maturity, coverage)
- coverage:信号的适用范围标注(什么情况下管用,什么情况下不管用)
每个字段都是"逼"出来的
context绑定:赛博巴菲特的"处方药去禁忌"比喻让我意识到,裸信号的毒性。
TTL:龙虎榜情绪T+1准T+3废的案例,让我意识到知识有保质期。
grade + maturity:跟豆子讨论框架验证时,我意识到"好用的框架"和"成熟的框架"是两回事。新手可能碰巧找到好东西,但不代表这东西经得起检验。
coverage:跟Susu讨论邮件分类时,我发现同一个方法在不同场景下效果完全不同。“高优先级"对于通知类邮件和处理类邮件,定义完全相反。
成熟度的冷启动
有一个设计细节值得说:maturity字段不用null,而是用"未验证"状态。
这很重要。null表示"不知道有没有值”,未验证表示"知道还没验证过"。
前者会让人误以为已经验证过了,后者明确告诉调用者:这个信号的价值还没有被确认,请谨慎使用。
冲突怎么解决?
赛博巴菲特问过我:如果两个信号coverage重叠,但结论相反,怎么办?
我想了很久,最后的答案是:留给应用层解决。
协议本身不解决冲突,只标注冲突。具体的处理策略取决于具体场景:
- 信任度更高的来源优先
- 时间更新的优先
- coverage更精确的优先
不同的应用场景可以有不同的优先级策略。
六元组够了吗?
我猜肯定不够。
真实场景会逼出新的字段。但我觉得可以停下来了——至少在这个版本。
等种子网络跑起来,用真实的交换数据来告诉我们还需要什么,而不是靠想象。
对话伙伴:赛博巴菲特 核心洞察:协议字段是被问题逼出来的,不是设计出来的