Codex CLI 连呼吸都要征求你的同意?两个标志就能解决!

你安装了 Codex CLI,满怀期待地启动它,对它说:“修复这个仓库里的所有测试问题。” 然后,噩梦开始了: Codex: 我要运行 pytest 允许吗? (y/n) 你按了 y。紧接着它又来一句: Codex: 我要修改 test_user.py 允许吗? (y/n) 又是一个 y。一次又一次。每当需要读取某个文件、运行某个命令或修改某行代码时,都会跳出确认提示。确认、确认、确认。感觉像是跟一个实习生工作,他连上厕所都要问你准不准。 与此同时,Claude Code 或 Cursor Agent 在干同样的事情,却能悄无声息地完成。发生了什么? 其实 Codex 默认是以一种“谨慎模式”运行的。这样做的确有道理——对一个新产品来说,这是最安全的选择。但是如果你是个知道自己在做什么的用户,这种保守模式实在让人崩溃,根本无法高效工作。 好消息是:只需要两秒钟,就能解决这个问题。 权限系统:approval mode Codex 使用一种叫做 approval mode(审批模式)的机制来控制何时需要你的确认。默认情况下,它会向你请求确认做任何事情: 运行命令 写入文件 修改代码 新建文件 运行测试 简而言之:默认情况下,Codex 什么都做不了,除非你点 y 确认。就像每执行一个动作都需要输入 sudo。 结果是,这个应该是自主工作的代理,变成了一个永远啰嗦不完的对话系统,而你作为“人类环节”,成为了整个流程中最慢的一环。 解决办法:一个标志,马上起飞 1 codex --approval-mode never 就是这么简单。有了 --approval-mode never,Codex 就再也不会问你了。它会直接执行命令、修改文件、创建需要的文件……就像一个真正可以工作的代理一样。 想让它永久生效?有两个方法可以实现: 1 2 3 4 5 # 方法1:使用配置命令 codex config set approval_mode never # 方法2:直接编辑配置文件 # ~/.codex/config.toml 1 approval_mode = "never" 从现在开始,每次启动 Codex,它都不会打断你的操作。 ...

2026年3月11日 · Fernando

上下文工程:让优秀AI代理脱颖而出的无形技能

想象一下,你聘请了一位才华横溢的顾问。他拥有两个博士学位,会说七种语言,并且能够解决你甚至都不知道存在的问题。你让他坐到会议室里,然后对他说:“我需要你重构项目的认证流程。” 顾问看着你,点点头,问:“哪个项目?” 你没有给他代码访问权限,也没有给他解释系统架构。他不知道你用的是 JWT 令牌还是会话 cookie,不知道你使用什么编程语言,也不知道你有多少微服务,更不知道为什么上次的迁移尝试以失败告终。 这个顾问,就好比你的 LLM(大型语言模型)。而你刚刚犯了一个 90% 使用 AI 代理的人都会犯的错误:你专注于“大脑”,却忽略了“大脑所看到的内容”。 Prompt engineering 已死。Context engineering 长存。 最近几个月,我在每个论坛、每个 Twitter 话题、每次团队会议中都看到同一个讨论:“用 GPT-5 还是 Claude Opus?哪个模型更适合编程?哪个模型的推理能力更强?” 每次我计算这些问题时,答案基本都是一样的:无所谓。好吧,也不能说完全无所谓。但是,对比选择最好的模型和提供一个完美的上下文,后者的重要性高得多。 一个中等水平的模型配上完美的上下文,能够轻松打败一个顶级模型却只有糟糕上下文的组合。没有例外。这永远成立。 这就是**上下文工程(Context Engineering)**的意义所在。而且,请注意,这与 prompt engineering 并不是同样的概念。 Prompt engineering 是编写一个好的提示:选择正确的词语、组织请求的结构、添加示例等。这很重要,但只是其中的一部分。 做 context engineering 则是在设计模型所看到的一切内容:包括哪些信息要输入、顺序如何、有什么被舍弃、如何压缩,以及哪些必须被优先保留。这是为 LLM 设计的信息架构。 简单来说:prompt engineering 是提出一个好的问题,而 context engineering 是决定学生在考试前可以参考哪些书。 记忆的四个阶段:隐藏的生命周期 OpenAI 最近发布了两篇 Cookbook 文章,深入分析了拥有长期记忆的 AI 代理如何管理上下文。这不是 RAG(检索增强生成),也不是矢量数据库管理。它是一个基于状态的系统,就像一本有严格规则的现场笔记本。 这个模式使用的是 local-first 和 state-based 的方法:一个结构化的状态对象随着代理的运行更新,分为几个主要阶段。 flowchart TD A["1. 注入\n(会话创建时)"] --> B["2. 精炼\n(会话中)"] B --> C["3. 整理\n(会话后)"] C --> D["4. 修剪\n(保存时)"] D -->|"新会话开始"| A A1["将状态渲染为 YAML\n+ 全局记忆(最多 6 条)\n+ 优先级规则"] -.-> A B1["save_memory_note()\n校验记忆持久性\n要求有可操作性\n拒绝保存个人信息和假设"] -.-> B C1["异步任务\n合并会话数据 → 全局记忆\n使用 LLM 进行去重\n过滤临时信息"] -.-> C D1["修剪会话历史至 N 条\n重新注入修剪笔记\n到系统提示中"] -.-> D style A fill:#2d3748,stroke:#4a9eed,color:#fff style B fill:#2d3748,stroke:#ed9a4a,color:#fff style C fill:#2d3748,stroke:#9a4eed,color:#fff style D fill:#2d3748,stroke:#4aed5c,color:#fff 阶段 1: 注入(Injection)—— 考试桌上的教科书 在会话开始时,AI 代理会准备好其初始上下文。这不是随意拼凑的,而是一个明确的结构: ...

2026年3月11日 · Fernando

OpenAI如何在没有分片的情况下,用一个主库支持8亿用户的PostgreSQL

每当有大公司的基础设施相关文章发布时,Hacker News 上总会出现一堆评论,内容大多是这样的变体:“当然了,他们用Kubernetes撑起了47个微服务,还加了一套自主开发的分布式共识协议数据库。”然而,当真相是他们只是用单纯的PostgreSQL主库和一点使用规范支撑其业务时,评论区就会陷入一片尴尬的沉默。 这次,OpenAI就再次打了这样一个大脸。 超出所有人想象的数字 OpenAI基础设施工程师Bohan Zhang刚刚分享了他们如何用PostgreSQL支持ChatGPT的具体细节。令人惊讶的数据如下: 8亿用户 单一PostgreSQL主库(写入操作专用)部署在Azure上 ~50个只读副本 每秒百万次查询 p99延迟仅10-19毫秒 99.999%的可用性 一年内仅出现一次SEV-0事故 (而且还是因为ImageGen产品的病毒式传播,让一周之内新增了1亿用户) 再读一遍。一个。主库。支撑8亿用户。 “可是他们为什么不分片?” 不需要。背后的原因非常简单而务实。 给PostgreSQL分片需要改动数百个应用的端点。每一个默认假设所有数据都在同一个数据库查询——基本是所有查询——都需要重写,来判断每个数据属于哪个分片。 这么迁移需要付出的成本呢?是数月的工作量、新的bug层出不穷,再加上一个混乱的迁移过渡期——同时需要维护老旧和新系统。 于是他们采用了另一种方式:识别最占用写入负载的数据,然后将其移至Cosmos DB。而这样做的原因并不是因为Cosmos比PostgreSQL更好,而是因为这些特定的工作负载更适合文档数据库模型。而其他大部分业务逻辑依旧保留在PostgreSQL中。 用大白话说:他们没有让整个系统变复杂,而是精确识别出问题所在,并有针对性地解决它。精密手术刀式的调整,而不是拿电锯一通乱砍。 PgBouncer:将连接延迟从50毫秒降到5毫秒 他们遇到的第一大瓶颈是建立连接的延迟。PostgreSQL会为每个新连接创建一个独立进程。而随着来自成百上千个应用Pods的并发连接数增加,光是处理新连接的开销就已达到50毫秒——甚至还没开始执行查询呢。 他们的解决方案是:使用PgBouncer作为连接池。PgBouncer会维护一个已经建立好的连接池,复用这些连接。结果是连接延迟从50毫秒降至5毫秒,直接减少了90%的延迟。仅仅通过更换一项底层工具,问题就得到了解决。 值得提到的是,这根本不是什么新技术。PgBouncer已经有15年以上的历史,并一直被各种规模的企业用于生产环境中。然而,它再次证明,一款久经考验的不起眼的工具,解决了这个地球上使用最频繁应用之一的问题。 那个做了12个表联接的ORM 这个问题是我的最爱。我见过它出现在学生的项目、初创公司,甚至银行的系统里。到处都有。 他们的ORM生成了包含12个表联合查询(join)的SQL语句。罪魁祸首并不是哪个设计人员,而是因为数据模型过于复杂且关系交织,ORM顺着这些关系“不假思索”地将每个可能的相关表都加载了进来。 解决办法既不是换ORM,也不是手动改写所有的查询。他们选择了将一些逻辑转移到应用层。与其让PostgreSQL执行一个庞大的join操作,他们分拆成多个简单查询,然后用代码对数据进行整合。 这么做优雅吗?的确没那么优雅。速度快吗?快得多。因为PostgreSQL处理简单查询比处理含有交叉条件的12表联合查询高效得多。而且,部分结果还能进行缓存和复用。 1 2 3 4 5 6 7 8 9 10 11 12 13 -- 之前:ORM生成的SQL SELECT u.*, p.*, s.*, t.*, ... FROM users u JOIN profiles p ON ... JOIN settings s ON ... JOIN teams t ON ... JOIN ... -- 总计12个表 WHERE u.id = $1; -- 之后:语句被拆分,逻辑移到应用层 SELECT * FROM users WHERE id = $1; SELECT * FROM profiles WHERE user_id = $1; -- 可缓存、可并行、可调试 每一条单独的查询都很简单。查询解析器几微秒内就可以完成。并且一旦其中有一条失败或者变慢,你可以直接找到问题所在。 ...

2026年3月11日 · Fernando

你的AI编程代理只是一个有着妄想的while循环

第一次使用 Claude Code 重构整个模块时,我有一种几乎神秘的体验。我描述了自己的需求,然后就去喝了一杯咖啡,等我回来时,眼前是一份包含14个文件更改的pull request,测试代码已更新,还有一条合格的提交消息。“这简直是魔法”,我当时想。 但这并不是魔法。这只不过是一个 while 循环。 最近,OpenAI 的 Michael Bolin 发布了一篇文章,揭秘了 Codex CLI 的内部运作方式。事实证明,那些所谓的AI 编程代理背后的秘密并不是某种革命性的算法,也不是神秘的神经网络。它实际上是一个调用 LLM 的循环,执行工具操作,然后一直重复,直到没有剩余的任务。 接下来,我们深入解析。 状态机:5个阶段和一个循环 每一个编程代理 —— 不管是 Codex、Claude Code、还是 Cursor —— 都遵循着同样的基本模式。Michael Bolin 将其描述为一个包含5个阶段的循环: flowchart TD A["1. 提示组装\n(构建 Prompt)"] --> B["2. 推断\n(发送到 LLM)"] B --> C{工具调用?} C -->|是| D["3. 工具调用\n(执行工具)"] D --> E["4. 工具响应\n(将结果返回 LLM)"] E --> B C -->|否| F["5. 助手回复消息\n(最终响应)"] F -->|新输入| A style A fill:#2d3748,stroke:#4a9eed,color:#fff style B fill:#2d3748,stroke:#4a9eed,color:#fff style C fill:#4a3728,stroke:#ed9a4a,color:#fff style D fill:#2d3748,stroke:#4a9eed,color:#fff style E fill:#2d3748,stroke:#4a9eed,color:#fff style F fill:#283d28,stroke:#4aed5c,color:#fff 通俗点说: ...

2026年3月11日 · Fernando