<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Notes | 董昊</title><link>https://donghao.ac/notes/</link><atom:link href="https://donghao.ac/notes/index.xml" rel="self" type="application/rss+xml"/><description>Notes</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>zh-Hans</language><lastBuildDate>Sun, 28 Jun 2026 00:00:00 +0000</lastBuildDate><image><url>https://donghao.ac/media/icon_hu_eee4a95885829ab2.png</url><title>Notes</title><link>https://donghao.ac/notes/</link></image><item><title>AI 安全的问题不在模型，在输入</title><link>https://donghao.ac/notes/llm-visibility/</link><pubDate>Sun, 28 Jun 2026 00:00:00 +0000</pubDate><guid>https://donghao.ac/notes/llm-visibility/</guid><description>&lt;p&gt;Emeritus 课程的最后一个单元讲 Guardrails——用多层模型来加固智能体的安全性。教授的框架很清晰：输入过滤 → 输出审核 → 行为约束。&lt;/p&gt;
&lt;p&gt;但我脑子里有一个问题挥之不去。&lt;/p&gt;
&lt;h2 id="用智能体审计智能体"&gt;用智能体审计智能体？&lt;/h2&gt;
&lt;p&gt;主流安全框架的做法是：让一个大模型生成输出，再用另一个大模型（或同一模型的另一个实例）去审查这个输出。&lt;/p&gt;
&lt;p&gt;审计者发现了问题，要求重新生成。重新生成的输出再次被审计……这不是安全。这是&lt;strong&gt;审计递归&lt;/strong&gt;——一个没有坚实基点的无限循环。&lt;/p&gt;
&lt;p&gt;问题在哪？&lt;/p&gt;
&lt;p&gt;不在输出。&lt;strong&gt;在输入。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="为什么没人问这个问题"&gt;为什么没人问这个问题&lt;/h2&gt;
&lt;p&gt;同一个模型、同一个任务——为什么有的提示词产生精准的答案，有的产生幻觉？&lt;/p&gt;
&lt;p&gt;如果所有幻觉都是&amp;quot;模型的问题&amp;quot;，那为什么不是所有提示词都产生幻觉？&lt;/p&gt;
&lt;p&gt;答案是：&lt;strong&gt;提示词的质量千差万别。&lt;/strong&gt; 有些提示词本身就是一团迷雾——别说 AI，换成人来读，也未必能看清用户想表达什么。&lt;/p&gt;
&lt;p&gt;大雾天开车，你需要的是能见度。AI 也一样。&lt;/p&gt;
&lt;h2 id="visibility能见度"&gt;Visibility（能见度）&lt;/h2&gt;
&lt;p&gt;我把这个概念命名为 &lt;strong&gt;Visibility&lt;/strong&gt;——LLM 输入的&lt;strong&gt;结构清晰度&lt;/strong&gt;和&lt;strong&gt;来源可追溯性&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;论文的核心命题很简单：&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;输入质量应该是 AI 安全的第一道防线。输出审计——今天的主流方案——应该降级为兜底机制。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这不是哲学。是可以量化的。&lt;/p&gt;
&lt;p&gt;我提出了四个维度的 Visibility 评分框架：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;测量什么&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;来源数量&lt;/strong&gt;（Source Count）&lt;/td&gt;
&lt;td&gt;输入引用了多少个独立信息源？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;溯源比例&lt;/strong&gt;（Provenance Ratio）&lt;/td&gt;
&lt;td&gt;多少断言可以追溯到具体出处？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;约束密度&lt;/strong&gt;（Constraint Density）&lt;/td&gt;
&lt;td&gt;每单位 token 包含多少具体约束？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;时序新鲜度&lt;/strong&gt;（Temporal Freshness）&lt;/td&gt;
&lt;td&gt;输入中的信息有多新？&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;然后用一个公式来表达核心关系：&lt;/p&gt;
$$V = \frac{F}{m}$$&lt;p&gt;其中 $F$ 是约束力（constraint force），$m$ 是上下文质量（context mass）。这个公式的含义：&lt;strong&gt;输入越长（m 越大），你就需要更强的约束（F 越大）来维持同样的 Visibility。&lt;/strong&gt; 这解释了为什么在长对话中，模糊的追问往往得到跑偏的回答。&lt;/p&gt;
&lt;h2 id="这不止是关于-ai"&gt;这不止是关于 AI&lt;/h2&gt;
&lt;p&gt;在写这篇论文的过程中，我意识到同样三条规律可以描述所有人际沟通：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一定律（注意力惯性）&lt;/strong&gt;：没有外力时，对方的回应自动坍缩到最平庸的社交套话。你问大模型&amp;quot;写个方案&amp;quot;→ 它给你放之四海而皆准的空话。不是模型笨，是它沿着训练数据里概率最高的路径在滑行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二定律（注意力偏转）&lt;/strong&gt;：要偏转对方的注意力所需的&amp;quot;特异性外力&amp;quot;，与对话历史的长度成正比。群聊刷了 100 条之后你轻飘飘说一句&amp;quot;吃了吗&amp;quot;——没人理你。但你突然说&amp;quot;老板刚才在电梯里哭了&amp;quot;——全场注意瞬间聚焦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三定律（注意力互惠）&lt;/strong&gt;：你投入多精细的引导，对方就回馈多精细的回应。&amp;ldquo;聊聊电影&amp;rdquo;→&amp;ldquo;好看&amp;rdquo;。&amp;ldquo;聊聊诺兰在《奥本海默》中刻意省略广岛镜头的叙事伦理&amp;rdquo;→ 对方被迫用同等深度回应你。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;治理 AI，从治理输入开始。而治理输入，从理解注意力开始。&lt;/p&gt;
&lt;p&gt;
·
&lt;/p&gt;</description></item><item><title>我给 Linux Kernel 写了一段代码</title><link>https://donghao.ac/notes/phicomm-k3-linux-kernel/</link><pubDate>Mon, 28 Oct 2019 00:00:00 +0000</pubDate><guid>https://donghao.ac/notes/phicomm-k3-linux-kernel/</guid><description>&lt;p&gt;2018 年冬天，我坐在老家安徽安庆的公寓里，面前摆着一台电烙铁、一管助焊剂，和一台花了近两千元买来的路由器——斐讯 K3。&lt;/p&gt;
&lt;p&gt;斐讯暴雷了。它用&amp;quot;零元购&amp;quot;的模式吸引了大量用户购买高端路由器，承诺全额返现，然后资金链断裂。成千上万的人血本无归。我手里这台 K3——BCM4709C0 处理器、512MB 内存、双频 WiFi、甚至还有一块 LCD 小屏幕——一夜之间变成了一堆电子垃圾。&lt;/p&gt;
&lt;h2 id="决定"&gt;决定&lt;/h2&gt;
&lt;p&gt;我决定让它活过来。&lt;/p&gt;
&lt;p&gt;具体来说：把斐讯 K3 的硬件描述写进 Linux 内核主线。这样，任何运行 Linux 的系统——包括 OpenWrt 开源路由器固件——都能原生识别并支持这台设备。不用再依赖斐讯（已经消失）的官方固件更新。&lt;/p&gt;
&lt;p&gt;这意味着我要写一个&lt;strong&gt;设备树源文件&lt;/strong&gt;（Device Tree Source, DTS）——一份描述硬件组成的结构化数据，告诉 Linux 内核&amp;quot;这台设备有什么芯片、多少内存、WiFi 模块怎么接线&amp;quot;。&lt;/p&gt;
&lt;h2 id="三个月"&gt;三个月&lt;/h2&gt;
&lt;p&gt;我不知道怎么做。所以我把能学的都学了：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;焊接&lt;/strong&gt;。K3 主板上有些硬件信息需要直接读取。我买了电烙铁和助焊剂，对着网上找来的焊接教程视频，自己摸索着完成了第一次硬件操作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;文档&amp;rdquo;&lt;/strong&gt;。没有现成的。Linux 内核的设备树规范写得抽象，Broadcom BCM5301X 系列的硬件细节不在任何官方文档里。我用的是最笨的办法——在 OpenWrt 源码里找参数相近的其他路由器固件，一个文件一个文件地比对，一个参数一个参数地试，把 K3 的硬件规律从零总结出来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;git send-email&lt;/code&gt;&lt;/strong&gt;。Linux 内核不用 GitHub PR。它用邮件列表。我花了整整一个周末学习如何用 &lt;code&gt;git format-patch&lt;/code&gt; 生成补丁，用 &lt;code&gt;git send-email&lt;/code&gt; 通过 SMTP 发给内核邮件列表。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="提交"&gt;提交&lt;/h2&gt;
&lt;p&gt;2019 年 1 月 20 日 23:33（北京时间 1 月 21 日凌晨），我的补丁出现在 Linux 内核邮件列表中。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Copyright (C) 2017 Hamster Tian &amp;lt;haotia@gmail.com&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Copyright (C) 2019 Hao Dong &amp;lt;halbertdong@gmail.com&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;bcm47094.dtsi&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;compatible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;phicomm,k3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;brcm,bcm47094&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;brcm,bcm4708&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Phicomm K3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;device_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;reg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mh"&gt;0x00000000&lt;/span&gt; &lt;span class="mh"&gt;0x08000000&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mh"&gt;0x88000000&lt;/span&gt; &lt;span class="mh"&gt;0x18000000&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个文件不长。但每一行参数都是我从零散的固件代码中比对出来的——没有用万用表逐个测量，靠的是从一堆看似不相关的信息里抽象出正确的硬件模型。&lt;/p&gt;
&lt;p&gt;OpenWrt 开发者 &lt;strong&gt;Rafał Miłecki&lt;/strong&gt; 帮我清理了代码格式，Broadcom 子系统维护者 &lt;strong&gt;Florian Fainelli&lt;/strong&gt; 在 1 月 31 日合并了补丁。&lt;/p&gt;
&lt;h2 id="它去了哪里"&gt;它去了哪里&lt;/h2&gt;
&lt;p&gt;大约十个月后——2019 年 10 月——我收到一封 GitLab 的自动通知。镜像仓库出了问题，我点进去一看……等等，这封通知说的是我的代码已经不在我的仓库里了。它&lt;strong&gt;在上游&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Linux Kernel mainline。Linus Torvalds 的仓库。&lt;/p&gt;
&lt;p&gt;后来我意识到：&lt;strong&gt;全球每一台安卓手机都运行着 Linux 内核。&lt;/strong&gt; 我的 72 行代码——在这个世界上运行次数最多的软件项目里——是其中的一部分。&lt;/p&gt;
&lt;p&gt;我不是内核的核心贡献者。我没写调度器，没修安全漏洞，没优化内存管理。我只是让一台被资本游戏抛弃的路由器，重新获得了自由。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
&lt;/p&gt;</description></item></channel></rss>