跳转到主要内容

TIL

TIL 全称为 Today I Learned,旨在简短的分享自己获得的知识/经验,或者仅仅是自认为有趣的事物。受到 Simon Willision 和 Julia Evans 的启发。形态上可能类似于微博(广义的 micro-blogging),但是不受平台限制。

我曾经让 LLM 找对应 TIL 的两个字的中文翻译,但似乎都不太满意,因此暂时保留原始名字。未来如果找到合适的可能会换上。以下是一些可能的翻译:今学;今知;今悟;今得;今获;今识;今明;今晓;今解。

另外如果你喜欢 TIL,可能也会对我的 书签 和 书签摘要 感兴趣。

  • 用 JSON 数据列派生出关系数据库中的其他列

    发布于 TIL 115 字 1 分钟

    一个看起来很奇妙,细想下似乎又有点道理的 SQL 建表方式:Data 列存储真正的数据(JSON),其他列都从 Data 派生而来。基本上是半个文档数据库? CREATE TABLE IF NOT EXISTS Cookie ( Cookie TEXT NOT NULL AS (Data->>'cookie') STORED UNIQUE, -- PK UserID INTEGER NOT NULL AS (Data->>'user_id') STORED REFERENCES User …

    一个看起来很奇妙,细想下似乎又有点道理的 SQL 建表方式:Data 列存储真正的数据(JSON),其他列都从 Data 派生而来。基本上是半个文档数据库? CREATE TABLE IF NOT EXISTS Cookie ( Cookie TEXT NOT NULL AS (Data->>'cookie') STORED UNIQUE, -- PK UserID INTEGER NOT NULL AS (Data->>'user_id') STORED REFERENCES User …

  • WebMention - 去中心化的网站间互动

    发布于 TIL 675 字 2 分钟

    阅读其他人的博客的时候,注意到底部有个 WebMention 提交框。查了下才发现还有这样一个 W3C 标准,用简单的 HTTP 请求就能做到。以下是一些 LLM 生成的说明。 Webmention 是一种 W3C 推荐的开放标准,旨在实现网站之间的去中心化通知。简单来说,当一个网页(称为“源”)链接或提及另一个网页(称为“目标”)时,源网页可以自动通知目标网页,从而让目标网页知道它被引用了。这使得网站能够接收并显示来自其他网站的“评论”、“引用”、“喜欢”或“转发”等互动,而无需依赖中心化的第 …

    阅读其他人的博客的时候,注意到底部有个 WebMention 提交框。查了下才发现还有这样一个 W3C 标准,用简单的 HTTP 请求就能做到。以下是一些 LLM 生成的说明。 Webmention 是一种 W3C 推荐的开放标准,旨在实现网站之间的去中心化通知。简单来说,当一个网页(称为“源”)链接或提及另一个网页(称为“目标”)时,源网页可以自动通知目标网页,从而让目标网页知道它被引用了。这使得网站能够接收并显示来自其他网站的“评论”、“引用”、“喜欢”或“转发”等互动,而无需依赖中心化的第 …

  • BOCU-1 - Unicode 的差分编码

    发布于 TIL 321 字 1 分钟

    UTF-8 作为变长编码,对 ASCII 很省空间,但是对于中文就不太友好了(一般需要 3 个 byte)。 BOCU-1 是一个变长"差分"编码,每个字符不是被直接编码,而是先计算和一个 prev 字符的差值,然后用 1 到 4 个 byte 编码这个差值。对于部分占据较大连续区间的字符组合(例如 CJK 统一汉字),会直接用区间中点作为 prev,从而减少存储占用,对中文而言大概是 25%。另外实际实现时,还做了一些特殊优化,来保证 BOCU-1 编码后的二进制排序和原始文本的排序一致(意味 …

    UTF-8 作为变长编码,对 ASCII 很省空间,但是对于中文就不太友好了(一般需要 3 个 byte)。 BOCU-1 是一个变长"差分"编码,每个字符不是被直接编码,而是先计算和一个 prev 字符的差值,然后用 1 到 4 个 byte 编码这个差值。对于部分占据较大连续区间的字符组合(例如 CJK 统一汉字),会直接用区间中点作为 prev,从而减少存储占用,对中文而言大概是 25%。另外实际实现时,还做了一些特殊优化,来保证 BOCU-1 编码后的二进制排序和原始文本的排序一致(意味 …

  • 用 apt-file search 找缺失的文件属于哪个包

    发布于 TIL 63 字 1 分钟

    虽然搜索/问 LLM 可能更快些,但是原来还可以这样找缺失的文件在哪个软件包里。 $ apt install -q --yes apt-file && apt-file update $ apt-file search pcre2posix.h libpcre2-dev: /usr/include/pcre2posix.h $ apt-file search libpcre2-posix.so libpcre2-dev: …

    虽然搜索/问 LLM 可能更快些,但是原来还可以这样找缺失的文件在哪个软件包里。 $ apt install -q --yes apt-file && apt-file update $ apt-file search pcre2posix.h libpcre2-dev: /usr/include/pcre2posix.h $ apt-file search libpcre2-posix.so libpcre2-dev: …

  • 被浏览器禁用的端口 (or 为什么连不上 6000 端口上的 HTTP 服务)

    发布于 TIL 299 字 1 分钟

    原因:部分服务对非预期的输入太宽容了,导致可能允许攻击者对这些服务构造特定的 HTTP 请求调用。(跨协议脚本漏洞,Cross-protocol scripting) 例子:SMTP 用换行符分割命令,且会忽略无效命令;攻击者构造了一个网页,里面包含一个 multipart/form-data 的表单,插入了一些 SMTP 命令;用户点击后,请求发送到 SMTP 所在端口上,HTTP 头和其他字段被 SMTP 服务忽略,但是剩下的真 SMTP 命令会被执行。 表现:Chrome 报错 …

    原因:部分服务对非预期的输入太宽容了,导致可能允许攻击者对这些服务构造特定的 HTTP 请求调用。(跨协议脚本漏洞,Cross-protocol scripting) 例子:SMTP 用换行符分割命令,且会忽略无效命令;攻击者构造了一个网页,里面包含一个 multipart/form-data 的表单,插入了一些 SMTP 命令;用户点击后,请求发送到 SMTP 所在端口上,HTTP 头和其他字段被 SMTP 服务忽略,但是剩下的真 SMTP 命令会被执行。 表现:Chrome 报错 …

  • Enthusiam 算法 - 群聊里有人又有 AI,下一个谁发言?

    发布于 TIL 277 字 1 分钟

    假如一个群聊里有人又有 AI,谁应该发言?作者在试图构建这样的聊天室时遇到了这个问题。作者尝试了一些简单的方法,例如用一个中央决策器协调对话,或者是用一个小模型来判断某个模型是否应该回复,但效果都不佳。在阅读一些社会学论文后,作者提出了 “热情度” (Enthusiam) 算法:对话过程中,每个 AI 根据是否直接涉及自己、是否是历史上下文延续(如追问)、是否会打断他人、自己的性格(是否健谈)来计算一个回复分数(0~9 之间),最后选择超过阈值(例如5)且分数最高的 AI 回复。未来作者在考虑探 …

    假如一个群聊里有人又有 AI,谁应该发言?作者在试图构建这样的聊天室时遇到了这个问题。作者尝试了一些简单的方法,例如用一个中央决策器协调对话,或者是用一个小模型来判断某个模型是否应该回复,但效果都不佳。在阅读一些社会学论文后,作者提出了 “热情度” (Enthusiam) 算法:对话过程中,每个 AI 根据是否直接涉及自己、是否是历史上下文延续(如追问)、是否会打断他人、自己的性格(是否健谈)来计算一个回复分数(0~9 之间),最后选择超过阈值(例如5)且分数最高的 AI 回复。未来作者在考虑探 …

  • 反爬虫工具 Anubis 中的 anime girl 图像

    发布于 TIL 343 字 1 分钟

    Anibus 是一个反 AI 爬虫的工具,通过工作量证明计算来放过真人并阻止爬虫。项目的名字来源于古埃及神话的死神阿努比斯,在死后会把人的心脏和羽毛放在天平上比较。这个工具已经被很多开源界的主要网站采用(甚至联合国都在用 (!))。 在挑战进行过程中(实际执行计算的时候),界面上会显示一个 anime girl 图像。有人对此感到不满,希望作者开放隐藏或者替换图像的能力。在这篇文章中,作者 Xe 说明了自己的理由:这是个故意为之的决定,目的是避免这个开源项目成为“无偿维护基础设施的牺牲品”。简而 …

    Anibus 是一个反 AI 爬虫的工具,通过工作量证明计算来放过真人并阻止爬虫。项目的名字来源于古埃及神话的死神阿努比斯,在死后会把人的心脏和羽毛放在天平上比较。这个工具已经被很多开源界的主要网站采用(甚至联合国都在用 (!))。 在挑战进行过程中(实际执行计算的时候),界面上会显示一个 anime girl 图像。有人对此感到不满,希望作者开放隐藏或者替换图像的能力。在这篇文章中,作者 Xe 说明了自己的理由:这是个故意为之的决定,目的是避免这个开源项目成为“无偿维护基础设施的牺牲品”。简而 …

  • DumPy - 没有聪明技巧,用起来更省心的 Numpy 封装

    发布于 TIL 132 字 1 分钟

    NumPy 功能多,速度快,但是广播机制容易引发错误,高维操作时 dim 和 None 到处乱飞,用起来心智负担很重。鉴于此,作者封装了 DumPy,用类似循环的语法​(显式索引)表达高维操作,但实际通过​向量化编译​来加速执行;计算时使用的维度也需要显式声明表达意图,再也不用瞎猜了。 src: https://dynomight.net/dumpy/ related: https://dynomight.net/numpy/

    NumPy 功能多,速度快,但是广播机制容易引发错误,高维操作时 dim 和 None 到处乱飞,用起来心智负担很重。鉴于此,作者封装了 DumPy,用类似循环的语法​(显式索引)表达高维操作,但实际通过​向量化编译​来加速执行;计算时使用的维度也需要显式声明表达意图,再也不用瞎猜了。 src: https://dynomight.net/dumpy/ related: https://dynomight.net/numpy/

  • simpleeval - 受限安全的 Python 表达式评估

    发布于 TIL 144 字 1 分钟

    提供了一个 Python 的简单子集,限制了高风险操作(例如指数操作在数值过大的时候也可以卡死运行环境(!)) 可以被放在各种需要表达式计算能力,但是又需要限制风险的场景下使用(例如拿来给 LLM 当计算器用) 底层用 ast 库解析语法树,并递归节点求值。 核心代码只有一个 py 文件,因此很容易嵌入。 需要 Python 3.9+。 src: https://github.com/danthedeckie/simpleeval via: …

    提供了一个 Python 的简单子集,限制了高风险操作(例如指数操作在数值过大的时候也可以卡死运行环境(!)) 可以被放在各种需要表达式计算能力,但是又需要限制风险的场景下使用(例如拿来给 LLM 当计算器用) 底层用 ast 库解析语法树,并递归节点求值。 核心代码只有一个 py 文件,因此很容易嵌入。 需要 Python 3.9+。 src: https://github.com/danthedeckie/simpleeval via: …

  • HyDE - 用生成的假答案来搜索嵌入 (2212.10496)

    发布于 TIL 198 字 1 分钟

    在读 Simon 的文章时,偶然学到这个精妙的小技巧(be like 这也行?): A neat trick is you can ask an LLM to entirely synthesize a potential answer to the user’s question—then embed that artificial answer and find your own content that’s nearby in vector space! 一个巧妙的小技巧是,你可以让大语言 …

    在读 Simon 的文章时,偶然学到这个精妙的小技巧(be like 这也行?): A neat trick is you can ask an LLM to entirely synthesize a potential answer to the user’s question—then embed that artificial answer and find your own content that’s nearby in vector space! 一个巧妙的小技巧是,你可以让大语言 …

  • 组织文档的 Diátaxis 框架

    发布于 TIL 472 字 1 分钟

    Diátaxis 框架旨在解决文档混乱导致信息无从查找的问题。这个框架把文档分为四个类型: 教程(Tutorials)- 学习导向:面向完全新手,从 0 开始,一步一步完成一个具体任务(例子:如何创建第一个接口) 操作指南(How-to Guides)- 任务导向:面向已有一些基础知识和经验的用户,达成某个特定目标,步骤清晰但是不过度详细(例子:如何排查接口的高耗时问题) 解释说明(Explanation)- 理解导向:提供背景和上下文,解释怎么做背后的“为什么”,帮助建立心智模型(例子:框架处 …

    Diátaxis 框架旨在解决文档混乱导致信息无从查找的问题。这个框架把文档分为四个类型: 教程(Tutorials)- 学习导向:面向完全新手,从 0 开始,一步一步完成一个具体任务(例子:如何创建第一个接口) 操作指南(How-to Guides)- 任务导向:面向已有一些基础知识和经验的用户,达成某个特定目标,步骤清晰但是不过度详细(例子:如何排查接口的高耗时问题) 解释说明(Explanation)- 理解导向:提供背景和上下文,解释怎么做背后的“为什么”,帮助建立心智模型(例子:框架处 …

  • Apple's Widget Backdoor - 如何用受限的 API 在小组件上实现动画效果

    发布于 TIL 344 字 1 分钟

    偶然被油管推送了这个视频,看完只能说太神奇了。 苹果允许开发者在 iOS 小组件上放置自己的内容,但是有一个重大限制:只能提供告诉系统在什么时间展示什么内容,而没法从主动刷新/重绘小组件。而且每次内容刷新之间至少需要间隔 5 分钟。然而,在此之外有两个小漏洞: 苹果为了自己的“时钟” App 能够显示秒针,留下了一个能以 20 fps 旋转某个 view 的私有 API,在某个 XCode 版本不慎暴露了出来 应用可以在小组件上放置一个 timer,放置后可以以每秒刷新一个时间文本(例如 …

    偶然被油管推送了这个视频,看完只能说太神奇了。 苹果允许开发者在 iOS 小组件上放置自己的内容,但是有一个重大限制:只能提供告诉系统在什么时间展示什么内容,而没法从主动刷新/重绘小组件。而且每次内容刷新之间至少需要间隔 5 分钟。然而,在此之外有两个小漏洞: 苹果为了自己的“时钟” App 能够显示秒针,留下了一个能以 20 fps 旋转某个 view 的私有 API,在某个 XCode 版本不慎暴露了出来 应用可以在小组件上放置一个 timer,放置后可以以每秒刷新一个时间文本(例如 …

  • Prima.cpp - 跨设备运行 LLM (2504.08791)

    发布于 TIL 131 字 1 分钟

    在 exo 之后的另一个跨设备 LLM 运行工具,但是速度比 exo 快得多;原理大致是,把所有参与节点组成一个环,一次推理可以在环上转多次,某个设备第一次推理和第二次推理加载不同的层;因此对小内存环境友好,不要求所有节点内存总大小大于模型大小(只要存储加载速度够快就行)。 src: https://github.com/Lizonghang/prima.cpp paper: https://arxiv.org/abs/2504.08791 via: …

    在 exo 之后的另一个跨设备 LLM 运行工具,但是速度比 exo 快得多;原理大致是,把所有参与节点组成一个环,一次推理可以在环上转多次,某个设备第一次推理和第二次推理加载不同的层;因此对小内存环境友好,不要求所有节点内存总大小大于模型大小(只要存储加载速度够快就行)。 src: https://github.com/Lizonghang/prima.cpp paper: https://arxiv.org/abs/2504.08791 via: …

  • 部分视频中的马赛克可以被去除

    发布于 TIL 493 字 1 分钟

    油管给我推荐了这个视频1,标题是 “It’s easier than ever to de-censor videos”。一个代码实现在这里2。 简单来说,如果一个视频中存在某个被打码的静态图片(例如一个文件查看器窗口),且这个图片(和马赛克)一起在视频画面上移动(例如从左侧拖到右侧),就有可能还原图片。(对动态视频的打码似乎还是安全的。) 这是怎么做到的?一般视频编辑器中,实现马赛克的方式是,将某一个区域(例如一个5x5像素的区域)用当前区域中心的像素填充。假如这个区域划分在整个视频中保持一致 …

    油管给我推荐了这个视频1,标题是 “It’s easier than ever to de-censor videos”。一个代码实现在这里2。 简单来说,如果一个视频中存在某个被打码的静态图片(例如一个文件查看器窗口),且这个图片(和马赛克)一起在视频画面上移动(例如从左侧拖到右侧),就有可能还原图片。(对动态视频的打码似乎还是安全的。) 这是怎么做到的?一般视频编辑器中,实现马赛克的方式是,将某一个区域(例如一个5x5像素的区域)用当前区域中心的像素填充。假如这个区域划分在整个视频中保持一致 …

  • JSX Over The Wire - 对 React 服务端组件的自然推导

    发布于 TIL 561 字 2 分钟

    一篇介绍 React Server Component 的文章,第一次让我有了一种“原来如此!”的感觉。作者分两条线,分别从概念和历史层面介绍了 RSC 的设计思想。十分推荐的 deepdive 文章! 概念:Model -> ViewModel -> REST -> Backend For Frontend 历史:CGI -> PHP -> XHP -> Async XHP -> Server Driven UI src: …

    一篇介绍 React Server Component 的文章,第一次让我有了一种“原来如此!”的感觉。作者分两条线,分别从概念和历史层面介绍了 RSC 的设计思想。十分推荐的 deepdive 文章! 概念:Model -> ViewModel -> REST -> Backend For Frontend 历史:CGI -> PHP -> XHP -> Async XHP -> Server Driven UI src: …

  • GCRA 限流算法

    发布于 TIL 244 字 1 分钟

    在看一个 Python 限流库(throttled-py)的仓库的时候,注意到了一个之前没有听说过的限流算法 GCRA(Generic Cell Rate Algorithm,通用信元速率算法)。 漏桶算法无法应对突发请求 令牌桶算法可以应对突发,但是需要维护两个状态(当前桶内令牌数、上一次补充令牌时间),且需要对状态加锁(这两个状态需要在一个原子里修改) GCRA 是对令牌桶的改进,减少了状态数(只需要维护一个状态 tat 理论到达时间),实现上更轻量 顺带一提,Let’s Encrypt 用 …

    在看一个 Python 限流库(throttled-py)的仓库的时候,注意到了一个之前没有听说过的限流算法 GCRA(Generic Cell Rate Algorithm,通用信元速率算法)。 漏桶算法无法应对突发请求 令牌桶算法可以应对突发,但是需要维护两个状态(当前桶内令牌数、上一次补充令牌时间),且需要对状态加锁(这两个状态需要在一个原子里修改) GCRA 是对令牌桶的改进,减少了状态数(只需要维护一个状态 tat 理论到达时间),实现上更轻量 顺带一提,Let’s Encrypt 用 …

  • rustc_codegen_clr - 把 Rust 编译成 C

    发布于 TIL 97 字 1 分钟

    Why?:有的架构/平台不支持 Rust,但是基本都有 C 编译器;如果可以把 Rust 编译成 C,那就可以让 Rust 在更多更广泛的平台上运行了。 How?: 作为一个 Rust 编译器(rustc)后端,目标是 C 而不是机器语言。 repo: https://github.com/FractalFir/rustc_codegen_clr via: https://fractalfir.github.io/generated_html/cg_clr_odd_platforms.html

    Why?:有的架构/平台不支持 Rust,但是基本都有 C 编译器;如果可以把 Rust 编译成 C,那就可以让 Rust 在更多更广泛的平台上运行了。 How?: 作为一个 Rust 编译器(rustc)后端,目标是 C 而不是机器语言。 repo: https://github.com/FractalFir/rustc_codegen_clr via: https://fractalfir.github.io/generated_html/cg_clr_odd_platforms.html

  • CaMeL - 用双 LLM 和数据流分析实现提示注入缓解 (2503.18813)

    发布于 TIL 837 字 2 分钟

    LLM 的提示注入是一个长久存在但鲜有突破性进展的问题,但今天一个这样的突破性进展似乎出现了。在 Simon Willson 的双 LLM 方案上1,Deepmind 提出了 CaMeL2。以下是简要介绍: LLM 提示注入的本质问题:指令和数据被混在一起输入给 LLM。 由此可见的一个思路:需要想办法把指令和数据从输入流里拆开;无论是通过明确的边界(像 SQL 的 binding),还是干脆分开给两个 LLM。 Simon Willson 的双 LLM 方案:不用单一 LLM 干所有事,而是拆 …

    LLM 的提示注入是一个长久存在但鲜有突破性进展的问题,但今天一个这样的突破性进展似乎出现了。在 Simon Willson 的双 LLM 方案上1,Deepmind 提出了 CaMeL2。以下是简要介绍: LLM 提示注入的本质问题:指令和数据被混在一起输入给 LLM。 由此可见的一个思路:需要想办法把指令和数据从输入流里拆开;无论是通过明确的边界(像 SQL 的 binding),还是干脆分开给两个 LLM。 Simon Willson 的双 LLM 方案:不用单一 LLM 干所有事,而是拆 …

  • Concrete Syntax Tree 具体语法树

    发布于 TIL 638 字 2 分钟

    在阅读一个用 LLM 给 Python 加 docstring 的工具llm-docsmith的创作笔记1时,首次了解到了 Concrete Syntax Tree 具体语法树这个概念(之前只知道 AST 抽象语法树)。 搜索了一些相关资料,看起来可以按照抽象层级从低到高这样排序: 源代码:抽象层级最低,信息最丰富 CST:抽象层级略高(有语言 grammer 能有的全部信息),信息较为丰富,但是视解析器可能丢失一些语言 grammer 没有的信息(例如缩进) AST:抽象层级最高,只含有相对必 …

    在阅读一个用 LLM 给 Python 加 docstring 的工具llm-docsmith的创作笔记1时,首次了解到了 Concrete Syntax Tree 具体语法树这个概念(之前只知道 AST 抽象语法树)。 搜索了一些相关资料,看起来可以按照抽象层级从低到高这样排序: 源代码:抽象层级最低,信息最丰富 CST:抽象层级略高(有语言 grammer 能有的全部信息),信息较为丰富,但是视解析器可能丢失一些语言 grammer 没有的信息(例如缩进) AST:抽象层级最高,只含有相对必 …

  • Graft - 支持部分复制的同步引擎

    发布于 TIL 337 字 1 分钟

    一个新的同步引擎,可以在此之上构建需要同步功能的应用(当然是用 Rust 写的)。 主要特性是将数据视作多个页面(page),页面本身存储在对象存储上;客户端使用(例如需要读取数据时)先获取元数据,再根据实际需要获取所需的页面,而不需要每次都拉取全量数据。每个页面可以有多个版本,由此可以得到快照和时间点恢复。 当然和任何分布式系统一样,某个客户端可能会尝试在一个旧版本上写入再提交。(想象在 git 中一个在旧未更新的分支上 commit 再 push)对这种情况,Graft 提供了多种冲突处理方 …

    一个新的同步引擎,可以在此之上构建需要同步功能的应用(当然是用 Rust 写的)。 主要特性是将数据视作多个页面(page),页面本身存储在对象存储上;客户端使用(例如需要读取数据时)先获取元数据,再根据实际需要获取所需的页面,而不需要每次都拉取全量数据。每个页面可以有多个版本,由此可以得到快照和时间点恢复。 当然和任何分布式系统一样,某个客户端可能会尝试在一个旧版本上写入再提交。(想象在 git 中一个在旧未更新的分支上 commit 再 push)对这种情况,Graft 提供了多种冲突处理方 …