AI 时代代码的价值被严重低估一、新闻概述1. 标题AI 时代代码的价值被严重低估：自然语言的精确性陷阱2. 发布时间2026 年 3 月 21 日3. 来源Steve Krouse 技术博客二、核心内容1. 事件摘要A. 主要内容Steve Krouse 发表文章反驳"代码已死"的观点，深入探讨了 AI 时代编程的价值，以及自然语言规格与代码规格在精确性上的本质差异。B. 核心亮点自然语言规格存在精确性错觉Vibe Coding 在规模化时遭遇抽象泄漏抽象是掌握复杂性的关键工具AGI 时代仍需高质量代码和更好的抽象2. 关键信息A. 背景当前社会舆论普遍认为"编程已死"，甚至知名播客主持人 Sam Harris 也公开表示"没有人应该再学习编程"。B. 核心论点代码是精确思维的产物，不仅仅是生成软件的工具AI 的真正价值在于帮助我们创造更好的抽象编程在 AI 时代将迎来新的繁荣3. 背景介绍A. 相关概念Vibe Coding：指用自然语言描述想法，让 AI 生成代码，然后通过视觉反馈迭代调整的开发方式。B. 讨论起源文章引用了"A sufficiently detailed spec is code"的观点，用漫画展示了自然语言规格的精确性错觉。三、详细报道1. 自然语言的精确性陷阱A. 核心问题自然语言规格在直觉上让人感觉很精确，但实际经验会揭示其充满歧义的本质。引用 Bertrand Russell 的名言："Everything is vague to a degree you do not realize till you have tried to make it precise."B. 规格对比graph LR A[自然语言规格] -->|感觉精确| B[直觉理解] B -->|实际| C[充满歧义] C -->|导致| D[意外行为] D -->|揭示| E[抽象泄漏] F[代码规格] -->|强制精确| G[编译/执行] G -->|反馈| H[错误暴露] H -->|促进| I[迭代改进]C. 迭代精确化编程和写作一样，是迭代精化的活动。AI 能帮助我们将英语转化为可运行的代码，然后通过反应式调整逐步精确化我们的想法。2. Vibe Coding 的局限性A. 概念解析Vibe Coding 让人停留在英语层面的直觉感受，同时通过 AI 生成的产物来帮助精化思维。B. 潜在风险Vibe Coding 给人一种错觉：认为直觉感受就是精确的抽象。这种感觉会持续到抽象泄漏发生时——当你添加足够多的功能或达到足够大的规模时，你不理解的底层抽象的意外行为会悄悄出现，破坏整个系统。C. 实际案例Dan Shipper 的 vibe-coded 文本编辑器应用爆火后崩溃的经历表明："实时协作极其困难"。看似精确的规格背后，隐藏着巨大的复杂性。graph TB subgraph Vibe Coding 流程 A1[英语想法] --> A2[AI 生成代码] A2 --> A3[视觉反馈] A3 --> A4[迭代调整] end subgraph 隐藏的复杂性 B1[底层抽象] --> B2[意外行为] B2 --> B3[故障调试] end A4 -->|规模化时触发| B1D. 复杂性的隐蔽性复杂性可能极其无聊、令人不快，难以记住所有细节和边缘情况。例如 Slack 决定何时发送通知的经典流程图展示了通知逻辑的复杂性。3. 抽象的价值A. 认知限制人类大脑存在基本限制：我们一次只能思考 7 个（±2）事物。B. 抽象的作用思考超过 7 个事物的唯一方法是将多个事物压缩为一个事物。这种压缩可以递归应用，使人类能够掌握无限的复杂性。引用 Edsger Dijkstra 的名言："The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise."C. 抽象机制graph TD A[复杂系统] -->|通过抽象| B[压缩认知] B --> C[7±2 项] C -->|递归应用| D[多层抽象] D --> E[掌握无限复杂性] F[具体细节] -->|抽象为| G[语义层] G -->|实现精确性| H[高层概念]D. 最佳实践编程的最佳部分之一是提出越来越好的抽象来帮助我们掌握复杂性。例如 ReactJS 和 TailwindCSS 在各自领域通过抽象简化了开发。4. AGI 时代的编程A. 错误观点认为 AGI 到来后将不再需要关注细节，只需让 AI 处理所有麻烦。B. 正确理解代码不仅仅是软件的副产品，它本身就是重要的产物。当做得好时，代码是诗歌。C. 与写作类比没有人谈论"vibe writing"，没有人认为 ChatGPT 会取代伟大的小说家或记者。同样的逻辑适用于编程。graph LR subgraph AI 发展路径 A[当前 AI] -->|协助| B[生成代码] B --> C[理解抽象] C --> D[AGI] end subgraph AGI 时代的应用 D -->|首要任务| E[解决抽象难题] E --> F[更好的抽象库] F --> G[更高质量的代码] end H[传统观点] -->|误解| I[用 AI 生成更多低质代码] J[正确观点] -->|理解| K[用 AI 创造更好的抽象]D. AI 的正确用途帮助我们产生更好的代码解决最困难的抽象问题创造更好的抽象和库E. 成功案例作者使用 Opus 4.6 解决了 React Router 7 在 Val Town 中全栈工作的问题，创建了 vtrr 框架，用 50 行代码掌握了所有复杂性。四、影响分析1. 行业影响A. 技术趋势AI 将成为编程的强大助力编程门槛降低，但抽象思维价值提升高质量代码和良好设计变得更加重要B. 人才需求编程技能仍然必要但焦点从"写代码"转向"设计抽象"系统思维和架构能力变得更重要2. 教育启示A. 学习编程的价值编程是训练精确思维的有效方式理解抽象和复杂性管理是核心竞争力B. 课程方向应该更强调抽象设计教授如何创建良好的抽象培养系统思维能力3. 技术方向A. 工具演进AI 辅助编程工具将持续改进更好的抽象库和框架会出现开发效率将大幅提升B. 质量标准代码质量标准会提高可维护性和可理解性变得更重要好的抽象将成为核心竞争力五、各方观点1. 作者立场代码不会消亡，AI 将成为编程的巨大助力。编程才刚刚开始。2. 业内共识（错误）99% 的社会认为编程已死，包括 Sam Harris 等知名人士。3. 反驳观点这就像在印刷术发明时认为讲故事已死一样荒谬。六、经典引言1. Edsger Dijkstra"Instead of regarding the obligation to use formal symbols as a burden, we should regard the convenience of using them as a privilege: thanks to them, school children can learn to do what in earlier days only genius could achieve."2. Tony Hoare"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies."3. Charles Babbage"The quantity of meaning compressed into a small space by algebraic signs, is another circumstance that facilitates the reasonings we are accustomed to carry on by their aid."七、总结在 AI 时代，编程的价值不是被削弱，而是被重新定义。AI 不会取代编程，而是会帮助我们创造更好的抽象，更优雅地掌握复杂性。代码作为精确思维的产物，其价值将随着 AI 的发展而进一步提升。参考资料Reports of code's death are greatly exaggeratedA sufficiently detailed spec is codeWhen your vibe-coded app goes viral and then goes down
Linux 应用开发基础教程一、概述1. 简介A. 是什么《Linux Application Development By Example - The Fundamental APIs》是由 Arnold Robbins 编写的 Linux 应用程序开发教程书籍，第二版于 2026 年出版。本书通过大量示例代码，系统介绍 Linux 系统编程的核心 API 和开发技巧。B. 为什么学掌握 Linux 系统编程基础，理解操作系统工作原理学习 POSIX 标准 API，提升跨平台开发能力通过实例代码快速掌握复杂的系统调用概念培养底层思维，为学习高级框架打下坚实基础C. 学完能做什么开发 Linux 命令行工具和系统程序处理文件 I/O、进程管理、信号处理等系统级任务进行网络编程和国际化应用开发使用调试工具分析和修复程序问题2. 前置知识A. 必备技能C 语言基础：指针、结构体、内存管理基本 Linux 操作：命令行使用、文件系统概念编译工具使用：gcc、makeB. 推荐知识操作系统基础概念：进程、线程、虚拟内存POSIX 标准了解Git 版本控制二、书籍结构1. 内容组织本书共 17 章，涵盖 Linux 应用开发的各个方面：mindmap root((Linux 应用开发)) 基础入门 第1章 简介 第2章 命令行 第3章 内存 文件操作 第4章 文件IO 第5章 文件信息 第7章 ls 实现 进程管理 第9章 进程 第10章 信号 第12章 资源限制 系统功能 第6章 通用工具1 第8章 挂载 第13章 通用工具2 高级主题 第14章 网络 第15章 国际化 第16章 扩展属性 第17章 调试2. 章节概览章节目录主题第 1 章ch-01-intro入门示例，数学计算程序第 2 章ch-02-cmdline命令行参数处理，环境变量第 3 章ch-03-memory动态内存分配，地址空间第 4 章ch-04-fileio文件 I/O，系统调用与库函数第 5 章ch-05-fileinfo文件元数据，stat 系统调用第 6 章ch-06-general1通用工具：时间、用户信息第 7 章ch-07-ls实现 ls 命令第 8 章ch-08-mounting文件系统挂载第 9 章ch-09-processes进程创建与管理第 10 章ch-10-signals信号处理第 12 章ch-12-limits系统资源限制第 13 章ch-13-general2更多通用工具第 14 章ch-14-networking网络编程基础第 15 章ch-15-i18n国际化与本地化第 16 章ch-16-extended扩展属性第 17 章ch-17-debugging调试技巧与工具三、核心概念1. 系统调用与库函数Linux 编程中区分两类函数：A. 系统调用直接进入内核态执行开销较大，需要上下文切换提供核心功能：文件操作、进程管理、网络通信B. 库函数在用户态执行通常封装系统调用，提供更友好的接口标准 C 库函数：printf、malloc、fopengraph TB A[应用程序] --> B{函数类型} B -->|库函数| C[glibc 等] B -->|系统调用| D[内核] C --> D D --> E[硬件资源]2. Linux 编程模型A. 一切皆文件普通文件、目录、设备、套接字都通过文件描述符访问标准 I/O：stdin（0）、stdout（1）、stderr（2）B. 进程模型进程是资源分配的基本单位fork + exec 创建新进程父子进程关系与等待机制C. 权限模型用户 ID 和组 ID文件权限：rwx 权限位setuid/setgid 机制四、快速上手1. 获取代码克隆本书的代码仓库：git clone https://github.com/arnoldrobbins/LinuxByExample-2e.git cd LinuxByExample-2e2. 编译示例各章节目录包含独立的示例程序，使用 gcc 编译：cd ch-01-intro gcc -o sindegrees ch-intro-sindegrees.c -lm ./sindegrees3. 代码风格说明命名规范：ch-<章节名>-<功能描述>.c头文件：ch-<章节名>-<功能描述>.h测试程序：ch-<章节名>-<功能>-test*.c脚本文件：功能描述.sh五、重点章节解析1. 第 1 章：入门示例A. 数学计算程序该章实现一个角度与弧度转换的程序，展示基本的 C 程序结构和数学库使用。核心代码结构：主程序：ch-intro-sindegrees.c头文件：ch-intro-sindegrees.h测试程序：多个测试版本2. 第 2 章：命令行处理A. main 函数参数int main(int argc, char *argv[])argc：参数个数argv：参数值数组argv[0]：程序名称argv[1] 到 argv[argc-1]：实际参数B. 环境变量extern char **environ;访问环境变量的两种方式：全局变量 environgetenv/setenv 函数示例程序：ch-cmdline-printenv.c（实现 printenv 命令）3. 第 3 章：内存管理A. 动态内存分配void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); void free(void *ptr);B. 内存地址程序地址空间布局：代码段只读数据段全局数据段堆（向上增长）栈（向下增长）graph TB subgraph "进程地址空间" A[高地址] B[栈] C[空闲区域] D[堆] E[未初始化数据 BSS] F[已初始化数据] G[代码段] H[低地址] end B -->|向下增长| C D -->|向上增长| C4. 第 4 章：文件 I/OA. 系统调用int open(const char *pathname, int flags, mode_t mode); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); int close(int fd);B. 库函数FILE *fopen(const char *path, const char *mode); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); int fclose(FILE *stream);C. 选择建议场景推荐使用原因二进制文件系统调用精确控制文本文件库函数缓冲提高效率设备文件系统调用直接访问普通应用库函数可移植性好5. 第 9 章：进程管理A. 创建进程sequenceDiagram participant P as 父进程 participant K as 内核 participant C as 子进程 P->>K: fork() K->>C: 创建子进程 C-->>P: 返回子进程 PID P->>P: 父进程中返回子进程 PID C->>C: 子进程中返回 0 C->>K: exec(program) K->>C: 加载新程序B. fork 函数pid_t fork(void);调用一次，返回两次父进程中返回子进程 PID子进程中返回 0失败返回 -1C. exec 函数族int execl(const char *path, const char *arg, ...); int execv(const char *path, char *const argv[]); int execle(const char *path, const char *arg, ...); int execve(const char *path, char *const argv[], char *const envp[]);替换当前进程映像为新程序。6. 第 10 章：信号处理A. 常见信号信号值默认动作说明SIGINT2终止Ctrl+CSIGQUIT3终止+coreCtrl+\SIGKILL9终止强制杀死SIGTERM15终止终止信号SIGCHLD17忽略子进程状态改变B. 信号处理typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);处理方式：SIG_DFL：默认处理SIG_IGN：忽略信号自定义函数：捕获信号7. 第 14 章：网络编程A. 套接字 APIint socket(int domain, int type, int protocol); int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);B. 客户端-服务器模型sequenceDiagram participant C as 客户端 participant S as 服务器 C->>S: socket() S->>S: socket() S->>S: bind() S->>S: listen() C->>S: connect() S->>S: accept() C-->>S: 请求数据 S-->>C: 响应数据 C->>C: close() S->>S: close()六、开发工具1. 编译工具A. gcc# 基本编译 gcc -o program program.c # 启用所有警告 gcc -Wall -Wextra -o program program.c # 链接数学库 gcc -o program program.c -lm # 生成调试信息 gcc -g -o program program.c # 优化编译 gcc -O2 -o program program.cB. make自动化构建工具，使用 Makefile 管理编译规则。2. 调试工具A. gdb# 启动调试 gdb ./program # 常用命令 break main # 设置断点 run # 运行程序 next # 单步执行 print variable # 打印变量 backtrace # 查看调用栈B. strace跟踪系统调用：strace ./programC. ltrace跟踪库函数调用：ltrace ./program七、最佳实践1. 错误处理// 检查系统调用返回值 if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } // 检查库函数返回值 if ((ptr = malloc(size)) == NULL) { fprintf(stderr, "malloc failed\n"); exit(EXIT_FAILURE); }2. 资源管理// 确保释放资源 FILE *fp = fopen("file.txt", "r"); if (fp == NULL) { perror("fopen"); return -1; } // 使用文件 process_file(fp); // 关闭文件 fclose(fp);3. 可移植性使用 POSIX 标准接口避免使用平台特定扩展使用条件编译处理平台差异#ifdef __linux__ // Linux 特定代码 #elif defined(__APPLE__) // macOS 特定代码 #endif八、进阶主题1. 多线程编程虽然本书主要关注进程，但现代 Linux 编程中线程也很重要：pthread_create() pthread_join() pthread_mutex_lock() pthread_mutex_unlock()2. 异步 I/O// POSIX AIO aio_read() aio_write() aio_error() aio_return()3. 高级网络编程非阻塞 I/OI/O 多路复用（select/poll/epoll）零拷贝技术九、学习建议1. 学习路径graph LR A[C 语言基础] --> B[第1-3章 入门基础] B --> C[第4-5章 文件操作] C --> D[第6-8章 通用工具] D --> E[第9-10章 进程信号] E --> F[第12-13章 资源限制] F --> G[第14-17章 高级主题]2. 实践建议动手编译运行每个示例程序修改代码，观察不同行为使用调试工具跟踪程序执行尝试实现类似功能的程序3. 扩展阅读《Advanced Programming in the UNIX Environment》《The Linux Programming Interface》Linux 手册页：man pagesPOSIX 标准文档参考资料LinuxByExample-2e GitHub 仓库Linux 手册页POSIX 标准规范
从零重建 VisiCalc 电子表格软件一、概述1. 项目背景A. VisiCalc 的历史意义VisiCalc 是世界上第一款电子表格软件，由 Dan Bricklin 和 Bob Frankston 于 1979 年创造。这款软件仅用数千行 6502 汇编代码编写，却能在 16KB 内存的机器上运行。它成为 Apple II 的杀手级应用，销量超过 100 万份，将早期的个人电脑转变为真正的商业工具。B. 电子表格的设计理念电子表格被誉为史上最佳用户体验设计之一。它具有极简的学习曲线，允许用户快速操作数据、描述逻辑、可视化结果，甚至可以用它创作艺术和运行 GameBoy 模拟器。C. 本文目标从零开始构建一个最小化的 VisiCalc 克隆版本，探索电子表格的核心设计原理。最终实现将包含完整的数据模型、公式求值器和简单的终端用户界面。2. 核心问题如何用最少的代码实现一个功能完整的电子表格系统，需要解决以下问题：如何表示和存储单元格数据如何解析和计算数学公式如何处理单元格间的依赖关系如何构建高效的用户界面二、系统设计1. 核心概念电子表格系统由以下几个基本概念组成：单元格（Cell）：表格的基本单位，可存储值、公式或标签网格（Grid）：单元格的二维集合公式（Formula）：引用其他单元格的数学表达式响应式计算：当单元格值变化时自动重新计算相关公式2. 数据模型设计A. 单元格结构每个单元格可以处于四种状态之一：空、数值、标签或公式。#define MAXIN 128 // 单元格输入最大长度 enum { EMPTY, NUM, LABEL, FORMULA }; // 单元格类型 struct cell { int type; // 单元格类型 float val; // 数值 char text[MAXIN]; // 原始用户输入 };B. 网格结构Excel 有 1,048,576 行和 16,384 列的限制，原始 VisiCalc 有 256 行和 64 列。我们的迷你版本可以使用更小的尺寸：#define NCOL 26 // 最大列数 (A..Z) #define NROW 50 // 最大行数 struct grid { struct cell cells[NCOL][NROW]; };3. 系统架构graph TB subgraph 用户界面 UI[TUI 界面] Input[输入处理] end subgraph 核心引擎 Grid[网格数据] Parser[公式解析器] Recalc[重新计算] end subgraph 数据模型 Cell[单元格] Formula[公式] end UI --> Input Input --> Grid Grid --> Parser Parser --> Recalc Recalc --> Grid Grid --> Cell Cell --> Formula三、公式求值器1. 解析器设计使用递归下降解析器（Recursive Descent Parser）来计算公式。解析器需要能够：识别数字和单元格引用处理运算符优先级支持函数调用访问网格中的单元格值A. 解析器结构struct parser { const char* s; // 公式字符串 int pos; // 当前位置 struct grid* g; // 网格引用 };2. 语法解析层次公式解析遵循经典的运算符优先级规则：表达式（Expression）：由加法和减法连接的项项（Term）：由乘法和除法连接的因子因子（Factor）：数字、单元格引用、函数调用或括号表达式graph TD A[表达式 Expression] --> B[项 Term] B --> C[因子 Factor] C --> D[数字 Number] C --> E[单元格引用 CellRef] C --> F[函数调用 Function] C --> G[括号表达式 ParenExpr] B -->|+/-| B A -->|*//| A3. 解析实现A. 因子解析因子是最基本的语法单位，可以是：带符号的一元运算函数调用（以 @ 开头）括号表达式数字字面量单元格引用float primary(struct parser* p) { skipws(p); if (!*p->p) return NAN; // 处理一元加号 if (*p->p == '+') p->p++; // 处理一元减号 if (*p->p == '-') { p->p++; return -primary(p); } // 函数调用 if (*p->p == '@') { p->p++; return func(p); } // 括号表达式 if (*p->p == '(') { p->p++; float v = expr(p); skipws(p); if (*p->p != ')') return NAN; p->p++; return v; } // 数字字面量 if (isdigit(*p->p) || *p->p == '.') return number(p); // 单元格引用 return cellval(p); }B. 项解析处理乘法和除法运算：float term(struct parser* p) { float l = primary(p); for (;;) { skipws(p); char op = *p->p; if (op != '*' && op != '/') break; p->p++; float r = primary(p); if (op == '*') l *= r; else if (r == 0) return NAN; else l /= r; } return l; }C. 表达式解析处理加法和减法运算：float expr(struct parser* p) { float l = term(p); for (;;) { skipws(p); char op = *p->p; if (op != '+' && op != '-') break; p->p++; float r = term(p); l = (op == '+') ? l + r : l - r; } return l; }4. 单元格引用解析将单元格地址（如 A1、AB123）转换为网格坐标：int ref(const char* s, int* col, int* row) { const char* p = s; // 解析列字母 if (!isalpha(*p)) return 0; *col = toupper(*p++) - 'A'; if (isalpha(*p)) *col = *col * 26 + (toupper(*p++) - 'A'); // 解析行数字 char* end; int n = strtol(p, &end, 10); if (n <= 0 || end == p) return 0; *row = n - 1; return (int)(end - s); }5. 函数支持支持基本的内置函数：@SUM：求和函数，支持范围参数（如 @SUM(A1...C3)）@ABS：绝对值函数@INT：取整函数@SQRT：平方根函数四、响应式计算1. 计算依赖问题电子表格的核心特性是响应式计算：当某个单元格的值发生变化时，所有引用该单元格的公式都应该自动重新计算。2. VisiCalc 的解决方案原始 VisiCalc 受限于 16KB 内存，采用了简单而有效的策略：每次单元格更新时重新计算整个表格用户可以选择按行优先或按列优先的计算顺序对于复杂依赖，建议用户多次运行手动重新计算命令3. 自动迭代计算现代实现可以自动化这个过程，运行多次迭代直到没有新的变化：graph TD A[单元格更新] --> B[开始重新计算] B --> C[遍历所有单元格] C --> D{单元格是否为公式?} D -->|是| E[重新计算公式值] D -->|否| C E --> F{值是否改变?} F -->|是| G[标记已变化] F -->|否| C G --> C C --> H{是否遍历完成?} H -->|否| C H -->|是| I{是否有变化?} I -->|是| B I -->|否| J[完成]实现代码void recalc(struct grid* g) { for (int pass = 0; pass < 100; pass++) { int changed = 0; for (int r = 0; r < NROW; r++) for (int c = 0; c < NCOL; c++) { struct cell* cl = &g->cells[c][r]; if (cl->type != FORMULA) continue; struct parser p = {cl->text, cl->text, g}; float v = expr(&p); if (v != cl->val) changed = 1; cl->val = v; } if (!changed) break; } }五、单元格设置1. 输入分类根据用户输入的第一个字符，自动判断单元格类型：以 +、-、( 或 @ 开头：公式以数字或小数点开头：数值其他：标签void setcell(struct grid* g, int c, int r, const char* input) { struct cell* cl = cell(g, c, r); if (!cl) return; // 空输入清空单元格 if (!*input) { *cl = (struct cell){0}; recalc(g); return; } // 保存原始输入 strncpy(cl->text, input, MAXIN - 1); // 分类输入类型 if (input[0] == '+' || input[0] == '-' || input[0] == '(' || input[0] == '@') { cl->type = FORMULA; } else if (isdigit(input[0]) || input[0] == '.') { char* end; double v = strtod(input, &end); cl->type = (*end == '\0') ? NUM : LABEL; if (cl->type == NUM) cl->val = v; } else { cl->type = LABEL; } // 触发重新计算 recalc(g); }2. 测试用例struct grid g = {0}; // 设置 A1=5, A2=7, A3=11, A4=@SUM(A1...A3) setcell(&g, 0, 0, "5"); setcell(&g, 0, 1, "7"); setcell(&g, 0, 2, "11"); setcell(&g, 0, 3, "+@SUM(A1...A3)"); assert(g.cells[0][3].val == 23.0f); // 修改值，总和应重新计算 setcell(&g, 0, 0, "5"); setcell(&g, 0, 1, "+A1+5"); setcell(&g, 0, 2, "+A2+A1"); assert(g.cells[0][3].val == 5.0f + 10.0f + 15.0f); // 修改 A1，所有公式应重新计算 setcell(&g, 0, 0, "7"); assert(g.cells[0][3].val == 7.0f + 12.0f + 19.0f);六、用户界面1. 界面布局VisiCalc 的屏幕分为四个区域，垂直排列：graph TB subgraph VisiCalc 界面 S[状态栏: 单元格地址 + 值/公式 + 模式] E[编辑行: 当前输入或单元格内容] H[列标题: A, B, C, ...] G[网格区域: 单元格内容 + 行号] end2. 视口设计由于网格可能比终端屏幕大，需要实现滚动视口：#define CW 9 // 列显示宽度 #define GW 4 // 行号栏宽度 // 可见的行列数 int vcols(void) { return (COLS - GW) / CW; } int vrows(void) { return LINES - 4; } struct grid { struct cell cells[NCOL][NROW]; int cc, cr; // 光标列、行 int vc, vr; // 视口左上角 };3. 视口滚动逻辑当光标移动到屏幕外时，视口自动跟随：// 水平滚动 if (g.cc < g.vc) g.vc = g.cc; if (g.cc >= g.vc + vcols()) g.vc = g.cc - vcols() + 1; // 垂直滚动 if (g.cr < g.vr) g.vr = g.cr; if (g.cr >= g.vr + vrows()) g.vr = g.cr - vrows() + 1;4. 渲染实现A. 状态栏显示当前单元格地址、值或公式，以及当前模式：// 状态栏：单元格地址 + 值 + 模式指示器 attron(A_BOLD | A_REVERSE); mvprintw(0, 0, " %c%d", 'A' + g->cc, g->cr + 1); if (cur->type == FORMULA) printw(" %s = %.10g", cur->text, cur->val); mvprintw(0, COLS - 6, mode == ENTRY ? "ENTRY" : "READY"); attroff(A_BOLD | A_REVERSE);B. 编辑行显示当前输入或单元格内容：if (mode) mvprintw(1, 0, "> %s_", buf); else if (cur->type != EMPTY) mvprintw(1, 0, " %s", cur->text);C. 列标题和网格绘制列标题（A、B、C...）和网格内容：// 列标题 attron(A_BOLD | A_REVERSE); for (int c = 0; c < vcols(); c++) mvprintw(2, GW + c * CW, "%*c", CW, 'A' + g->vc + c); attroff(A_BOLD | A_REVERSE); // 网格单元格 for (int r = 0; r < vrows() && g->vr + r < NROW; r++) { int row = g->vr + r, y = 3 + r; // 行号栏 attron(A_REVERSE); mvprintw(y, 0, "%*d ", GW - 1, row + 1); attroff(A_REVERSE); // 单元格内容 for (int c = 0; c < vcols() && g->vc + c < NCOL; c++) { int col = g->vc + c; struct cell* cl = cell(g, col, row); // 格式化显示 int is_cur = (col == g->cc && row == g->cr); if (is_cur) attron(A_REVERSE); mvprintw(y, GW + c * CW, "%s", formatted_buf); if (is_cur) attroff(A_REVERSE); } }七、输入处理1. 模态界面设计VisiCalc 采用模态界面设计，用户处于两种模式之一：READY 模式：在网格中导航ENTRY 模式：编辑单元格内容2. 特殊字符处理在 READY 模式下，以下字符有特殊含义：/：进入命令模式（/B 清空、/Q 退出、/F 格式化）：进入跳转模式（输入单元格地址如 B5 并按 Enter）其他可打印字符：进入单元格编辑模式3. 命令模式实现if (ch == '/') { mvprintw(1, 0, "Command: /"); refresh(); ch = getch(); if (toupper(ch) == 'Q') break; // 退出 if (toupper(ch) == 'B') { // 清空单元格 *cell(&g, g.cc, g.cr) = (struct cell){0}; recalc(&g); } if (toupper(ch) == 'F') { // 格式化 // 格式化命令处理 } }4. 确认和导航在 ENTRY 模式下：Enter：确认输入并向下移动Tab：确认输入并向右移动if (ch == 10 && mode == ENTRY) { setcell(&g, g.cc, g.cr, buf); if (g.cr < NROW - 1) g.cr++; mode = READY; }八、实现总结1. 核心功能通过约 500 行 C 代码，我们实现了：完整的单元格数据模型递归下降公式解析器自动迭代重新计算机制模态 TUI 用户界面视口滚动和渲染2. 未实现功能完整版本还可以添加：文件 I/O/R 复制命令（批量复制公式）更多内置函数移动和删除行列更复杂的格式化选项3. 设计启示VisiCalc 的设计历经 47 年仍然有效，证明了其核心设计的优雅和简洁。关键设计原则包括：极简的数据模型响应式计算直观的用户界面高效的实现方式参考资料VisiCalc reconstructed - zserge.comkalk - VisiClone implementation on GitHubWorld smallest office suite
生活在平面国的程序员一、概述1. 文章简介A. 标题The programmers who live in Flatland（生活在平面国的程序员）B. 发布时间2025 年 11 月 24 日C. 来源Red Planet Labs 博客D. 作者Nathan Marz（Clojure 专家、Rama 框架创始人）2. 核心隐喻文章借用 Edwin Abbott 的经典小说《Flatland：A Romance of Many Dimensions》中的概念：二维世界的居民无法理解第三维度的存在。作者将此隐喻延伸到编程领域——许多程序员受限于自己的"维度"，无法理解更强大的编程抽象。3. 文章主旨大多数程序员生活在"编程平面国"中，他们无法理解 Lisp/Clojure 宏（macros）所代表的更高维度的编程能力。这并非因为宏没有价值，而是因为他们缺乏理解这种抽象所需的"表征机制"。二、背景故事：Paul Graham 与 Lisp1. Beating the Averages2001 年，Paul Graham 发表著名文章《Beating the Averages》，核心论点包括：A. Lisp 的根本优势Lisp 比其他语言本质上更强大宏（macros）是 Lisp 的核心区分能力Viaweb 使用 Lisp 构建了竞争对手无法实现的功能B. 作者的亲身体验Nathan Marz 受这篇文章影响，过去 15 年一直将 Clojure 作为主要编程语言。他证实 Paul Graham 关于宏的描述"绝对正确"。2. 现实困境A. 采用率极低Lisp/Clojure 全球使用比例极小（Stack Overflow 调查显示约 2.6%）与其巨大的优势不成正比B. 常见误解"生态系统"障碍：对 Common Lisp 有效，但 Clojure 可与 Java 生态系统互操作"括号很怪"的直观反应括号的感知成本从未与 Clojure 的巨大收益进行权衡C. Blub ParadoxPaul Graham 提出的"Blub 悖论"试图解释这种脱节，本文从另一个角度补充这个解释。三、编程的维度1. 两类抽象A. 自动化抽象大多数程序员使用的抽象属于此类：将一组操作打包在一个名称后面函数是经典例子：接受输入，产生输出只需要了解函数的规格和性能特征B. 维度扩展抽象罕见的抽象类型：扩展编程本身的代数改变基本概念和概念间关系的种类创造新的"维度"2. Lisp/Clojure 宏的维度之力A. 语言的自我组合源于语言的统一性，使语言能够自我组合：编译时逻辑可以像运行时一样执行使用相同的函数和技术语法树可以被操纵和转换B. 语义控制实现对代码语义本身的控制：宏不仅仅是语法糖它们改变了代码的结构和含义可以创造全新的控制结构C. 编译时的轻松操纵effortless compile-time manipulation 是一个新的编程维度：编译时代码生成变得简单元编程成为一等公民运行时和编译时的界限变得模糊3. Flatland 隐喻graph LR subgraph Flatland["2D 平面国"] F1[三角形] F2[正方形] F3[圆形] end subgraph Spaceland["3D 空间国"] S[球体] end S -.-> F1 S -.-> F2 S -.-> F3在 Flatland 中，正方形无法理解第三维度，因为他只能以 2D 思考。同样，你无法理解新的编程维度，因为你不知道如何在该维度中思考。你没有"表征机制"来理解新维度提供的东西。2D 程序员可能会得出 3D 概念客观上错误的结论——这不是因为他们理解了它，而是因为他们试图将其扁平化到自己的坐标系中。四、学习新维度1. 说服的局限性你不能用 3D 论据说服 2D 的人。这就像在 Flatland 中，球体无法让正方形理解"上"和"下"的含义。2. 隐喻的断裂点然而，这正是隐喻失效的地方：你的大脑永远无法理解 4D 空间但你的大脑可以适应新的编程维度3. Lisp 学习曲线采用 Lisp/Clojure 的人通常描述相似的经历：graph LR A[不适感] --> B[一系列清晰时刻] B --> C[无法回头的顿悟] C --> D[新维度的思维方式]A. 第一阶段：不适感语法看起来"奇怪"编程范式不同需要改变思维习惯B. 第二阶段：清晰时刻逐渐理解宏的威力开始看到代码抽象的新可能性意识到之前方法的局限性C. 第三阶段：无法回头新维度的思维成为自然回到旧语言感觉受限理解了什么是真正的编程抽象4. 突破认知偏见需要的只是：好奇心理解最好的编程思想有时无法立即被欣赏识别自己的认知偏见认识到这种偏见足以打破它，这是作为程序员成长的最好方式之一。五、社区讨论与反馈1. Valerie Kim：Laws of Form 的类比A. 稀有抽象的概念文章中关于"稀有抽象"的论述让她想起 George Spencer-Brown 的《Laws of Form》（1969）。B. 形式系统的维度扩展即使是最简单的形式系统（一个符号、两个规则、约一个值），在引入"重新进入"（re-entry）的自指扩展后，也能获得全新的维度：类似于引入虚数 i 作为 x = -1/x 的解宏本质上是自指的它们提供了引入新区分（概念）的强大方式2. ao：实用主义的质疑A. 维护成本论点实际程序在其生命周期中经常被修改修改的成本和速度很重要宏像"魔法"：难以快速理解B. Blub 语言的优势可能更冗长，但显式更容易找到替代开发者更快地进行更改C. 维度的代价第三维度需要很多时间，用户并不总是愿意为此付费。这就像大多数人通勤使用道路车辆而不是飞机。D. Viaweb 的后续据互联网消息，Yahoo 在长期维护中将 Viaweb 从 Lisp 迁移到主流技术栈。3. Nathan Marz 的回应A. "魔法"与"难以理解"的误解这是混淆了糟糕的使用与思想本身：可以用宏写出糟糕的代码，就像任何语言构造一样宏确实能让你写出更糟糕的代码但这不是反对宏的论据，你可以选择不写糟糕的代码B. 宏的使用原则Lisp 中有句俗话："宏的第一条规则是不要使用宏"：绝对正确除非需要，否则不应使用当你使用它们时，你在做任何其他语言构造都无法很好完成的事情C. Specter 项目示例一个项目中的关键宏实现了：极具表现力的抽象难以匹配的性能即使是手写优化代码也难以匹敌D. 知情决策的缺失确实有少数程序员理解 Lisp/Clojure 并做出知情决定不使用它们但大多数程序员没有花时间真正理解它们的益处只有约 2.6% 的开发者使用 Lisp 或 Clojure作者怀疑甚至不到 5% 的程序员真正理解 Lisp/Clojure 足以做出知情决定E. 团队入职经验在 Red Planet Labs 的亲身经验：如果大型 Clojure 代码库编写良好，让开发者入职不是问题即使是新学习 Clojure 的开发者也能适应有调整期，但任何大型代码库都有调整期当学习新的编程范式时，调整期可能更强烈，但这是值得的Clojure 中的开发速度高于其他语言，因为能够构建更好的核心抽象宏是重要因素，Clojure 对不可变性的强调也是六、结论1. 选择权最终，生活在 Flatland 是一个选择。2. 关键时刻选择出现在你注意到自己对不熟悉思想的本能退缩时，当你感觉到"这没有意义"和"也许我还没有概念来理解它"之间的张力时。3. 定义时刻你在那一刻做的事情定义了你是留在 Flatland 还是走出它。4. 更广泛的启示宏不是唯一具有这种维度转移品质的伟大编程思想：函数式编程的概念类型系统的抽象并发模型领域特定语言（DSL）每一个伟大的编程思想都可能遇到同样的"Flatland 效应"。关键在于保持开放的心态，认识到自己的认知局限，并愿意投入时间去理解新的维度。参考资料The programmers who live in Flatland - Red Planet Labs Blog
足够详细的规范就是代码一、新闻概述1. 标题足够详细的规范就是代码2. 发布时间2026 年 3 月 17 日3. 来源Haskell for all 技术博客二、核心内容1. 事件摘要A. 主要内容本文作者以批判的视角分析了"从规范文档生成代码"（agentic coding）的理念，认为这种做法本质上是在重蹈历史覆辙——试图用自然语言替代精确的代码表达。B. 核心亮点指出 agentic coding 宣传的两个常见误解以 OpenAI 的 Symphony 项目为案例，剖析其"规范文档"的本质引用 Dijkstra 的理论，说明精确描述必然演变为代码通过实际测试证明，即使非常详细的规范也无法可靠生成工作代码2. 关键信息A. 涉及项目OpenAI Symphony：一个声称从规范文档生成的 agent 编排器B. 核心论点当规范文档足够精确到能可靠生成实现时，它必然扭曲成代码或类似代码的形式规范文档从来不是省时工具，如果追求交付速度，直接写代码更有效C. 技术术语Agentic coding：基于 AI agent 的代码生成Specification：规范文档Narrow interfaces：狭义接口（即代码）3. 背景介绍A. 相关上下文近年来，业界兴起"从自然语言规范生成代码"的理念，宣传工程师可以转变为编写规范的"管理者"，而由 AI agent 完成编码工作。B. 作者立场作者对此持反对意见，认为这是对软件工程本质的误解。三、详细报道1. 主要内容A. 两个常见误解误解 1：规范文档比对应代码更简单Agentic coding 推广者常将此理念卖给相信者，让他们幻想工程师变成管理者，只需编写规范文档后交给 agent 团队执行。这只有在规范工作比实际编码更便宜时才成立。误解 2：规范工作必须比编码工作更深思熟虑推广者用此观点说服怀疑者，声称通过规范文档过滤工作能提高质量并促进更好的工程实践。B. Symphony 案例分析OpenAI 的 Symphony 项目被宣传为从规范文档生成项目的范例。其所谓的"规范文档"（SPEC.md）实际上更像 Markdown 形式的伪代码，而非传统意义上的规范。文档包含：数据库 schema 的散文描述：列出字段名、类型、约束代码的散文描述：如并发控制、重试逻辑专门为模型代码生成添加的"速查表"部分完整的算法代码块示例：服务启动算法function start_service(): configure_logging() start_observability_outputs() start_workflow_watch(on_change=reload_and_reapply_workflow) state = { poll_interval_ms: get_config_poll_interval_ms(), max_concurrent_agents: get_config_max_concurrent_agents(), running: {}, claimed: set(), retry_attempts: {}, completed: set(), codex_totals: {input_tokens: 0, output_tokens: 0, total_tokens: 0, seconds_running: 0}, codex_rate_limits: null } ...C. Dijkstra 理论支持Edsger W. Dijkstra 在 EWD667 文章中解释了为何精确描述必然演变为代码：数学史表明，希腊数学停留在口头和图形阶段，穆斯林代数在符号化尝试后因回归修辞风格而消亡，现代文明世界只有在西欧摆脱中世纪经院主义后才能兴起。软件工程同理，试图用自然语言追求精确性是徒劳的。2. 技术细节A. 规范与代码的关系graph LR A[自然语言想法] --> B{足够精确?} B -->|否| C[模糊规范] B -->|是| D[结构化形式] D --> E[伪代码] D --> F[形式化规范] E --> G[实际代码] F --> G C --> H[生成失败/不完整]B. 实际测试结果作者尝试使用 Claude Code 按照 Symphony 规范生成 Haskell 实现，结果：存在多个 bug，需要多次提示修复即使"成功"运行，codex agent 也只是静默旋转，无法处理 Linear 工单结果存储在 Gabriella439/symphony-haskell 仓库C. 其他规范示例YAML 规范极其详细、广泛使用、包含一致性测试套件，但大多数 YAML 实现仍不完全符合规范。这印证了精确规范不等于可靠实现。3. 数据与事实A. 规范文档规模Symphony 规范文档长度：已达到所含 Elixir 实现的 1/6若继续扩展，将重演博尔赫斯"论科学的精确性"中的荒谬故事B. 代码质量问题作者指出 Symphony 规范中充斥着"AI 产物"的痕迹：代码片段标注为 text 而非代码块缺乏连贯性、目的感和对全局的理解例如第 10.5 节的"规范形"句子杂乱堆砌四、影响分析1. 行业影响A. 技术趋势Agentic coding 运动试图将工程师转变为规范编写者，但这忽视了软件工程对精确性的内在需求。B. 工程实践过度依赖规范文档可能导致：规范本身质量下降（为求快而牺牲思考）生成代码质量不稳定维护成本增加2. 用户影响A. 工程师被误导以为可以"外包"编码工作实际上需要投入与编码相当的精力编写精确规范B. 团队在追求速度的工程文化中，规范质量无法保证"垃圾输入，垃圾输出"原则依然适用3. 技术趋势A. 根本问题代码就是规范最精确的表达形式。试图绕过这一本质是徒劳的。B. 前景AI 辅助编码有价值，但不应寄望于完全替代精确思维和直接编码。五、各方反应1. 作者立场规范文档从来不是省时设备。如果优化交付时间，直接写代码比通过中间规范文档更有效。2. 业内观点A. 支持 Agentic Coding认为规范能提高质量、减少编码工作、让工程师转向更高层抽象。B. 反对意见强调精确描述必然演变为代码，规范质量决定生成质量。六、相关链接1. 相关项目OpenAI Symphony 项目Symphony Haskell 实现2. 参考资料Dijkstra EWD667YAML 规范参考资料A sufficiently detailed spec is code - Haskell for all
每一层审查让你慢 10 倍一、新闻概述1. 标题每一层审查让你慢 10 倍2. 发布时间2026 年 3 月 16 日3. 来源apenwarr.ca（Avery Pennarun 的个人博客）二、核心内容1. 事件摘要A. 主要内容Tailscale CEO Avery Pennarun 发表观点文章，指出软件开发中每一层审查都会让流程变慢 10 倍。文章分析了为什么 AI 代码生成无法解决这一瓶颈，并提出了通过减少审查层级和建立信任文化来提高开发效率的方案。B. 核心亮点每一层审查会让流程慢 10 倍（按实际时间计算，而非工作量）AI 的加速作用被后续审查等待时间抵消传统 QA（质量保证）模式反而会降低质量通过模块化和小组信任文化替代多层级审查2. 关键信息A. 版本号/发布内容这是一篇博客观点文章，非产品发布B. 重要数据简单 Bug 修复：30 分钟同事代码审查：300 分钟（5 小时）设计文档批准：50 小时（约 1 周）跨团队协调：500 小时（12 周，一个季度）高管决策：10 个季度（约 2.5 年）C. 涉及产品/技术软件开发流程、代码审查、质量保证、AI 编码助手、模块化架构3. 背景介绍A. 前置版本/历史作者 Avery Pennarun 之前有多篇关于系统设计的文章，本文是其系统设计系列的延续，特别关注 LLM（大型语言模型）时代的软件工程问题。B. 相关上下文随着 Claude Code 等 AI 编码工具的兴起，软件开发速度大幅提升，但传统的审查流程成为新的瓶颈。三、详细报道1. 主要内容A. 审查层级的速度衰减规律作者提出一个经验法则：每一层审查会让流程变慢 10 倍。这里的变慢指的是实际时间，而非工作量。大部分额外时间都花在等待上。具体示例：graph LR A[简单 Bug 修复 30 分钟] --> B[同事代码审查 300 分钟] B --> C[设计文档批准 3000 分钟] C --> D[跨团队协调 30000 分钟] D --> E[高管决策 75000 分钟]B. AI 无法解决等待延迟问题AI 编码工具可以将编码时间从 30 分钟缩短到 3 分钟，但：如果开发者用节省的时间自己审查 AI 生成的代码，仍然是循环等待如果直接提交未验证代码，审查者仍需 5 小时，且会因阅读低质量代码而不满如果用于大型项目，代码太长无法一次审查，需要拆分为多个小块，每个都有 5 小时审查周期C. QA（质量保证）的悖论作者引用 W. E. Deming 的质量管理哲学，指出传统 QA 模式的问题：在工厂环境中，如果每一轮 QA 能捕获 90% 的缺陷，理论上两轮就能减少 100 倍缺陷。但现实中的问题：第一道 QA 知道有第二道 QA，会降低工作标准第二道 QA 不愿过于严格，因为这会影响同事的评价生产人员知道有 QA 检查，会降低生产时的质量控制这种"多层检查"模式实际上激励了质量控制的外部化，而非内部化。D. 日本汽车制造业的启示著名的丰田生产系统完全取消了专门的 QA 阶段，而是给每个工人一个"停止生产线"按钮。当发现缺陷时，任何人都可以停止生产线进行修复。美国汽车制造商试图复制这一系统，安装了同样的按钮，但没有人敢使用，因为害怕被解雇。关键差异在于信任：员工信任上级真心希望了解每个缺陷管理层信任员工会主动发现问题执行层信任系统确实有效E. 代码审查的真正使命代码审查者的工作不是审查代码，而是弄清楚如何让这一类评论在未来不再出现。等到审查发现错误时，错误已经发生了。审查只是症状，而非根本原因。F. 模块化和小组协作的解决方案作者提出的解决方案：组件应该由能全权负责的小团队构建小团队可以建立对质量的共识和信任通过清晰定义的接口，组件可以可靠地交付给其他团队可以让多个小组竞争构建同一组件，通过进化选择质量利用 AI 快速尝试不同的模块边界代码现在很便宜，但好的想法仍然稀缺。AI 编码使我们能比以往更快地实验新想法。2. 技术细节A. AI 开发者的堕落循环作者描述了 AI 辅助开发中常见的恶性循环：graph TD A[1. 原型快速完成] --> B[2. 发现 Bug 让 AI 修复] B --> C[3. 每次修复引入新 Bug] C --> D[4. 用 AI 代理审查代码] D --> E[5. 人工在代理间传递数据] E --> F[6. 需要代理框架] F --> G[7. 让 AI 编写代理框架] G --> A许多开发者陷入这个循环，不断让 AI 生成更复杂的代理框架，而实际代码质量没有提升。B. 单体和微服务的平衡微服务之前名声不好，因为它们"太微"。在原始术语中，一个"微"服务正好适合"两个披萨团队"独立构建和运维。有了 AI，可能只需要一个披萨和一些 token。有趣的是，可以利用更快的编码来实验不同的模块边界。C. 信任的重要性质量建立在信任之上：信任系统确实有效信任员工有能力识别问题信任管理层不会惩罚发现问题的人3. 数据与事实A. 审查层级的量化影响审查层级所需时间相对倍数无审查（直接编码）30 分钟1x同事审查300 分钟10x设计文档批准3,000 分钟100x跨团队协调30,000 分钟1,000x高管决策75,000 分钟2,500xB. QA 效率的数学陷阱如果每轮 QA 捕获 90% 的缺陷：一轮：剩余 10%两轮：剩余 1%三轮：剩余 0.1%这看起来很有效，但忽视了人类激励系统的复杂性。四、影响分析1. 行业影响A. 技术趋势AI 编码工具大幅提升编码速度传统审查流程成为新的瓶颈需要重新思考质量保证机制B. 竞争格局小型创业公司因审查层级少，可能更具优势大公司因固有流程难以改革，面临挑战2. 用户影响A. 现有用户AI 编码工具的使用者发现"第一环节很快，后续环节很慢"一些人盲目相信可以"不审查也能行"，导致质量下降B. 潜在用户需要理解 AI 只是加速器，而非替代品系统设计和组织文化同样重要C. 迁移成本减少审查层级不能单独进行，必须有替代机制需要建立信任文化和质量意识3. 技术趋势A. 技术方向从"多层审查"转向"模块化 + 信任"组件质量由源头保证，而非后续检查利用 AI 快速实验和迭代B. 生态影响代码变得廉价，但好的想法仍然稀缺通过进化选择找到最优架构和边界微服务架构可能重新获得重视五、各方反应1. 官方回应本文为个人观点文章，非官方公告2. 业内评价A. 专家观点作者参考了 Deming 的质量管理哲学，指出传统 QA 模式的根本问题质量应该内置于生产过程，而非事后检查审查应该用于学习，而非惩罚B. 社区反馈许多开发者经历过 AI 编码加速后审查瓶颈的困境对如何平衡速度和质量存在分歧3. 用户反馈A. 正面评价量化分析（10x 规则）直观易懂模块化和信任文化的建议具有建设性B. 关注点完全取消审查可能导致质量灾难需要渐进式改革，而非一刀切C. 中立观察大公司固有流程难以改变实际落地需要结合具体组织环境六、相关链接1. 相关文章Highlights on quality, and Deming's work as it applies to software development（2016）Systems design 3: LLMs and semantic revolution（2025）2. 参考资料丰田生产系统W. E. Deming 质量管理哲学参考资料Every layer of review makes you 10x slower
Emacs 与 Vim 在 AI 时代的未来一、新闻概述1. 标题Emacs and Vim in the Age of AI（Emacs 与 Vim 在 AI 时代）2. 发布时间2026 年 3 月 9 日3. 来源(think) 个人博客二、核心内容1. 事件摘要A. 主要内容文章作者 Bozhidar Batsov 作为拥有 20 年以上 Emacs 使用经验的核心贡献者，深入分析了在 AI 工具快速发展的背景下，Emacs 和 Vim 这两款传统编辑器面临的挑战与机遇。B. 核心亮点VS Code 和专用 AI 编辑器（Cursor、Windsurf 等）正在形成强大的吸引引力AI 改变了编程的核心技能：从编辑速度转向意图表达和代码审查AI 可能降低 Emacs Lisp 和 VimScript 的学习门槛终端原生 AI 工具与 Emacs/Vim 的工作流天然契合2. 关键信息A. 作者背景Emacs 狂热使用者超过 20 年维护了多个热门 Emacs 包，包括 copilot.el近期重新学习 Vim 和 NeovimB. 涉及技术Emacs、Vim、NeovimClaude Code、Copilot、Cursor、Windsurf 等 AI 工具gptel、ellama、aider.el、avante.nvim 等集成插件C. 文章定位这是一篇技术观点文章，而非纯粹的新闻报道，基于作者多年开源社区经验对未来趋势的思考。3. 背景介绍A. 前置背景VS Code 已经在编辑器市场占据绝对主导地位，并且正在获得所有主要 AI 工具的一流集成支持。微软有充分的资源和动力让 VS Code 成为 AI 辅助开发的最佳宿主。B. 相关上下文编程领域正在经历根本性转变，AI 越来越多地承担代码生成工作，人类的角色从编写代码转向审查、引导和精炼代码。三、详细报道1. 风险分析A. IDE 的引力井VS Code 的市场份额已经远超其他编辑器，正在获得 Copilot、Codex、Claude、Gemini 等 AI 工具的深度集成。Cursor、Windsurf 等专用 AI 编辑器也吸引了大量投资和人才。这些工具围绕 AI 工作流构建完整的体验，提供集成的上下文管理、内联差异、多文件编辑和代理循环。每个转向这些工具的开发者都是一个不再学习 Emacs 或 Vim 快捷键、不再编写 Elisp、不再为生态系统做出贡献的人。这种引力井效应是真实的。B. "强力工具"的必要性存疑Emacs 和 Vim 一直以来的卖点在于让用户更快地编写和编辑代码。快捷键、宏、可扩展性——所有这些都在于让人类更高效地完成编码的机械动作。但如果 AI 正在编写你的大部分代码，机械编辑速度还重要吗？当你正在审查和引导 AI 生成的差异而不是逐个字符地输入代码时，瓶颈从"我能编辑多快"转移到"我能多清楚地表达意图并评估输出"。这是一种完全不同的技能，而且不清楚 Emacs 或 Vim 在这方面有内在优势。学习曲线的论证也变得更难成立。当使用 Cursor 的初级开发者可以在一个下午搭建整个应用程序时，要求某人花费六个月学习 Emacs 以获得 10 倍速度是一个艰难的推销。C. 企业支持的不对称VS Code 有微软。Cursor 有风险投资。Emacs 有一小群志愿者和自由软件基金会。Vim 有 Bram 和现在的维护者社区。Neovim 有一个小型但专注的核心团队。这种情况一直存在，但 AI 放大了差距。构建深度 AI 集成需要跟上快速发展的 API、模型和范式。资金充足的团队可以专门投入工程师全职从事这项工作。志愿者驱动的项目以人们业余时间和热情的节奏前进。D. 末日场景让我们走向极端：如果我们熟悉的编程在下一个十年内完全自动化会怎样？如果 AI 代理可以接收规范并生成工作、经过测试、已部署的软件而无需人工干预，我们就根本不需要编码编辑器了。没有 Emacs，没有 Vim，没有 VS Code，没有 Cursor。整个类别变得无关紧要。作者认为这在短期内不太可能，但值得承认这是一种可能性。AI 能力的轨迹甚至让乐观主义者感到惊讶。2. 机遇分析A. AI 使配置和扩展变得微不足道几乎没有人谈论这一点：Emacs 和 Vim 一直受困于其扩展语言的晦涩。Emacs Lisp 是大多数程序员从未见过的 20 世纪 80 年代的 Lisp 方言。VimScript 就是 VimScript。即使是 Neovim 专门采用因为它更易接近的 Lua，也足够小众以至于大多数开发者没有写过一行。这几十年来一直是两个生态系统的最大瓶颈。不是编辑器本身——它们极其强大——而是自定义它们需要学习一种不熟悉的语言，而且大多数人从未超越从博客文章和 README 文件复制片段。作者在第一次学习 Emacs 和 Vim 时对 Elisp 和 VimScript 感到不知所措，他认为自己不是唯一一个。只有投入大量时间真正学会 Elisp 后，他才开始在 Emacs 中感到非常富有成效。（从未费心对 VimScript 做同样的事情，而且坦率地说，他也不太渴望掌握 Lua。）AI 一夜之间改变了这一点。你现在可以用简单的英语描述你想要什么，并获得工作的 Elisp、VimScript 或 Lua。"写一个 Emacs 函数，将当前段落重新格式化为 72 列并添加前缀"——完成。"配置 lazy.nvim 使用这些快捷键设置 LSP"——完成。扩展语言障碍，几十年来一直是采用的最大障碍，突然之间变得低得多。B. 插件开发同样受益在 Emacs 社区 20 多年后，作者经常感觉到一个相对较小的群体——也许 50 到 100 人——正在推动最有意义的进展。同样的名字出现在 MELPA、邮件列表和错误报告中。这不是对那些人的批评（他自豪地是其中之一），但这是一个结构性弱点。一个依赖如此少贡献者的社区是脆弱的。不仅仅是 Elisp 和 VimScript。Emacs 和 Vim 的 C 内部（以及 Neovim 的 C 核心）由更小的群体维护。找到既愿意又能够入侵数十年旧的 C 代码库的人确实很难，而且随着越来越少的人学习 C，这变得更难。AI 工具可以在这里以两种方式提供帮助。首先，它们降低了新贡献者的门槛——理解想要构建东西的"概念"的人现在可以获得 AI 对不熟悉语言"实现"的帮助。其次，它们帮助现有维护者更快地移动。作者个人发现 AI 非常擅长生成测试脚手架、编写文档和处理减慢包维护速度的繁琐部分。C. AI 集成已经在发生Emacs 和 Neovim 社区并没有坐以待毙。已经存在令人印象深刻的 AI 集成：Emacs：gptel——多功能 LLM 客户端，支持多个后端（Claude、GPT、Gemini、本地模型）ellama——通过 llama.cpp 和 Ollama 与 LLM 交互的 Emacs 接口aider.el——Aider 的 Emacs 集成，Aider 是流行的 AI 结对编程工具copilot.el——GitHub Copilot 集成（作者恰好是项目的当前维护者）elysium——具有内联差异应用的 AI 驱动编码助手agent-shell——通过代理客户端协议与 LLM 代理（Claude Code、Gemini CLI 等）交互的原生 Emacs 缓冲区Neovim：avante.nvim——Neovim 内部的类似 Cursor 的 AI 编码体验codecompanion.nvim——支持多个 LLM 提供商的 Copilot Chat 替代品copilot.lua——Neovim 的原生 Copilot 集成gp.nvim——具有多个提供商支持的 Neovim 中类似 ChatGPT 的会话这只是样本。构建这些集成并不像看起来那么困难——API 很简单，两个编辑器的可扩展性意味着你可以以感觉原生的方式连接 AI 工具。在 AI 帮助下，创建新的集成变得更加容易。作者不会惊讶插件开发速度显著加速。D. 终端原生 AI 工具是天然契合这里有一个值得更多注意的讽刺：许多最强大的 AI 编码工具是终端原生的。Claude Code、Aider 和各种 Copilot CLI 工具都在终端中运行。而终端里有什么？Emacs 和 Vim。在 Emacs vterm 缓冲区或 Neovim 终端分割中运行 Claude Code 是完全自然的工作流。你在一个窗格中获得 AI 代理，在另一个窗格中获得你的编辑器，所有快捷键和工具都保持完整。没有切换到不同的应用程序——都在同一个环境中。这实际上是优于基于 GUI 的 AI 编辑器的优势，其中 AI 集成与编辑器自己的界面紧密耦合。使用终端原生工具，你可以选择自己的编辑器和自己的 AI 工具，它们自然地组合在一起。E. Emacs 作为 AI 集成平台Emacs 的"编辑器即操作系统"哲学非常适合 AI 集成。它不仅仅是代码编辑器——它是邮件客户端（Gnus、mu4e）、笔记系统（Org mode）、Git 接口（Magit）、终端模拟器、文件管理器、RSS 阅读器等等。AI 可以在每一层集成。想象一个 AI 助手，可以读取你的 org-mode 议程、在 mu4e 中起草邮件回复、在 Magit 中帮助你编写提交消息以及在源缓冲区中重构代码——都在同一个环境中，共享上下文。没有其他编辑器架构使这种深度的跨域集成像 Emacs 一样自然。F. AI 帮助你自助对于 Emacs 和 Vim 用户来说，AI 最被低估的好处之一是平凡的：故障排除。两个编辑器都有臭名昭著的陡峭学习曲线和不透明的错误消息。"Wrong type argument: stringp, nil" 比任何竞争对手都让更多人远离 Emacs。AI 工具在解释神秘错误消息、诊断配置问题和建议修复方面非常出色。它们可以读取你的 init 文件并发现问题。它们可以解释一段 Elisp 做什么。它们可以帮助你理解为什么你的快捷键不起作用。这显着拉平了学习曲线——不是通过使编辑器更简单，而是通过给每个用户提供耐心、知识渊博的指南。作者在 Emacs 设置中确实不需要任何 AI 帮助来排除故障，但在 Neovim 世界中偶尔很方便，相比之下他的知识相对有限。至少有一个记录在案的案例表明，有人离开多年后回到 Emacs，特别是因为 Claude Code 使修复配置问题无痛无苦。他们因为配置负担太烦人而离开 Emacs 去 IntelliJ——一旦 AI 消除那个障碍就回来了。"快乐该死的日子我又回家了"，正如他们所说的那样。如果 AI 能带回离开的 Emacs 用户，在我看来这是一件好事。G. 即使在编程后的世界，Emacs 和 Vim 也能生存让我们重新审视末日场景。假设编程完全自动化，没有人再编写代码。Emacs 会死吗？不一定。Emacs 已经用于远不止编程。人们使用 Org mode 管理他们的整个生活——任务、笔记、日历、日志、时间跟踪，甚至学术论文。Emacs 是散文的强大写作环境，对 LaTeX、Markdown、AsciiDoc 和纯文本有出色的支持。你可以阅读电子邮件、浏览网页、管理文件，是的，玩俄罗斯方块。Vim 同样是一种文本编辑范式，也是一个程序。Vim 快捷键已经殖民了计算世界的每一个文本输入——VS Code、IntelliJ、浏览器、shell，甚至 Emacs（通过 Evil mode）。即使 Vim 程序淡出，Vim 想法是不朽的。谁知道——也许有一天会有手工制作的软件市场。"本地采购、自由放养的代码，由人类在 Emacs 中编写。"作者会买那件 T 恤。而且他相当确定那些工匠程序员不会使用 VS Code。因此即使在最极端的情况下，两个编辑器都有超越代码的生命。一个可能 diminished 的生活，但仍然是生活。3. 技术细节A. 编辑器角色转变几十年来，编辑器是你"编写"代码的地方。越来越地，它正在成为你"审查、引导和精炼"AI 编写的代码的地方。重要的技能从打字速度和编辑体操转移到规范清晰度、代码阅读和架构判断。在这个世界中，获胜的编辑器不是具有最佳代码补全的编辑器——而是给你对工作流最大控制的编辑器。而这一直是 Emacs 和 Vim 的核心价值主张。B. 社区适应的挑战问题是社区能否足够快地适应。工具在那里。架构在那里。哲学是正确的。需要的是人——更多的贡献者、更多的插件作者、更多的文档作者、对话中更多的声音。AI 可以帮助弥合差距，但它不能取代真正的社区参与。C. 伦理关注Emacs 和 Vim 社区中并非每个人都对 AI 热情，反对意见超越了单纯的技术恐惧症。存在将在很长一段时间内辩论的真正伦理关注：能源消耗。训练和运行大型语言模型需要大量的计算能力和电力。对于一直重视效率极简主义的社区——以在 40 年前的编辑器上运行为荣的 Emacs 用户、以亚秒启动时间为豪的 Vim 用户——AI 的环境成本难以忽视。版权和训练数据。LLM 在大量代码和文本语料库上训练，该训练的合法性和伦理仍然有争议。一些开发者对使用可能未经明确同意从受版权保护的代码中学习的工具感到不舒服。这种担忧深深地触动了对许可深切关心的开源社区。工作置换。如果 AI 使开发人员显着更高效，可能需要更少的开发人员。对于任何编程社区来说这是一个不舒服的想法，而对于围绕赋予人类程序员力量的身份而建立的编辑器来说，这尤其尖锐。这些担忧已经产生了具体的行动。Vim 社区最近看到了 EVi 的创建，这是 Vim 的一个分支，其整个存在理由是提供没有 AI 辅助（生成的？）代码贡献的文本编辑器。无论你是否同意前提，人们因此分叉既定编辑器这一事实告诉你一些社区成员感觉有多强烈。四、影响分析1. 行业影响A. 编辑器竞争格局VS Code 和专用 AI 编辑器在资金和市场份额上拥有巨大优势，但 Emacs 和 Vim 的核心价值——工作流控制和可定制性——在新的编程范式中仍然相关。B. 技术趋势编程的角色从"编写"转向"审查和引导"，这有利于那些在上下文管理和工具集成方面提供最大灵活性的编辑器。2. 用户影响A. 现有用户对于现有 Emacs 和 Vim 用户，AI 工具可以降低配置障碍、加速插件开发，并在需要时提供故障排除帮助。B. 新用户学习曲线曾经是 Emacs 和 Vim 的主要障碍。AI 可以显着降低这一障碍，使新用户更容易进入生态系统。C. 离开用户的回归已记录的案例表明，一些用户因配置复杂而离开 Emacs，在 AI 工具让故障排除变得容易后回归。3. 社区影响A. 贡献者门槛降低AI 可以帮助不熟悉 Elisp 或 VimScript 等语言的新贡献者更快地实现他们的想法，扩大贡献者基础。B. 伦理分歧关于 AI 的伦理担忧可能导致社区分裂，例如 EVi 分支展示了部分社区对 AI 代码的强烈反对。五、各方反应1. 作者观点作者承认担忧，但保持谨慎乐观。他一直在听人说 Emacs 即将死亡 20 年了，但它仍然存在。社区很小但充满激情，编辑器比以往任何时候都更有能力，架构确实适合 AI 时代。2. 社区行动A. AI 集成插件蓬勃发展Emacs 和 Neovim 社区已经开发了丰富的 AI 集成插件生态系统，包括 gptel、copilot.el、avante.nvim 等。B. 伦理反对Vim 社区出现了 EVi 分支，明确反对 AI 代码，显示了社区内对 AI 的分歧。3. 作者建议如果你是 Emacs 或 Vim 用户：不要恐慌，但也不要自满。学习新的 AI 工具（如果你不是从根本上反对它们）。美化你的设置并使其令人敬畏。写你的工作流。帮助新来者。确保你的编辑器在 AI 时代生存的最佳方式是让它在其中繁荣。也许未来不是它曾经的样子——但不一定是一件坏事。参考资料Emacs and Vim in the Age of AI
2026年重返Rails一、新闻概述1. 标题2026年重返Rails：一次充满乐趣的开发体验回顾2. 发布时间2026年3月5日3. 来源Mark Dastmalchi-Round 的个人博客 markround.com二、核心内容1. 事件摘要A. 主要内容作者 Mark Dastmalchi-Round 在为他的乐队开发歌曲列表管理应用时，选择了 Rails 8 作为技术栈，并分享了重新使用 Rails 的开发体验和对 Rails 8 新特性的深入分析。B. 核心亮点Rails 8 采用了"No-Build"前端开发方式，无需 Webpack 等复杂构建工具Solid 系列组件：Solid Cache、Solid Queue、Solid Cable，无需额外基础设施SQLite 生产环境支持成为默认配置新的 Kamal 部署工具提供零停机部署体验2. 关键信息A. 版本号Rails 8B. 涉及技术Ruby on Rails 8Stimulus + Turbo (Hotwire)SQLiteKamal 部署工具Solid 系列组件C. 背景介绍2025年 Stack Overflow 开发者调查显示，Rails 在框架流行度中排名第20，落后于主流 JavaScript 和 ASP.NET 框架。Ruby 语言也仅排在前十名之外，低于 Lua 甚至汇编语言。三、详细报道1. 主要内容A. 前端开发：No-Build 方式Rails 8 采用了"无构建"的前端开发方法，开发者无需配置 Webpack、Yarn、npm 或其他 JavaScript 工具链。默认的 Hotwire 技术栈由 Stimulus 和 Turbo 组成。Turbo 负责拦截链接点击和表单提交，交换页面片段以提供类似单页应用（SPA）的流畅体验，而无需实际构建 SPA。开发者可以在需要时添加少量 Stimulus JS 控制器来实现特定行为。Stimulus 组件库通过简单的 importmap 命令管理：$ bin/importmap pin @stimulus-components/dialog这会从 JS CDN 下载包并将其添加到 vendor 目录，自动更新配置。使用时只需在控制器中注册即可在视图模板中立即使用。B. 工作流：Rails 开发体验Rails 的"约定优于配置"理念让开发变得高效。通过生成器可以快速创建模型、控制器和路由。例如，创建一个标签系统：$ bin/rails generate model Tag label:string color:string band:belongs_to这会自动生成模型文件：class Tag < ApplicationRecord belongs_to :band endActiveRecord 会自动从数据库获取列名和定义，无需额外工作。路由配置也极其简单，一行代码即可生成完整的 RESTful 路由：resources :tags开发者可以使用 curl 等工具快速测试 API：$ curl --silent -XGET \ -H "Authorization: Bearer <token>" http://localhost:3000/bands/4/tags/5.json | jq .C. 后端改进：Solid 系列组件Rails 8 引入了 Solid 系列组件，解决了需要额外基础设施的问题。Solid Cache使用数据库而不是内存存储进行缓存。现代存储性能足够用于缓存目的，这意味着可以缓存更多内容，同时也不需要 Redis 等额外层级。片段缓存示例：<% cache "time_based", expires_in: 5.minutes do %> <% end %>或基于模型的缓存：<% cache ["band_dashboard", @band.cache_key_with_version, expires_in: 1.hour] do %> <% end %>Solid Queue无需 Redis 即可管理后台任务，默认使用数据库。开发环境只需简单设置：SOLID_QUEUE_IN_PUMA=1 bundle exec rails server任务声明同样简单：# app/jobs/my_sample_job.rb class MySampleJob < ApplicationJob queue_as :default def perform Rails.logger.info "Yup, I still love Ruby..." end endSolid Cable用于实时 WebSocket 功能，同样默认使用数据库。作者主要用它来启用开发环境的 debugbar 工具栏。D. 认证生成器Rails 8 内置了认证生成器，为小型项目提供简洁的认证系统。相比 Devise 等功能丰富的解决方案，内置生成器更简单直接。不过对于复杂需求如 Omniuth 集成，Devise 仍有更多文档和指南支持。E. SQLite 生产级支持Rails 8 的 SQLite 配置默认值现在适合生产环境使用。database.yml 中的 pragma 设置包括：production: adapter: sqlite3 database: storage/production.sqlite3 pragmas: journal_mode: wal synchronous: normal mmap_size: 134217728 cache_size: 2000 busy_timeout: 5000 foreign_keys: true journal_size_limit: 67108864这些设置使 SQLite 成为中小型 Rails 应用的可行生产数据库，结合 Solid 组件，不再仅仅是本地开发工具。F. 部署：KamalKamal 是 Rails 8 的默认部署工具，提供零停机部署体验。配置文件 deploy.yml 定义服务器角色：servers: web: - web.rails.example.com job: hosts: - jobs.rails.example.com cmd: bin/jobs部署时 Kamal 会：构建容器并推送到注册表在所有服务器上拉取镜像启动新容器健康检查通过后将流量路由到新容器停止旧容器并清理Kamal-proxy 作为轻量级反向代理处理流量切换，支持 Let's Encrypt 的 SSL 终止。2. 技术细节A. Rails 架构演变graph TB subgraph 前端 A[Stimulus 控制器] B[Turbo 驱动] end subgraph Rails 8 核心 C[ActiveRecord] D[路由系统] E[生成器] end subgraph Solid 组件 F[Solid Cache 基于数据库] G[Solid Queue 基于数据库] H[Solid Cable WebSocket] end subgraph 数据层 I[SQLite 生产级配置] end subgraph 部署 J[Kamal] K[容器构建] L[kamal-proxy] end A --> B B --> D C --> F C --> G D --> E F --> I G --> I E --> J J --> K K --> LB. 工作流程graph LR A[构思模型] --> B[生成脚手架] B --> C[配置路由] C --> D[实现控制器逻辑] D --> E[curl 测试 API] E --> F[生成视图模板] F --> G[热重载开发]3. 数据与事实A. 流行度对比JavaScript 框架：占前十主导地位ASP.NET：占前十主导地位Rails：排名第20Ruby 语言：57.9% 使用率（Python）B. 发布节奏Rails 自 2010 年的 3.0 版本以来，每年持续发布新版本，保持稳定的发布节奏，是少数没有因项目规模扩大而降低发布频率的开源项目。C. 生态活跃度一些 Rails 相关项目如 Devise 显示发布活动呈下降趋势，自 2016 年 v4 版本发布后基本进入维护模式。不过 Shopify、SoundCloud、Basecamp 等大型企业仍在使用 Rails。四、影响分析1. 行业影响A. 技术趋势Rails 8 的"No-Build"方法和 Solid 组件体现了简化开发体验的趋势。将缓存、队列、WebSocket 等功能集成到框架内部，减少对额外基础设施的依赖。B. 竞争格局尽管在流行度调查中落后于 JavaScript 框架，Rails 仍在持续创新，每年稳定发布新版本。其简化部署和降低基础设施依赖的方向可能吸引追求开发效率而非"最前沿"技术的开发者。2. 用户影响A. 现有用户对于长期 Rails 开发者，Rails 8 带来的改进（如 SQLite 生产级支持、Kamal 部署）显著降低了中小型应用的开发和部署复杂度。B. 潜在用户对于小型项目或独立开发者，Rails 8 提供了从开发到部署的完整解决方案，无需学习多种工具即可快速构建和上线应用。C. 迁移建议作者建议通过教程尝试 Rails，构建有趣的项目，最重要的是享受开发过程。五、各方反应1. 官方趋势Stack Overflow 开发者调查显示 Ruby 和 Rails 流行度有所下降，但 Rails 项目本身保持了每年稳定发布的节奏。2. 业内评价A. 优势观点开发体验极佳：约定优于配置、生成器工具高效简化依赖：No-Build 前端、Solid 组件减少外部依赖部署友好：Kamal 提供零停机部署B. 挑战观点社区活跃度下降：部分项目进入维护模式文档更新滞后：一些指南和 Gem 多年未更新技术小众：Ruby 语言流行度低于主流语言3. 用户反馈A. 正面评价作者本人对 Rails 8 的开发体验非常满意，表示这是多年来最有乐趣的开发经历。B. 关注点前端技能门槛：对于不熟悉现代前端开发的用户，仍有学习曲线生态活跃度：部分周边项目维护不如从前活跃六、相关链接1. 官方资源Ruby on Rails 官方文档Rails Guides2. 相关文章SQLite 生产环境配置指南Kamal 部署文档3. 社区资源Stimulus LibraryStimulus Components参考资料Returning To Rails in 2026
CLI-Anything：让所有软件成为 AI Agent 原生工具一、概述1. 简介A. 是什么CLI-Anything 是一个 Claude Code 插件，能够将任何软件自动转换为 AI Agent 可控制的命令行工具。通过一条命令，它可以为 GIMP、Blender、LibreOffice 等应用生成功能完整的 CLI 接口，让 AI Agent 获得直接控制专业软件的能力。B. 为什么学解决 AI Agent 使用软件难题：当前 AI Agent 虽然推理能力强，但难以使用真实的专业软件统一接口范式：CLI 是 AI Agent 的理想接口，结构化、可组合、自描述自动化生成：无需手动编写代码，自动分析软件架构并生成 CLI生产级质量：1,508 个测试用例验证，覆盖 11 个主流应用C. 学完能做什么为任何软件自动生成 CLI，让 AI Agent 可以控制理解 7 阶段自动化流水线的工作原理部署和使用生成的 CLI 工具通过 refine 命令迭代改进 CLI 覆盖率2. 前置知识A. 必备技能Python 3.10+ 基础基本的命令行操作经验理解 AI Agent 的基本概念B. 推荐知识Click 框架（Python CLI 工具）pytest 测试框架Claude Code 使用经验二、环境准备1. 系统要求Python 3.10 或更高版本目标软件已安装（如 GIMP、Blender 等）Claude Code 或其他支持的 AI 编码代理2. 安装步骤Claude Code 平台安装：# 添加 CLI-Anything 市场 /plugin marketplace add HKUDS/CLI-Anything # 安装插件 /plugin install cli-anything手动安装（可选）：# 克隆仓库 git clone https://github.com/HKUDS/CLI-Anything.git # 复制插件到 Claude Code 插件目录 cp -r CLI-Anything/cli-anything-plugin ~/.claude/plugins/cli-anything # 重新加载插件 /reload-plugins3. 验证安装安装完成后，在 Claude Code 会话中输入：/cli-anything:cli-anything --help三、核心概念1. 基本术语Agent-Native（Agent 原生）：专为 AI Agent 设计的接口，支持结构化输入输出Harness（工具套件）：为特定软件生成的完整 CLI 包REPL（交互式解释器）：命令行交互模式，支持状态持久化7-Phase Pipeline：从分析到发布的自动化流程2. 工作原理CLI-Anything 通过自动化流程分析软件源码，理解其功能架构，然后生成标准的命令行接口。生成的 CLI 直接调用真实软件的后端，确保功能完整性。graph TB A[软件源码/仓库] --> B[分析阶段] B --> C[设计阶段] C --> D[实现阶段] D --> E[测试规划] E --> F[测试编写] F --> G[文档更新] G --> H[发布安装] subgraph 生成产物 I[Click CLI] J[REPL 界面] K[JSON 输出] L[测试套件] end D --> I D --> J D --> K F --> L3. 架构设计graph LR A[AI Agent] -->|命令| B[CLI-Anything 生成的 CLI] B -->|调用| C[真实软件后端] C -->|渲染/处理| D[输出文件] B -->|JSON 输出| A B -->|人类可读| E[终端输出] subgraph CLI-Anything 核心 F[分析引擎] G[代码生成器] H[测试框架] end F --> G G --> H四、快速上手1. Hello World 示例生成第一个 CLI 工具：# 为本地 GIMP 源码生成完整 CLI（所有 7 个阶段） /cli-anything:cli-anything ./gimp2. 核心功能演示# 从 GitHub 仓库生成 /cli-anything:cli-anything https://github.com/blender/blender3. 代码讲解上述命令会自动执行以下流程：第 1 阶段：分析扫描源代码，映射 GUI 操作到 API第 2 阶段：设计架构命令组、状态模型、输出格式第 3 阶段：实现构建 Click CLI，包含 REPL、JSON 输出、撤销/重做功能第 4 阶段：测试规划创建 TEST.md，包含单元测试和端到端测试计划第 5 阶段：测试编写实现全面的测试套件第 6 阶段：文档更新 TEST.md 包含测试结果第 7 阶段：发布创建 setup.py，安装到 PATH4. 使用生成的 CLI# 进入生成的 harness 目录 cd gimp/agent-harness # 安装到 PATH pip install -e . # 使用帮助 cli-anything-gimp --help # 创建新项目 cli-anything-gimp project new --width 1920 --height 1080 -o poster.json # 添加图层 cli-anything-gimp --json layer add -n "Background" --type solid --color "#1a1a2e" # 进入交互式 REPL cli-anything-gimp五、进阶内容1. 常用功能插件命令列表命令描述/cli-anything <path-or-repo>构建完整 CLI 工具套件/cli-anything:refine <path> [focus]改进现有工具套件，扩展覆盖率/cli-anything:test <path-or-repo>运行测试并更新 TEST.md/cli-anything:validate <path-or-repo>验证是否符合 HARNESS.md 标准refine 命令使用迭代改进 CLI 覆盖率：# 广泛改进 —— 分析所有功能的缺口 /cli-anything:refine ./gimp # 聚焦改进 —— 针对特定功能区域 /cli-anything:refine ./gimp "批量图像处理和滤镜功能"refine 命令会执行以下操作：分析软件完整能力与当前 CLI 覆盖之间的缺口为识别出的缺口实现新命令添加相关测试更新文档可以多次运行以稳步扩展覆盖率，每次运行都是增量且非破坏性的。2. 最佳实践真实软件集成原则CLI 必须调用实际软件进行渲染不使用简化替代品（如用 Pillow 替代 GIMP）生成有效的项目文件，然后调用真实后端测试策略# 运行特定 CLI 的测试 cd <software>/agent-harness python3 -m pytest cli_anything/<software>/tests/ -v # 强制已安装模式（推荐用于验证） CLI_ANYTHING_FORCE_INSTALLED=1 python3 -m pytest cli_anything/<software>/tests/ -v -sJSON 输出模式AI Agent 可以通过 --json 标志获取结构化输出：cli-anything-libreoffice --json document info --project report.json返回格式：{ "name": "Q1 Report", "type": "writer", "pages": 1, "elements": 2, "modified": true }3. 性能优化使用批量操作减少命令调用次数在 REPL 模式下工作，保持会话状态JSON 模式比人类可读输出更快，适合 Agent 解析六、实战案例1. 场景描述为 LibreOffice 生成 CLI，让 AI Agent 能够自动创建文档、添加内容并导出为 PDF。2. 实现步骤步骤 1：生成 CLI/cli-anything:cli-anything https://github.com/LibreOffice/core步骤 2：安装生成的 CLIcd libreoffice/agent-harness pip install -e .步骤 3：使用 CLI 创建文档# 创建新的 Writer 文档 cli-anything-libreoffice document new -o report.json --type writer # 添加标题 cli-anything-libreoffice --project report.json writer add-heading -t "季度报告" --level 1 # 添加表格 cli-anything-libreoffice --project report.json writer add-table --rows 4 --cols 3步骤 4：导出为 PDFcli-anything-libreoffice --project report.json export render output.pdf -p pdf --overwrite3. 完整 REPL 交互$ cli-anything-blender ╔══════════════════════════════════════════╗ ║ cli-anything-blender v1.0.0 ║ ║ Blender CLI for AI Agents ║ ╚══════════════════════════════════════════╝ blender> scene new --name ProductShot ✓ Created scene: ProductShot blender[ProductShot]> object add-mesh --type cube --location 0 0 1 ✓ Added mesh: Cube at (0, 0, 1) blender[ProductShot]*> render execute --output render.png --engine CYCLES ✓ Rendered: render.png (1920×1080, 2.3 MB) via blender --background blender[ProductShot]> exit Goodbye!七、常见问题1. 安装问题问题：插件安装后无法识别解决：确认 Claude Code 版本，使用 /reload-plugins 重新加载2. 生成问题问题：生成过程失败或输出不完整解决：确保源码可访问，检查 Python 依赖是否安装完整3. 运行问题问题：生成的 CLI 命令无法执行解决：确认已运行 pip install -e . 安装到 PATH八、应用场景CLI-Anything 可用于多种软件类型：GitHub 仓库将任何开源项目转换为 Agent 可控工具，如 VSCodium、WordPress、Calibre、Zotero 等AI/ML 平台自动化模型训练、推理管道和超参数调优，如 Stable Diffusion WebUI、ComfyUI、InvokeAI 等数据与分析工具支持程序化数据处理、可视化和统计分析，如 JupyterLab、Apache Superset、Metabase 等开发工具简化代码编辑、构建、测试和部署流程，如 Jenkins、Gitea、Portainer、SonarQube 等创意媒体工具控制内容创建、编辑和渲染工作流，如 Blender、GIMP、OBS Studio、Krita、Kdenlive 等科学计算自动化研究工作流、模拟和复杂计算，如 ImageJ、FreeCAD、QGIS、ParaView 等企业办公将商业应用和生产力工具转换为 Agent 可访问系统，如 NextCloud、GitLab、Grafana、Mattermost 等九、测试结果CLI-Anything 在 11 个不同的应用上进行了全面测试，总计 1,508 个测试用例，100% 通过率。软件领域CLI 命令后端测试数量GIMP图像编辑cli-anything-gimpPillow + GEGL/Script-Fu107Blender3D 建模与渲染cli-anything-blenderbpy (Python scripting)208Inkscape矢量图形cli-anything-inkscape直接 SVG/XML 操作202Audacity音频制作cli-anything-audacityPython wave + sox161LibreOffice办公套件cli-anything-libreofficeODF 生成 + 无头 LO158OBS Studio直播与录制cli-anything-obs-studioJSON 场景 + obs-websocket153Kdenlive视频编辑cli-anything-kdenliveMLT XML + melt 渲染器155Shotcut视频编辑cli-anything-shotcut直接 MLT XML + melt154Zoom视频会议cli-anything-zoomZoom REST API (OAuth2)22Draw.io绘图cli-anything-drawiomxGraph XML + draw.io CLI138AnyGenAI 内容生成cli-anything-anygenAnyGen REST API50总计 1,508测试层级包括：单元测试：隔离测试每个核心函数E2E 测试（原生）：项目文件生成管道E2E 测试（真实后端）：真实软件调用 + 输出验证CLI 子进程测试：通过 subprocess.run 验证已安装命令参考资料CLI-Anything GitHub RepositoryClaude Code Documentation
AI 如何影响技能养成：Anthropic 实验研究揭示关键发现
AI 如何影响技能养成：Anthropic 实验研究揭示关键发现一、新闻概述1. 标题AI 如何影响技能养成：Anthropic 实验研究揭示关键发现2. 发布时间2026 年 2 月 27 日3. 来源Anthropic 研究团队二、核心内容1. 事件摘要A. 主要内容Anthropic 研究人员通过一项随机对照实验，证实了在使用 AI 学习新技能时，不同的使用方式会导致显著不同的学习效果。整体而言，过度依赖 AI 的学习者技能掌握程度下降 17%，但正确的 AI 使用方式反而能提升学习效果。B. 核心亮点首个针对 AI 辅助学习效果的随机对照实验发现 6 种不同的 AI 使用模式，其中 3 种有益、3 种有害认知参与度是决定学习效果的关键因素调试技能是最容易因 AI 替代而退化的能力2. 关键信息A. 研究规模52 名专业开发人员参与随机对照实验B. 重要数据AI 整体组技能得分低 17%p 值为 0.010，具有统计学显著性高认知参与组得分 86%低认知参与组得分仅 24%得分差距最大的是调试类问题C. 涉及产品/技术Anthropic Claude AI 助手3. 背景介绍A. 前置研究背景随着 AI 编程助手在开发者社区中的普及，关于 AI 是否会影响学习能力的讨论日益激烈。此前缺乏系统的实证研究来回答这一问题。B. 相关上下文AI 工具被广泛认为能提高开发效率，但其对长期技能养成的影响一直是业界关注的话题。本研究填补了这一空白，提供了科学依据。三、详细报道1. 主要内容A. 实验设计研究采用随机对照实验方法，招募 52 名专业开发人员参与。任务要求参与者使用从未接触过的 Python 库进行真实编程工作。参与者被随机分为两组：AI 组配备 AI 助手，对照组无 AI 辅助。B. 实验结果整体上，AI 组在技能评估中的得分比对照组低 17%。差异的统计显著性通过 p 值 0.010 得到确认。令人意外的是，AI 组并未在速度上获得优势，他们学到的内容更少，同时也没有节省时间。C. 六种 AI 使用模式通过分析参与者的屏幕录像，研究人员识别出 6 种使用 AI 学习新技能的不同模式。这些模式对学习效果的影响呈现两极分化：3 种模式有助于保持学习效果，另外 3 种则会破坏学习效果。2. 技术细节A. AI 使用模式对比分析graph TD subgraph 有益模式 A1[模式1: 概念性提问 得分: 86%] A2[模式2: 代码后追问 得分: 高] A3[模式3: AI 作为思考伙伴 得分: 高] end subgraph 有害模式 B1[模式4: 粘贴提示词 得分: 24%] B2[模式5: 复制输出结果 得分: 低] B3[模式6: 逃避思考 得分: 低] end A1 -->|认知参与度高| 学习效果好 A2 -->|认知参与度高| 学习效果好 A3 -->|认知参与度高| 学习效果好 B1 -->|认知参与度低| 学习效果差 B2 -->|认知参与度低| 学习效果差 B3 -->|认知参与度低| 学习效果差B. 高认知参与组特征得分最高的 AI 用户提出了"为什么这样行得通"类型的问题，而非要求 AI "替我写这段代码"。他们在生成代码后会主动追问以便理解，将 AI 视为思考伙伴而非思考的替代品。这组参与者的表现甚至超过了无 AI 对照组。C. 低认知参与组特征得分最低的一组参与者采用粘贴提示词、复制输出结果、然后继续下一步的工作方式。他们完成任务的速度最快，但几乎什么也没学到。D. 调试技能退化风险研究发现，得分差距最大的是调试类问题。这项技能正是监管 AI 输出所需要的关键能力，同时也是让 AI 代劳时退化得最快的技能。3. 数据与事实A. 学习效果对比使用模式认知参与度技能评估得分相对对照组概念性提问高86%+代码后追问高高+思考伙伴模式高高+粘贴提示词低24%--复制输出低低-逃避思考低低-无 AI 对照组中基准基准B. 学习机制分析对照组在任务执行过程中犯了更多错误，遇到了各种 bug。但这番挣扎恰恰构建了他们的理解。研究表明，错误并非学习的障碍，错误本身就是学习。用 AI 消除错误，也就消除了建立能力的机制。C. 参与者反思AI 组参与者在事后反思中坦言，希望自己当时能"更用心一点"，并觉得自己的做法很"懒惰"。其中一人写道："我的理解还有很多漏洞。"他们能感受到那种完成了任务却不知其所以然的空虚感。这种体验并非生产力的胜利，而是技术债。四、影响分析1. 行业影响A. 技术趋势这项研究为 AI 辅助学习提供了科学依据，将影响未来的技术培训和教育方式。企业和教育机构需要重新思考如何有效使用 AI 工具。B. 竞争格局AI 工具提供商可能需要在产品设计中考虑引导用户采用更有效的使用模式，避免过度自动化导致的技能退化。2. 用户影响A. 现有用户正在使用 AI 进行编程和学习的开发者需要反思自己的使用方式，从"让 AI 替我工作"转向"让 AI 帮我理解"。B. 潜在用户新入门的开发者和学习者需要了解 AI 的正确使用方式，避免陷入低效的学习模式。C. 工程经理工程经理需要警惕调试技能的退化风险，因为这是监管 AI 输出的核心能力。团队培训中应强调 AI 的正确使用方式。3. 技术趋势A. 技术方向未来可能发展出专门针对学习场景的 AI 工具，设计上更注重促进认知参与而非完全替代思考。B. 生态影响技术教育和培训体系需要更新，将 AI 工具的正确使用方法纳入课程，培养学习者的"AI 素养"。五、各方反应1. 研究结论论文并非反对使用 AI，而是反对无意识地使用 AI。核心结论很简单：如果你在学习新东西，请用 AI 来提问，而不是用它来逃避工作。那份挣扎，才是成果所在。2. 实践建议A. 对学习者问"为什么"而非"怎么做"用 AI 生成代码后，一定要追问原理保留一定难度的问题由自己解决将 AI 视为导师而非代劳者B. 对管理者鼓励团队成员独立解决部分问题将调试能力作为关键考核指标提供 AI 使用方式培训关注长期技能建设，而非短期效率C. 对 AI 工具开发者设计提示引导用户主动思考提供解释性输出而非直接答案添加学习进度跟踪功能参考资料Anthropic 研究团队：《AI 如何影响技能养成》