近日,有用户反馈在使用 Gemini、GPT 等主流大模型尝试生成几十页的标书或技术规范书时遭遇瓶颈。尽管输入文本在模型的上下文窗口限制内,但 AI 的输出往往被截断,无法一次性提供完整的数十页回复。这一现象揭示了当前 AI 领域的一个普遍矛盾:虽然厂商们热衷于竞赛“超长上下文窗口”,但在“长文本生成输出”能力上却存在明显短板。输出长度限制和连贯性维持,依然是阻碍 AI 在严肃文档撰写和深度办公场景中完全替代人工的关键技术障碍。
原文链接:Linux.do
近日,有用户反馈在使用 Gemini、GPT 等主流大模型尝试生成几十页的标书或技术规范书时遭遇瓶颈。尽管输入文本在模型的上下文窗口限制内,但 AI 的输出往往被截断,无法一次性提供完整的数十页回复。这一现象揭示了当前 AI 领域的一个普遍矛盾:虽然厂商们热衷于竞赛“超长上下文窗口”,但在“长文本生成输出”能力上却存在明显短板。输出长度限制和连贯性维持,依然是阻碍 AI 在严肃文档撰写和深度办公场景中完全替代人工的关键技术障碍。
原文链接:Linux.do
随着 AI 编程工具深度融入日常开发,开发者向 Claude、Codex 等大模型发送代码上下文时,敏感信息泄露风险日益凸显,例如 .env 文件中的 API 密钥可能被 AI 工具读取并上传。V2EX 用户分享了一款开源项目 FlashRoute,定位为支持数据脱敏的聊天与 AI 网关工具。其核心策略是在请求发送至 AI 之前先做脱敏处理,例如将真实密钥 sk-123456 替换为格式相同的假值 sk-ab1351;AI 基于假数据生成回复后,网关再将内容中的假值替换回真实值返回给用户。整个过程中,开发者使用体验不受影响,而 AI 模型接收到的均为伪造内容,真实密钥、token 等敏感数据不会离开本地环境。项目已在 GitHub 开源,作者称以 Vibe Coding 方式开发完成。该方案针对的是 AI 编程场景下的典型痛点:开发者既需要让 AI 理解完整项目上下文以获得最佳效果,又担心凭据、环境变量等随代码一并外泄。脱敏网关通过中间代理层实现双向替换,在 AI 提效与数据安全之间提供了折中路径,为个人开发者和小团队提供了一种低成本的隐私保护选择。
核心观点:AI 编程工具越强大,数据安全越致命,脱敏网关正从可选项演变为 AI 时代开发者的标配基础设施。
原文链接:V2EX 分享发现
一位开发者公开了其团队12个Claude Team账号连续一个月的用量统计:按CPA口径计算,全月消耗仅约3600美元,低于七八月份水平,当时每个账号每周至少跑出100美元用量,单月合计可超4000美元。作者还对比称,该总量甚至不及单个200美元档Claude Code账号一周的产出。表面数据上,账号可用率显示为92%,但实际情况是每次额度重置时都遭遇容量限制而无法使用;重置频率提高看似利好,但受5小时滚动限额约束,用户来不及在下次重置前跑完可用额度,形成结构性浪费。作者认为这个月是其体验最差的一个月,官方此前推出的28天周期调整等改动均未带来实际改善,模型可用性反而跌至低谷,且尚未计入模型’降智’与响应速度下降的问题。作者直言,与其频繁做重置活动,不如优先解决容量调度问题。该帖从重度用户视角,反映了Claude订阅服务在容量供给与限额策略之间的真实矛盾。
核心观点:当订阅量跑不赢算力瓶颈,可用率只是纸面数字——大模型竞争正从模型能力转向供给保障能力。
原文链接:Linux.do
V2EX“分享发现”板块出现一则开源项目推荐帖。起因是有用户在站内分享对搜狗输入法的逆向分析,引发开发者对输入法实现原理的讨论,一位开发者顺势介绍了自研的开源输入法项目“水杉输入法”(MetaSequoia IME),并公开了完整代码仓库。该项目在GitHub上分为三部分:其一是面向Windows平台的纯净版输入法,不捆绑任何推广内容和广告;其二是覆盖多种操作系统的全平台版本;其三是项目的技术核心——自研中文输入法语言模型(chinese-ime-lm),由团队自行训练,主要用于输入过程中的候选词排序、联想补全等功能。作者在帖末表示希望获得网友的GitHub star支持。从项目结构看,水杉输入法与搜狗、百度等主流商业输入法思路不同:后者依赖云端服务和用户数据积累优化输入体验,同时通过广告商业化;水杉输入法则走纯本地化路线,将语言模型直接部署在用户设备上,既避免云端请求带来的隐私顾虑,也消除了广告干扰。自训练语言模型的引入,使其在词频排序、整句联想等核心能力上具备一定智能化水平,而非仅依赖传统词库规则。开源输入法作为商业输入法的替代选择,正在成为部分注重隐私和体验的用户的新方向。
核心观点:当商业输入法靠广告变现时,开源项目以本地自训练模型切入,正把隐私与纯净体验转化为新的竞争筹码。
原文链接:V2EX 分享发现
Copper是一门由个人开发者独立设计的极简低级编程语言,支持面向对象编程(OOP)与泛型特性,近日在Hacker News上引发技术社区讨论。与主流语言多由团队或企业维护不同,Copper完全由一名开发者为自己使用而创建,其设计理念强调简洁性与底层控制能力的平衡。在语法层面,Copper采用Ruby风格语法,整体观感接近Python,但与Python显著不同的是,Copper不依赖缩进空白作为语法结构,这一差异在社区讨论中被反复提及。除语言本身外,作者的个人博客也受到关注,其中包含多篇编程语言设计相关的深度文章。尤其值得注意的是作者关于异常处理机制的设计思考:他曾为Copper实现异常机制,随后经过权衡又决定将其移除,这一决策过程为语言设计研究提供了难得的一手资料。此外,官方变更日志完整记录了Copper从诞生至今的演化轨迹,包括语法特性、标准库及各项设计取舍的迭代细节。参与讨论的用户认为,该项目展示了单人构建完整编程语言的可行性,其博客文章与变更日志的价值不亚于语言本身,可作为语言设计者的学习参考材料。目前该语言面向个人使用场景,尚未形成大规模生态。
核心观点:先实现异常再将其移除的完整决策记录,比语言本身更珍贵——它暴露了低级语言设计中错误处理这一被主流刻意回避的核心矛盾。
原文链接:Hacker News
极简框架把复杂度从框架搬到了你身上。循环本身只有 1445 行,它不替你做日志、不替你做预算、不替你做回滚、不替你做评测。它只保证一件事:模型做了什么、失败了什么,都变成事件发出来。剩下的账,得自己付。
20 条失败用例覆盖四类:调用不存在的工具、参数不合 schema、工具抛异常、工具超时。每条独立跑一次完整循环,统计失败信号是否送达模型、循环是否崩溃。
20 条用例,四类失败各 5 条。结果很干净:20 条全部产生了明确的错误结果,带 isError 标记和可读原因;循环零崩溃,每次都能继续或正常收尾。
四类的处理路径不一样。工具不存在时,循环直接生成「Tool xxx not found」的结果,不让模型空等;参数不合 schema 时,校验在执行前失败,工具根本没被调用;工具抛异常时,异常被捕获成错误结果;超时同理。
这个一致性是设计出来的,不是碰巧。它意味着模型永远知道「刚才那步为什么没成」,而不是收到一个空结果或者一个被吞掉的异常。上一代系统最缺的就是这一层。
| 失败类型 | 用例数 | 信号送达 | 循环崩溃 | 错误信息平均长度 |
|---|---|---|---|---|
| 工具不存在 | 5 | 5 | 0 | 74 字符 |
| 参数不合 schema | 5 | 5 | 0 | 90 字符 |
| 工具抛异常 | 5 | 5 | 0 | 77 字符 |
| 工具超时 | 5 | 5 | 0 | 88 字符 |
四类失败各 5 条,全部把错误如实送给模型,循环没有一次崩溃。
注意:但「信号送达」不等于「问题解决」。框架保证模型看见错误,不保证它看见之后能改对。实测里能跑通是因为策略是脚本化的、确定会换策略;真实模型可能在同一处反复试,这时候需要的是预算闸门和人工接管,不是更多的重试。
循环没有内置预算。模型可以一直调工具,直到上下文爆掉或者你手动停。必须在钩子里计次、在上层计 token,两道闸门都要有。
计次容易,计 token 麻烦——用量在 assistant 消息的 usage 字段里,要自己累加。累加的地方应该是 afterToolCall 或每轮结束,别放在界面层,界面层可能在重连后丢掉。
这不是理论风险。我让一个脚本化模型在同一个错误上反复重试:权限被拒,它继续读同一个路径。没有闸门时,30 轮上限内它把 30 次调用全用完了;加一条「8 次预算 + 拦下后 terminate」的规则,第 9 轮就收尾。

同一个死循环任务:无预算闸门时 30 轮上限内把 30 次调用全部用尽,加 8 次预算后 9 轮收尾。差的不只是次数,还有这 22 轮里每一个 token。
更值得记的是那 30 轮不是终点,是我给实验设的上限。没有 terminate,模型会在这个错误上继续试下去,直到上下文撑爆或者你手动 kill。脚本编排时代这个由进程超时兜着,循环里没有进程生命周期,只能靠钩子。
所以预算闸门要做两件事:到点拦住,并且让这一轮直接结束。只拦不终止,模型下一轮还会再请求同一个工具,你只是把频率降低了。
pi 生态里有独立的 pi-telemetry 包,但那是可选项。真正必须做的是把事件落盘:每个事件带会话 id、轮次、时间戳、工具名、耗时、结果摘要。有了这份结构化记录,任何一次线上异常都能重放出来。
反例是只记日志。日志是自由文本,事后要靠正则去猜当时发生了什么;事件是结构化的,可以直接算工具成功率、平均轮次、按失败类型分组。
循环会改东西——改文件、写库、重启服务。要能回滚,前提是每个有副作用的工具都留下「改之前是什么」。这件事框架不管,工具的作者必须管。
务实做法是给工具加一个 replay 策略字段:声明为 safe 的工具可以重放,声明为 never 的工具出错后必须人工确认。循环本身支持这个语义,但具体哪些工具是 safe,只有你知道。
真实模型做回归测试几乎不可能:温度、采样、上游版本都会让结果漂移。可行的做法是分层——循环用脚本化模型做单测,锁死「钩子是否拦截」「队列是否消费」「错误是否送达」这类行为;模型效果用固定用例集做抽查,允许答案措辞不同但要求关键结论一致。
评测集不要超过 30 条。超过就没人维护了。每条用例写清三件事:输入、期望的关键结论、不可接受的结果。
把这一篇和前九篇压缩成一张表。每一条都对应一个具体的失败模式,不是泛泛而谈。
| 检查项 | 失败模式 | 对应实验 |
|---|---|---|
| 工具描述能区分用途 | 模型选错工具、反复试同一个 | 04 |
| 失败带 code 与原因 | 模型不知道发生了什么,原样重试 | 10 |
| 危险动作有钩子 | 提示词约束失效,危险命令被执行 | 07 |
| 有调用预算 | 同一错误上无限重试,烧成本 | 07 |
| 上下文有剪枝策略 | 20 轮后上下文线性膨胀 | 06 |
| 长任务有进度事件 | 用户以为卡死,提前退出 | 05 |
| 支持插话 | 方向错了只能等跑完或杀进程 | 08 |
| 事件落盘可重放 | 线上异常无法还原 | — |
| 有回归集 | 换模型或改提示词后无据可依 | 10 |
回头看这十篇,pi-agent-core 做的事情可以一句话概括:它只实现循环,把所有判断留给你和模型。工具只有几个,没有 MCP,没有子 Agent,没有沙箱,没有计划模式。
这套设计的代价很明确,就是这一篇列的四件事都要自己做。收益也很明确:每个决定都是你做的,所以每个失败你都能定位。不会出现「框架内部在某处重试了三次」这种查不下去的情况。
从 LangGraph 迁过来最大的变化不是代码少了,是心态变了。以前你在设计图的形状,试图把所有分支提前想到;现在你在设计工具和闸门,接受模型会走弯路。前者追求确定性,后者追求可恢复性——面对开放的任务,可恢复比确定更值钱。
十篇的实验代码都在一个仓库里,每个数字都能自己跑一遍。如果你的场景是流程固定、分支可穷举,状态机仍然是更好的选择;如果你的场景是排障、调研、修复这类「下一步取决于这一步看到了什么」的任务,循环的性价比会高得多。
前八篇讲的是循环怎么用,这一篇讲怎么把一个已经在跑的系统换过去。改造不需要推倒重来——把「固定调用」换成「给工具加判断」,把「退出码」换成「结构化结果」,把「暗依赖」换成「显式参数」,三步就能让同一批任务从 20% 通过率走到 100% 有结论。
沿用第 1 篇的 30 个任务集:6 类故障、两类编排器。这一篇逐条对照 7 项差异,并统计 24 个失败任务在改造后的去向。
典型的写法是:平台里写一行 subprocess.run,参数固定为 –log-dir 和 –output-json,脚本名固定,cwd 不传。这一行代码在 80% 的情况下工作良好,所以没人觉得有问题。
问题出在剩下 20%。脚本可能叫 analyze_log.py,可能放在 scripts/ 子目录,可能需要额外参数。每一种变化都要改一次平台代码、发一次版本、等一次审批。改到最后,平台里堆了十几个 if 分支,每个分支对应一个客户现场的目录结构。
改造方式是把调用权交给模型:给它 ls 看目录、read 看内容、bash 执行。模型先看有什么,再决定跑什么。平台代码里一个分支都不用留。
# 改造前:一条路走到黑
subprocess.run(['analyze.py', '--log-dir', d, '--output-json'], check=True)
# 改造后:模型自己决定
# 模型看到 ls 输出 -> 发现 scripts/ -> 再 ls -> 找到 analyze_log.py -> 拼命令执行
# 平台只提供三个原语:ls / read / bash
背景:有人会担心「让模型拼命令不安全」。这个担心是对的,但解法不是把命令写死,是在 bash 工具前面加钩子——路径白名单、命令黑名单、预算上限。第 7 篇的实测里,这一步能把危险命令拦到零执行。
脚本世界里,退出码是唯一的结构化信号。0 成功、1 通用错误、2 用法错误、其他是脚本自定义。问题在于:宿主往往只认 0 和 2,其余全部压成「失败」。
被压掉的恰恰是最有信息量的部分。脚本返回 4 可能意味着「数据里有除零,我需要你看一眼」;返回 3 可能意味着「这里没有分析脚本,你要不要直接读日志」。宿主看不懂,模型更看不懂——它收到的是一个没有原因的异常。
更糟的是同码不同义。python 找不到文件也返回 2,脚本主动 exit(2) 表示「交给模型」也返回 2。宿主把两者都当成「交给模型」,于是「脚本不存在」也被当成了「需要模型判断」,模型一脸茫然地收到一个它无法处理的请求。
改造的关键是别再用退出码传递语义。工具应该返回结构化结果:成功带数据,失败带 code 和 message,需要人判断就明确写出来。上层拿到的是对象,不是数字。
实测里最有说服力的是这一类任务:脚本主动返回 2 表示「时间戳跨时区,脚本判断不了先后」。脚本式编排把它当成需要模型介入,但宿主没有接的逻辑,任务就此卡死。循环式编排里,模型拿到这个结果后直接 read 日志,自己给出了结论。同一批 4 个任务,从零通过变成全部通过。
启动子进程不传 cwd,脚本里的相对路径就依赖父进程的工作目录。开发机上恰好对,部署到服务里就不对。这类 bug 最难查,因为它不报错,只是读不到文件然后走默认值。
循环式编排天然规避了这个问题——bash 工具必须显式接收 cwd,模型每次调用都要指定在哪个目录跑。强迫显式,等于强迫正确。
但要注意另一面:显式之后模型可能传错 cwd。所以工具实现里应该校验目录存在,不存在就返回明确错误,而不是让它继承一个默认值然后静默失败。
| 维度 | 脚本编排 | Agent 循环 | 改造动作 |
|---|---|---|---|
| 调用方式 | 固定命令固定参数 | 模型按目录内容拼 | 暴露 ls / read / bash |
| 失败语义 | 退出码 0/2 白名单 | 结构化结果带 code | 工具返回对象而非数字 |
| 退出码歧义 | 同码不同义,无法区分 | 由工具实现消歧 | 错误消息里写清原因 |
| 工作目录 | 继承父进程,静默失败 | 每次显式传 cwd | 工具校验目录存在 |
| 资源预算 | 轮次和超时写死在宿主 | 钩子里计次 | beforeToolCall 加预算闸门 |
| 找东西 | 路径写死,找不到就失败 | 模型自己探索 | 给探索工具而不是给路径 |
| 判断归属 | 脚本判定,宿主无法接管 | 模型拿到结果再判断 | 删除宿主的分支逻辑 |
第 1 篇里脚本式编排有 24 个任务失败。同一批任务交给循环之后:19 个被自动处理完,5 个带原因上报(目录不存在),0 个变成无信息的失败。
19 这个数字值得拆开看:找不到脚本的 10 个里,6 个直接读日志得出结论,4 个在子目录里找到脚本;脚本返回 4 的 5 个和返回 2 的 4 个,全部靠 read 日志收尾;剩下的就是原本就正常的 6 个。
5 个上报的也没浪费。它们给出的结论是「目录不存在,需要人工确认路径」——这不是能力不足,是正确行为。人接手只需要改一个配置,不需要重新排查一遍。

24 个失败任务改造后的去向:19 个自动处理完成,5 个带原因上报人工,没有任何一个落在「无信息失败」。
成本侧也要说清楚。脚本式跑 30 个任务花了 30 次子进程调用;循环式花了 63 次工具调用,平均每个任务 2.1 次。多出来的调用就是探索成本——ls 一次、read 一次,然后才动手。
这笔账划不划算,取决于失败一次的代价。如果失败意味着一个人工介入、一次重跑、一次客户投诉,那多两次工具调用完全不值一提。如果任务本身极其简单、失败率本来就接近零,那确实没必要上循环。
不要一次性切。第一步让两套并行跑同一批任务,只记录不切换,对比结论是否一致、循环式的额外成本有多少。这一步通常能暴露出脚本里那些没人知道的隐式约定。
第二步挑一类任务真切换,选失败率最高但影响面最小的那类。跑一两周,看人工介入率的真实变化。
第三步才是全量。这时候你已经有了真实的对照数据,也有了「它什么时候会出错」的直觉。
有一件事必须提前做:把脚本的退出码语义整理成文档。你会发现有几种码连原作者都说不清含义。这些是迁移路上最硬的部分,跟框架无关。
最后一篇讲上线之后。框架能保证失败信号送达模型(实测 20 条用例全部送达),但它不保证模型判断正确、不保证成本可控、不保证线上可回滚。这些是你要自己搭的。






评论前必须登录!
立即登录 注册