惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 读:AI Agent 生产化——一份从原型到上线的速查清单 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 hyperfine:命令行基准测试工具 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日
读:llm-test —— 用 LLM agent 驱动 Emacs 测试
2026-04-23 · via 暗无天日

Andrew Hyatt(Emacs 核心贡献者)最近开源了一个实验性项目1llm-test 。它的核心想法是——用 LLM 代替人来测试 Emacs 包。你用自然语言描述"用户应该看到什么",LLM agent 会启动一个干净的 Emacs 进程,像人一样操作它(按键、输入文字、执行命令),然后判断测试是否通过。

怎么工作

整个流程分四步:

  1. 用 YAML 文件写测试描述,就是一段英文说明要测什么、期望什么结果
  2. llm-test 解析 YAML,为每个测试描述注册一个 ERT 测试
  3. 运行测试时,启动一个 emacs -Q 的干净 daemon 进程
  4. LLM agent 通过 tool calling 驱动这个 Emacs,直到判定通过或失败
group: auto-fill mode
setup: |
  Enable auto-fill-mode in a text-mode buffer.
  Set fill-column to 40.
tests:
  - description: |
      Type a long paragraph that exceeds fill-column.
      Verify that the text is automatically wrapped.
  - description: |
      Type a numbered list item that exceeds fill-column.
      Verify that continuation lines are indented properly.

这个例子测试的是 auto-fill-mode :开一个文本 buffer,设置 fill-column 为 40,然后让 LLM 输入一段超过 40 列的文字,检查 Emacs 是否自动换行了。测试描述就是自然语言,不需要写一行 Elisp。

Agent 怎么"看" Emacs

LLM agent 看不到图形界面——测试 Emacs 是以 daemon 模式运行的。那它怎么知道 Emacs 当前什么状态?

答案是:每次 agent 执行完一个操作(按键、执行命令、eval 代码等), llm-test 会自动附加一份 JSON 格式的 frame 快照。这个快照包含当前所有窗口的可见内容(就像截图,但是文字版)、光标位置、minibuffer 状态和 echo area 消息。

{
  "selected-window": {"number": 0, "buffer": "<buffer name>"},
  "windows": [
    {
      "number": 0,
      "buffer": "<buffer name>",
      "mode": "<major mode>",
      "point": 1,
      "lines": ["<visual line 1>", "<visual line 2>"]
    }
  ],
  "minibuffer": {"active": false, "prompt": "", "input": ""},
  "message": "<echo area message>"
}

Agent 不需要主动请求"给我看看现在屏幕上有什么"——每次操作后自动收到。这让 agent 的行为更像真人:按了一个键,"看"到结果,决定下一步做什么。

Agent 可以调用的工具包括:

  • eval-elisp :在测试进程中执行任意 Elisp 并返回结果
  • send-keys :模拟按键(如 C-x C-fM-x
  • type-text :逐字输入文本(保留空格和特殊字符)
  • run-command :按名称执行命令(比 M-x 更可靠)
  • sleep :等待异步操作完成
  • suggest-improvement :记录 UI/UX 改进建议(不影响测试结果)
  • pass-test / fail-test :判定测试结果,结束循环

整个 agent loop 最多跑 80 轮( llm-test-max-iterations 默认值),每轮是一次 LLM 请求/响应往返。

跟传统测试的区别

传统的 Emacs 测试用 ERT(Emacs Lisp 测试框架),测试代码直接调用函数、检查返回值。比如测试 auto-fill ,你要写 Elisp 设置 buffer、插入文字、检查换行位置。这测的是 函数的行为

llm-test 测的是 用户的体验 。Agent 不知道你的内部函数怎么调用——它只知道按键、看屏幕、判断结果是否符合描述。这跟真实用户使用 Emacs 的方式一模一样。

这种思路的优势:

  • 能测传统测试很难覆盖的场景 :比如" M-x 输入命令时的补全是否正确"、" dired 中按 g 刷新后文件列表是否更新"——这些涉及多个命令组合和 UI 状态变化的交互流程,用 Elisp 写测试非常痛苦,用自然语言描述却很自然
  • 测试描述就是文档 :YAML 里的自然语言描述既是测试用例,也是用户行为的文档
  • 对被测代码零侵入 :不需要为测试暴露内部接口或写 test helper

但也有明显的代价:

  • 非确定性 :同一个测试跑两次,LLM 可能走不同的操作路径,甚至得出不同的结论。这不是传统测试的"确定性"范式
  • 成本 :每个测试都要多次调用 LLM API,一个测试组跑下来可能消耗不少 token
  • 速度 :每轮 agent loop 都是一次 API 调用,比直接 eval Elisp 慢几个数量级
  • 依赖模型质量 :Andrew Hyatt 在 README 中建议使用 Claude Sonnet 级别的模型,不过他指出只要指令足够清晰,便宜的模型也能胜任

"LLM 当测试员"的适用场景

llm-test 不会取代传统 ERT 测试。对于"函数 f(x) 输入 5 应该返回 10"这类确定性逻辑测试,Elisp 单元测试更快更准。

它适合的是另一类测试——那些"人一眼就能看出来对不对,但用代码描述很麻烦"的场景:

  • 包的 UI 工作流是否顺畅(按键 → 期望看到某个界面)
  • 多步骤交互的端到端验证(打开文件 → 编辑 → 保存 → 确认状态)
  • 发现 UI/UX 问题( suggest-improvement 工具让 agent 可以主动提出改进建议)

这个思路也可以延伸到其他 GUI 应用——只要你能给 LLM 提供"屏幕状态"和"操作接口",就能用同样的 agent loop 模式做测试。 llm-test 的 frame state JSON 快照设计就是一个很好的参考:不需要真的截图,把视觉信息结构化为文本就够了。