To Signal

钓鱼的时候,我看不到水下的全部情况,只能观察浮漂。

下竿之前,要调漂、配重,让饵料落在合适的位置。遇到小杂鱼闹窝,还得继续调整。我希望经过这些准备,值得提竿的变化能够清楚地表现出来,其他扰动尽量少一些。

过去几年,排查 bug、做 code review,尤其是和 AI 协作的时候,我越来越觉得,自己也需要这样一支浮漂。

先定义值得关注的东西#

和 AI 协作,我能得到大量代码、解释和分析。如果每次都要从头审阅,重新建立对整个实现的理解,很快就会超出我的处理能力。

我需要一些关键信息,帮助我判断当前的状态,看出变化的方向,再决定是否介入、施加约束,或者要求重做。

我把经过提炼、能够让人快速理解某种状态或趋势的信息,叫作 ​Signal。

接口延迟的变化是一种信号。在需求讨论中,我也经常让 AI 反问几个最重要的问题。我的回答会明确一些限制和前提,成为后续协作里的高价值信号。

先明确自己关心什么,过滤才有依据。

我关心哪些状态?什么变化值得注意?哪些事情必须经过我的确认?这些问题需要在工作开始时就有所考虑。随后,才能围绕它们组织信息,做聚合、过滤和分层。

这也是我想主动设计信号的原因:让重要的事情有一个稳定的出口,减少每次都从杂乱信息中重新寻找它们的负担。

给低频的异常留一个位置#

我曾经遇到过一个 Python 服务的故障。它可能几天才出现一次:CPU 突然打满,服务不可用,内存却几乎没有明显变化。

后来,我注意到调用这个服务的是一个 AI 系统,它的上下文非常大。我开始怀疑,故障与 context 的大小有关。沿着这个方向寻找相关案例,最终定位到一个带终端排版渲染的日志库。处理超长日志时,其中的排版计算成了问题。

CPU 异常让我知道需要介入。上下文大小这个线索,又帮助我缩小了排查范围。

我希望信号能起到这样的作用:平时帮助我了解状态,需要排查时,给我一个进入细节的入口。

这段经历也让我对“过滤”更加谨慎。一个异常即使只出现过一次,也可能值得立即处理。出现频率、变化幅度、证据是否充分、后果是否严重,需要分别考虑。

多方面的信息可以相互印证,提高判断的可靠性。对于已经造成严重影响的异常,我也要保留直接介入的通道。眼下看起来轻微的变化,则需要关注它继续扩大的可能性。

因此,信号的分层应该包含不同的处理方式:有些留待观察,有些需要补充信息,有些必须马上让人看见。

对信号说“不”#

我希望信号忠实地反映客观事实,也需要知道它覆盖了哪些事实。

“所有测试通过”可以完全属实,重要场景却可能没有被覆盖。AI 在 code review 中给出很多正面评价,实现里也可能存在不必要的设计。我就遇到过这样的情况:亲自检查之后,发现新增的一些数据库约束,对当时的业务并没有必要。

人也会遗忘上下文。曾经讨论过的设计前提,可能在几轮修改之后被忘掉,留下重复甚至矛盾的实现。

这些盲区提醒我,信号能够支持多大的结论,需要另行判断。

我一直认为,人要有对 AI 说“不”的能力。对信号也是一样。

有时,我怀疑信息本身的准确性;有时,我接受它描述的事实,但认为现有证据还不充分,需要再看一些东西。

如果错误信号反复出现,就要回头检查它的产生过程:关注点是否偏了,必要的信息是否缺失,聚合和过滤是否应该提前一步完成。这些调整,也应该成为信号系统的日常维护。

To Signal#

我很喜欢 Mitchell Hashimoto 在 《As Code》 中表达的想法:把知识从人的脑海中带入明确的系统,让它能够被共享、版本化和迭代。

对我来说,To Signal 是一种相近的工程习惯。

把我们对重要状态和变化的认识,落实成能够被看见、被理解、被检验的信号。让有限的注意力有机会及时出现在需要判断的地方。

就像钓鱼。

浮漂动了,我会留意。要不要提竿,仍然由我判断。


延伸阅读#

这里的 Signal 是我对工程实践的一种个人表述。围绕信号的识别、状态判断和人的介入,以下领域提供了更系统的方法。

信号检测理论:如何权衡误报与漏报#

信号检测理论(Signal Detection Theory) 区分了两个问题:我们有多大能力分辨信号与噪声,以及我们把判断门槛设在哪里。对于同一套证据,调整门槛会改变命中、漏报和误报的比例;不同错误的代价,也会影响门槛的选择。这为“哪些扰动应该过滤,哪些异常值得打扰人”提供了精确的讨论语言。

可以从 David Heeger 的 《Signal Detection Theory》讲义读起

控制理论:通过有限观测理解系统状态#

控制理论(Control Theory) 中的可观测性与状态估计,研究如何根据系统的输入和输出推断内部状态,再利用这些估计形成反馈。它很适合用来思考:我们选择的观察入口,究竟能让我们知道什么,又有哪些状态仍然隐藏着。

Åström 与 Murray 的 《Feedback Systems》第八章:Output Feedback讨论了这些问题。这些方法依赖明确的模型与假设,借用到软件协作场景时,也需要检查其适用范围

人因工程与告警管理:为人的响应能力设计信息#

人因工程(Human Factors) 关注人的能力与限制。告警管理将这种关注落实到系统设计中:告警应该把注意力引向需要及时判断的状态,提供有用、相关的信息,并给人留下足够的响应时间。

英国 HSE 的 《Alarm Management》是一份简短的入口。它提醒我们,人的理解和响应能力,本身就是信号系统的设计条件

SRE:把这些问题落实到软件系统#

Google SRE 的 《Monitoring Distributed Systems》直接讨论了监控与告警的工程取舍:区分症状和原因,让告警对应值得采取的行动,控制噪声,并避免让人持续盯着屏幕寻找问题。

对于软件工程师,这篇最适合作为实践上的第一站,尤其值得阅读其中的 Symptoms Versus Causes 和 Tying These Principles Together 两节