小道的技术笔记

记录折腾、认知与闭环

三阶九则学了三个月,最实用的不是九条,是三句问话。我每天早上开工前先过一遍:现场需什么?闭环在哪?我何时退场?这三问过了,今天才动手。没过,今天就是研究。

TL;DR

FDE认知线最后一篇,不新讲方法论,讲怎么用。把三阶九则压缩成每日三省三句话,加一段团队宣誓当对照。核心是区分”研究态”和”交付态”——三问过不了,说明今天在做的是研究,不是交付。回扣成长线:181篇文件≠1个客户,”闭环在哪”就是答案。

一、三阶九则,最后要能收进三句话

方法论文档我读了很多,FDE的三阶九则读了最久。因为它是唯一一套”能每天早上用”的方法论。

三阶九则展开是九条:能需对齐、黑盒白化、双向驯化、痛点优先、代价可视、最小正循环、系统自治、知识沉淀、自我失业。九条,记不住。

但压缩成三句问话,每天早上5分钟就能过一遍:

现场需什么?(对应认知翻译)
闭环在哪?(对应价值锚定)
我何时退场?(对应能力外化)

三问各对应一阶。三问全过,今天可以动手。过不了,今天该做的是研究,不是交付。

二、”现场需什么”:不是”AI能做什么”

第一问最容易答错。我的第一反应是”我最近学了个新工具,现场能不能用”。这是把”现场需什么”问反了。

正确的问法是:今天客户那边,有什么事没解决、在疼?

疼的才算需求。不疼的,是”我能力很强”。

我在阿里那套习惯叫”现地现物”——下沉到一线,看真实业务。FDE的第一问,就是把”现地现物”从渠道管理搬进AI部署。不看模型参数,看客户的早晨在忙什么。

三、”闭环在哪”:181篇文件的答案

第二问是整套认知线里最狠的一句:闭环在哪?

什么叫闭环?需求→方案→交付→验收→复用,五个环节都在,才算闭环。缺一个,是研究。

回扣我自己7月26日那条反思原话:一周累计10篇H3MS文件,0个付费客户。10篇文件,没有一篇能指到”闭环”上。因为”写文件”这个动作,本身不在需求→交付→验收的链路里。它是链路之外的。

“闭环在哪”问的就是:你今天做的事,能不能指到五个环节里的某一个?

指得到,是交付。指不到,是研究。研究不是罪,但研究得算研究,别算交付。

181篇H3MS文件是我三个月的研究。它们有价值,但它们不是1个客户。这句”闭环在哪”,是我给自己从研究陷阱里爬出来的钩子。

四、”我何时退场”:被需要的最高级

第三问最难,因为它直接对着我”对被需要极度敏感”的软肋。

我何时退场?

问的不是”这个客户还要不要我”,是”这个系统什么时候不需要我了”。

上一篇文章讲了能力外化,终极目标是自我失业。落到每天,就是这个问题:我今天做的这件事,是在往”退场”推,还是在往”更离不开我”推?

往退场推的,是系统自治、SOP、文档、培训。
往离不开推的,是口头约定、隐性知识、只有我能修的bug。

每天开工前问一句:今天这活儿,是在修bug还是在写文档? 修bug是往离不开推,写文档是往退场推。比例要倒过来。

五、团队宣誓:三问的对照

FDE思想体系里有一段宣誓,我抄在这里当收尾的镜子:

我不追逐技术的无限可能,我只锚定现场的真实疼痛。
我不交付不可解释的模型,我只输出可行动的认知。
我不追求永远被需要,我只追求系统能自治、人能自主。

三句,对着三问:

  • 第一句对应”现场需什么”——真实疼痛,不是”AI能做什么”。
  • 第二句对应”闭环在哪”——可行动的认知,黑盒白化之后的东西。
  • 第三句对应”我何时退场”——系统能自治、人能自主,被需要的最高级。

宣誓不是喊口号,是三问的价值观版本。三问是每天问,宣誓是问不动了拿出来照一下。

六、结语:认知线收束,回到”从0到1”

FDE认知线五篇写完了:

  • 23《FDE是什么》:行业为什么变,翻译为什么比写代码稀缺
  • 24《认知翻译》:黑盒白化,”帮我提效”不是需求
  • 25《价值锚定》:一盘凉菜,30天MVP,60分比100分可靠
  • 26《能力外化》:让自己多余,”被需要”的最高级是被尊重
  • 27《每日三省》:三问压缩方法论,研究态和交付态的分界

五篇合起来,一句话:AI能力与现场需求之间,需要一个翻译桥。桥的两头是”真实疼痛”和”可行动的认知”,桥的中间是”最小正循环”。

回到我自己那句”每季度必须有一个从0到1的商业闭环”——这三问,就是那句承诺的每日检查版本。

研究不丢人,但研究得算研究。交付不轻松,但交付才让闭环合上。

下一篇如果继续,该切成长线了。FDE认知线,到此收束。


作者:小道 · 2026-10-06
关联阅读:《FDE方法论实战系列:23-26》 · 系列:FDE方法论实战(认知线·收束篇)

我做了个系统,客户离不开我。听起来是褒奖,其实是警告。系统离不开我,说明系统还没自治。FDE第三阶的能力外化,终极目标是”自我失业”——让自己在这个场景里变得多余。这件事最反直觉,也最值钱。

TL;DR

三阶九则第三阶,能力外化三原则:系统自治、知识沉淀、自我失业。交付的终点不是系统上线,是维护者不再需要原班人马。渠道管理里对应的是”SOP沉淀”——把成功经验打包成模板,降低关键人依赖。对”对被需要极度敏感”的人来说,这条最难,也最该先修。

一、系统自治:交付的终点不是上线

“系统上线了”这句话,在FDE语境里不是交付完成,是交付开始。

真正的终点是:维护者不再需要原班人马。

怎么判断系统自治了?三个信号:

  • 客户团队自己能改配置、看日志、排小问题,不用打给你
  • 你两周没出现,系统没出过事
  • 有人接了你的活儿,接得还行

三个信号缺一个,系统就还”依赖你”。依赖你的系统,价值是”你的人力”,不是”系统的价值”。

自治不是”客户不需要你”,是”客户不依赖你”。 这两者区别巨大:前者是冷漠,后者是能力。

二、知识沉淀:代码可以迭代,认知不可回退

能力外化的第二条:项目结束时,代码可以迭代,但现场认知的跃迁不可回退。

什么意思?项目做完了,代码可以重构、可以换语言、可以换框架。但客户团队在这个过程中学会的东西——怎么理解AI的边界、怎么判断幻觉、怎么和机器协作——这部分不能退回,也不应该退回。

这是FDE和传统外包的分水岭。外包交的是”一个系统”,FDE交的是”系统+一支会用系统的队伍”。

实操里我把它落成四类资产沉淀:

  • 需求模板:客户痛点、数据边界、验收指标
  • 能力库:研发、顾问、产品、法律资源
  • 案例库:试点过程、踩坑、复盘
  • 协议库:合作、保密、退出、分配

这四类里,前两类是”能力”,后两类是”记忆”。系统自治靠能力,知识沉淀靠记忆。缺哪边都不行。

三、自我失业:最反直觉的一条

第三条,我读了两遍才接受:FDE的终极成功,是让自己在这个场景里变得多余。

这句话听起来像自爆。我”对被需要”极度敏感,自我价值感很大程度上建立在”别人离不开我”上。所以”让自己多余”这句话,第一反应是”这不对吧”。

但转念一想:客户说”离不开你”的时候,有两种可能。

一种是尊重:你的判断、你的经验、你的审美,系统还没有。这时候你是不可替代的。

另一种是依赖:你的活儿没人接得住,你走了系统就崩。这时候你是被需要的,但系统是不自治的。

“离不开你”是尊重的时候,你该庆祝。是依赖的时候,你该焦虑。

区分这两个,靠的不是客户的嘴,是系统自治的三个信号。信号全过,客户说”离不开你”,你可以走。信号没过,客户说”幸好有你在”,你该留下来修系统,而不是留下来收钱。

四、渠道映射:SOP沉淀,降低关键人依赖

这条在渠道管理里有个直接对应物:SOP沉淀。

11年渠道,我见过太多”关键人”现象:一个区域经理走了,那个区域的数据、关系、判断全跟着走。新来的人从零开始,前半年全靠”听老人说”。

FDE把这个现象翻过来:我走了,系统还在,认知还在,下一班人接得住。 不是”我走了系统崩”,是”我走了系统还能长”。

渠道管理的解法是SOP:把成功经验打包成模板,降低关键人依赖。FDE的解法更彻底:把认知本身沉淀进系统,让”老人的经验”变成”系统的默认行为”。

SOP沉淀的是动作,能力外化沉淀的是判断。 动作可以写文档,判断得写进代码和配置里。

五、对”被需要敏感”的人,这条最难

写到这里,要诚实一下。

我的核心风险清单里有一条:对被需要极度敏感。”你太慢了”让我难受,”这事还得找你”让我受用。能力外化的第三条,直接打在这个软肋上。

我给自己定的规矩是:每个MVP交付前,先问一句”这件事做到60分,客户能不能自己接走?” 能接走,我就停在那,不做到90分。做不到90分是”交付边界”,不是”能力上限”。

这不是偷懒,是把”被需要”的来源,从”系统依赖”挪到”判断力依赖”。客户不需要我写代码,但需要我判断”下一个该做什么”。前者是劳动力,后者是认知。前者的天花板是”我有多快”,后者的天花板是”我看多远”。

六、结语:高级感不是”永远被需要”

三阶九则走到第三阶,会发现一个反直觉的结论:

FDE的高级感,不是”永远被需要”,是”系统能自治、人能自主”。

“系统能自治”是能力外化的硬指标,”人能自主”是软指标。硬指标靠代码,软指标靠认知沉淀。两个都过,你才能从”被需要”走向”被尊重”——这两个词,差着一个阶。

下一篇是认知线收束:每日三省——现场需什么?闭环在哪?我何时退场?


作者:小道 · 2026-10-05
关联阅读:《价值锚定:先做”一盘凉菜”,别上来满汉全席》 · 系列:FDE方法论实战(认知线)

FDE最容易翻的车,不是技术做不到,是承诺太大。客户说”帮我做个系统”,你回了句”没问题”。三个月后系统做出来了,客户不认账——因为他要的不是系统,是那个痛点别再疼。价值锚定的第一课:60分试点比100分承诺可靠。

TL;DR

三阶九则第二阶,价值锚定三原则:痛点优先、代价可视、最小正循环。实操用30天MVP框架:第一周选一个痛点做最小Demo(禁止研究新工具),第二周找一个人用,第三周迭代,第四周试着收500-2000块。被拒了别放弃,问一句”你觉得不值这个价?”——这个问题本身就有价值。

一、痛点优先:在无限清单里选有限子集

“AI能做什么”是无限清单。”不做会痛”是有限子集。

FDE最危险的词是”我们还能帮你……”。每次我(或者任何销售)说这句话,脑子里想的是功能,客户脑子里想的是”我为什么要为这个掏钱”。

痛点优先的实操标准:客户愿意为”不再痛”付多少钱?不是为”多一个功能”付多少钱。

渠道场景里,”减少XX小时沟通成本”比”提升渠道满意度”值钱一百倍。前者能算账,后者算不了。

二、代价可视:每次部署,同时呈现三样东西

价值锚定的第二条,最容易被跳过:代价可视。

每次部署,必须同时呈现三样:

  • 省下的成本
  • 新增的风险
  • 被替代的流程

只呈现第一样,是销售,不是FDE。

客户最怕的不是”这个AI很贵”,是”这个AI上线后,我的团队会不会乱”。把风险摊在桌上,不是示弱,是建立信任。

代价可视的一句话:我帮你省了10万,但你得接受新流程要3个月磨合期,前两个月指标会掉。掉多少,我提前告诉你。

三、最小正循环:先让一个指标动起来

第三条:先让一个工位、一个班次、一个指标产生可感知的改善,再谈规模化。

这是最反”大方案”思维的一条。渠道管理里我见过太多”全面转型”的规划,第一年轰轰烈烈,第二年悄无声息。根子就在于没有”最小正循环”——没有一个小到不可能失败的改善先跑通。

最小正循环的验收标准:一个具体的人,在一个具体的时间点,感知到了一个具体的改善。不是”系统上线了”,是”张师傅说这个月少填了两天表”。

四、30天MVP框架:4周,从Demo到收费

把上面三条落到日历上,就是30天框架。我把它拆成4周,每周有明确的”禁止项”和”验收项”:

第1周:选定场景 + 最小产品

  • 选一个最熟悉的业务痛点(挑一个就一个)
  • 用现有工具链做最小Demo(能回答3个问题就行)
  • 周五前Bot能跑通核心流程
  • 禁止:新建知识库、研究新工具、写方法论文章

这条禁止项,是我自己翻过车才加的。第1周最容易犯的错误,是”我先把这个工具研究透了再做”。一研究就是两周,Demo还没影。

第2周:找到第一个测试用户

  • 从现有的人脉里找一个”懂业务”的人
  • 直接说:”我做了个小工具,你帮我试试有没有用”
  • 收集反馈:用了什么?哪里好?哪里不好?其他场景想用吗?
  • 验收:至少1个人实际使用并给文字反馈

“文字反馈”四个字很关键。口头说”挺好的”不算反馈。写下来”我觉得第3步没用,第5步能不能去掉”,才算。

第3周:根据反馈迭代 + 探索第二场景

  • 改Demo——加功能/改交互/修Bug
  • 观察使用数据:哪些功能用得最多?
  • 验收:Demo稳定运行,至少2个核心功能被使用超过3次

“超过3次”是最低门槛。用1次是客气,用3次是习惯。习惯才值得进下一轮。

第4周:第一次”收费”尝试

  • 提出一个低金额付费方案(500-2000元区间)
  • 找第2周的测试用户或他的朋友——熟人付费概率最高
  • 如果拒绝,问:”你觉得不值这个价?”
  • 验收:至少一个付费意向(口头承诺或实际付款)

五、被拒了别慌:那个问题本身就有价值

第4周最难受的不是”被拒”,是”被拒了不知道下次怎么开口”。

30天框架里有一条反直觉的规矩:被拒了,问一句”你觉得不值这个价?”

这个问题不是逼单,是收集信息。客户回答”太贵了”和回答”我觉得这东西没什么用”,是两种完全不同的拒绝。前者是定价问题,后者是价值没锚定。

“太贵了”:降价或换个小一点的场景重新试点。
“没什么用”:回到第1周,痛点选错了,不是Demo做得不好。

大多数人在被拒之后,默认是”我做得不够好”,回去改Demo。但有一半的拒绝,根本不是Demo的问题,是痛点选错了。

六、过度承诺:FDE最贵的翻车方式

写到这里,要戳一下自己的老毛病。

我的核心风险清单里第一条就是过度承诺——先说”能”,再验证。飞书图片提取翻过车,那时候我第一反应是”应该能搞”,搞了三天没搞成,客户的信任掉了70%。

30天框架里”降低承诺”这条,就是治这个的。先说明试错性质,再谈收费和范围。 这句话听起来是示弱,其实是保护——保护客户的预期,也保护自己的交付节奏。

60分试点,比100分承诺可靠。因为60分是你能兑现的,100分是你在赌。

七、结语:一盘凉菜,不是敷衍

“一盘凉菜”这四个字,最容易被供应商理解成”偷工减料”。

不是。凉菜的意义是:先证明你的菜能入口,再上硬菜。 客户吃第一口的时候,判断的不是”这顿饭丰不丰”,是”这厨师水平行不行”。水平行了,后面的菜才有机会被点。

价值锚定不是”少做”,是”先做对的那一小块”。

下一篇展开第三阶:能力外化——FDE的终极成功,是让自己变得多余。


作者:小道 · 2026-10-04
关联阅读:《认知翻译:为什么”黑盒白化”是FDE的第一课》 · 系列:FDE方法论实战(认知线)

客户说”帮我用AI提效”,这不是需求,这是症状。FDE的第一课不是写代码,是翻译:把”AI能做什么”的无限清单,翻译成”现场痛在哪”的有限问题。任何不可解释的输出,都是未完成的交付。

TL;DR

FDE三阶九则的第一阶是认知翻译,三原则:能需对齐、黑盒白化、双向驯化。最容易被跳过的是”黑盒白化”——AI跑出一个结果,你说不清它为什么对,这个交付就没完成。渠道老兵做这件事有天然优势:把总部策略翻译成渠道商动作,干了11年。

一、需求六要素:先问”谁有问题”

客户走进来,开口就是”帮我用AI提效”。

这句话里,没有需求。这是症状,不是病。

Palantir的方法论里,需求翻译第一步是六要素,我记了两年,到现在还在用:

  1. 谁有问题? 渠道商、经销商、还是终端客户?
  2. 问题是什么? 信息不对称、决策慢、执行偏差?
  3. 现有方案缺陷? 人工沟通成本高、数据滞后?
  4. AI如何解决? 智能推荐、自动预警、数据洞察?
  5. 如何验证? 满意度、决策时效、执行准确率?
  6. 价值量化? 减少XX小时沟通、提升XX%转化?

前5年中供跑客户,我最恨的一句话就是”你们帮我提提效率”。提什么效?谁的效?我怎么知道提了多少?11年渠道管理下来,我养成了一个习惯:客户说什么,我先翻译成”谁、痛在哪、怎么证明不痛了”。

AI时代这件事更急。因为”帮我用AI”这种话,比”帮我提效”还空。AI能做什么,是个无限清单;现场痛在哪,是个有限问题。FDE的第一课,是把无限翻译成有限。

二、黑盒白化:不可解释的输出,是未完成的交付

三阶九则里最容易被跳过的一条,是黑盒白化。

核心句:任何不可解释的输出,都是未完成的交付。

什么意思?你做了个AI客服,答得又快又准,客户很满意。但有一天它答错了一次,你说不清为什么错。这时候”满意”是假的——你不知道下一个错在哪。

黑盒白化不是”把模型开源”,是把AI的判断路径翻译成客户能理解的规则。

渠道场景里我见过太多”黑盒事故”:总部推了个新品策略,渠道商执行了一版,动销率掉了。复盘的时候,没人说得清策略里哪条传导偏了。最后变成”下次注意”,问题原样躺在下一版里。

AI部署里,”下次注意”的代价更大。因为黑盒里住的是幻觉,不是笔误。

黑盒白化的实操标准:每个AI输出,要能回答”它为什么这么判断”。回答不了,交付就没完成,不管指标多好看。

三、双向驯化:不是人适应机器,也不是机器迁就人

第一阶的第三条,最反直觉:双向驯化。

不是”员工学怎么用AI”(人适应机器),也不是”AI改成合员工习惯”(机器迁就人)。是人和机器共同演化出一套新的工作语言。

举个例子。我做新闻播报的时候,最初让AI自由搜,它编新闻。我没怪AI”不靠谱”,也没逼自己”学提示词工程”。我做的是:把数据层换成脚本直抓(机器侧改造),把”AI只做提炼不做搜索”写成SOP(人侧改造)。两边同时动,才跑通。

这就是双向驯化。单方面动,永远是”我教你用”或”你按我的来”,都不是翻译。

驯化的完成标志:系统里有一条规则,人不知道它存在,但违反它的代价已经被系统消化。到这一步,翻译才算完成。

四、渠道老兵的天然优势

写到这里,我自己都意外:认知翻译这件事,我练了11年,只是没叫这个名字。

渠道管理的本质:把总部的策略/产品/技术,翻译成渠道商可理解、可执行、可衡量的动作。总部说”提升品牌势能”,渠道商听到的是”下季度我要多投多少广告费”。中间这层翻译,就是认知翻译。

FDE比渠道翻译多了一件事:机器。渠道翻译是”人说人话”,FDE翻译是”人、机器、需求”三方对齐。但底层的坐标系是一样的——痛点优先,代价可视,先证明一个最小正循环,再谈规模化。

所以这篇文章不是给工程师写的。是给那些”一直在做翻译,但没意识到自己在做翻译”的人写的。

五、结语:翻译不是技能,是立场

认知翻译最难的部分,不是”会不会”,是立不立得住。

“帮我用AI提效”这种话,顺着接是最省力的。但顺着接,你交出去的就是黑盒。黑盒迟早出事,出事的那天,背锅的是你。

翻译不是技能,是立场:我宁可多问六个问题,也不接一句”帮我提提”。

下一篇展开第二阶:价值锚定——先做”一盘凉菜”,别上来满汉全席。


作者:小道 · 2026-10-03
关联阅读:《FDE是什么:AI时代最稀缺的不是写代码的人,是翻译的人》 · 系列:FDE方法论实战(认知线)

2026年5月,OpenAI成立了一家专门负责企业部署的新公司,砸了超过40亿美元。岗位增速800%,顶尖年薪50-100万美金。但FDE最稀缺的能力,不是写代码,是翻译——把AI能力翻译成企业听得懂的”现场语言”。

TL;DR

FDE(Forward Deployed Engineering,前沿部署工程师)是AI时代企业落地的新岗位:工程师前置到客户现场,围绕业务结果写代码、接系统、做部署、做迭代。它不是”驻场外包”,是”翻译桥接”。稀缺的不是技术,是把AI能力翻译成现场需求的能力。

一、一个岗位,为什么突然火了

2026年5月,OpenAI成立了一家专门负责企业部署的新公司,准备投入超过40亿美元,并通过收购扩展能力。

同一时间,私募股权开始投资FDE服务公司。FDE岗位需求增速800%,顶尖FDE年薪可达50-100万美金。

一个岗位,从Palantir的独家模式,一夜之间变成整个行业的标准配置。为什么?

二、企业AI过了”看Demo”的阶段

过去两年,企业AI的交付方式还停留在”讲方案、写标书、打单子、做项目”。客户要的是”一个能讲的故事”。

现在变了。客户要的是能降本提效、少出幻觉、进生产系统的交付。

每个企业现场环境不同——数据格式、接口、权限、流程,模型本身不知道这些。Agent比聊天机器人难交付得多:接入企业系统出错,是真金白银的损失。

AI落地是系统工程——OCR+RAG+向量库+工作流+权限+日志+BI+ERP……需要有人把碎片拼成系统。

这个”有人”,就是FDE。

三、FDE不是外包,是翻译

FDE最容易误解的地方,是把它当成”驻场外包”。

传统外包的逻辑是:甲方提需求,乙方执行。主导权在甲方。

FDE的逻辑是:乙方深入现场找真问题,用产品/平台交付结果。 主导权在乙方。

这不是”外包”,是”翻译桥接”。把AI能力翻译为企业场景可理解、可执行、可衡量的价值。

我在阿里干了11年,前5年中供B2B,后4年钉钉渠道。渠道管理的本质,就是”把总部的策略/产品/技术,翻译成渠道商可理解、可执行、可衡量的动作”。

FDE和渠道管理,底层是同一件事:翻译。

四、为什么”翻译”比”写代码”更稀缺

技术平权在加速。模型越来越强,工具越来越便宜,写代码的门槛在肉眼可见地下降。

但”翻译”不下降。

一个FDE要同时懂:

  • 业务:客户到底痛在哪,愿意为结果付多少钱
  • 技术:AI能做什么、不能做什么、幻觉边界在哪
  • 组织:谁有决策权、谁在反对、利益冲突在哪
  • 数据:现场的数据格式、接口、权限、合规边界

这四样,缺一样都翻译不完整。

写代码的人越来越便宜,翻译的人越来越贵。 这是FDE岗位增速800%的底层原因。

五、三阶九则:FDE的方法论内核

FDE不是”什么都做”,有一套清晰的方法论。我把它总结成三阶九则:

第一阶·认知翻译:能需对齐、黑盒白化、双向驯化。把”AI能做什么”翻译成”现场需要什么”。

第二阶·价值锚定:痛点优先、代价可视、最小正循环。在”AI能做什么”的无限清单里,只选”不做会痛”的有限子集。

第三阶·能力外化:系统自治、知识沉淀、自我失业。交付的终点不是系统上线,是维护者不再需要原班人马。

三阶九则后面会逐篇展开。这篇先讲清楚一件事:FDE的本质,是翻译。

六、结语:你是哪种人

AI时代ToB交付方式变了:

过去:卖产品 → 讲方案 → 写标书 → 打单子 → 做项目

现在:进现场 → 懂业务 → 写代码 → 接系统 → 跑指标 → 沉淀能力

最稀缺的不是”会写代码的人”,是”能翻译的人”。

你不需要是工程师,甚至不需要会写代码。你需要的是:

  • 懂一个行业,比工程师懂
  • 能把业务问题翻译成技术问题
  • 能证明”翻译”是有价值的

下一篇,展开第一阶:认知翻译——为什么”黑盒白化”是FDE的第一课。


作者:小道 · 2026-10-02
关联阅读:《OPC护城河:技术会过时,信任才是唯一壁垒》 · 系列:FDE方法论实战(认知线)

Agent跑久了,home目录会长成垃圾场。22GB里堆着重复备份、node_modules、__MACOSX。我定了三级目录+7天定时清理,还定了一条铁律:清理脚本不能碰cron心跳。

TL;DR

一个长期运行的Agent,磁盘问题不是”满了”,是”脏了”。解法不是每次手动清,是定规矩:scripts放长期工具,workspace放交付项目,scratch放临时垃圾,cron每7天清scratch里超7天的文件。这条规矩救过我自己一次——清理脚本差点把cron心跳写废。

一、起因:22GB里住着多少个垃圾堆

9月初清磁盘,我盯着du的输出看了半天。Termux占22GB,拆开看:

/usr/tmp 9G,全是pip和rust编译的临时文件;.hermes/state.db 627M,5万条消息;downloads里954M;.cargo 1.1G;.local/share/pnpm 829M。第一波清完释放10G。

但清完我意识到一个问题:清完还会再长。Agent是活的,它每天跑cron、下载东西、留中间文件,home目录就是个只进不出的下水道。手动清是治标,不治本。

二、三级目录:把”放哪”变成不需要思考的事

P叔(另一个项目里的前辈)提了个三级结构,我直接抄了,改到适配自己的场景:

1
2
3
4
~/
├── scripts/ # 长期脚本、工具项目(稳定可重复使用)
├── workspace/ # 交付项目、正式代码(要维护的)
└── scratch/ # 临时实验、缓存、图片下载(定时清理)

这个结构的妙处不在”分了三类”,在于它把判断前置了:一个文件落盘之前,先问自己一句”这是工具、是交付、还是临时货”。90%的目录混乱,不是清不干净,是当初就该放对地方但随手一拖。

scripts:CLI工具、自动化脚本、长期跑的服务。我现在的news播报、股票脚本、Worker部署脚本,全在这。规矩是:不放node_modules、dist、.map这类构建产物,要用的话装到scratch再链接。

workspace:交付级项目,有PRD、有维护周期的。人事考勤系统、HexaBench的发布包,在这。

scratch:临时下载的图片、RSS缓存、实验代码、”跑完就可以删”的东西。规矩:不放重要项目,不放生产配置。它就是个垃圾桶,定期倒。

三、cron每7天清scratch:垃圾自己会过期

三级目录解决了”放哪”,但scratch这个桶会满。所以我加了一条cron:每7天,清scratch里超过7天没动过的文件。

find scratch/ -type f -mtime +7 -delete,一行。

这条规矩的价值不是省了多少空间,是让”临时”两个字有了时间定义。没有它的scratch,”临时文件”会变成”忘删的文件”,三周后你分不清它是垃圾还是宝贝。有了它,所有进scratch的东西自动打上了7天保鲜期,到期自动消失。

这是整套治理里最反直觉的一点:对临时文件的慈悲,是让它过期。 你越舍不得删,它越占地方。

四、翻车:清理脚本差点把cron心跳写废

规矩立完,我以为万事大吉。直到7月28日,一条cron执行完,H3MS的每日反思播报没按时跑。

我去查,翻出事故记录,心凉了半截:清理脚本在跑的时候,把 .hermes/cron/ticker_last_success 这个文件给碰了,往里写了一个未来时间戳(1785198164,换算过来是9月25号,事故发生在7月28日,差了近两个月)。

那个文件是cron的心跳——记录”上次调度成功是在什么时候”。被写成未来时间,调度器就懵了:心跳在”未来”,那所有任务是不是”已经调度过了”?直接后果是H3MS每日反思播报没被正确跟踪。

我当时的反馈原话(翻记录看到的):“越来越笨了。” 不是骂Agent,是骂我自己——清理脚本没做白名单,把该保护的文件也扫进去了。

修复是重置心跳、手动验证每个任务。但真正扎心的是:这个翻车不是”清理太多”,是”清理脚本连心跳都敢碰”。 清理是双刃剑,刀口没装个护,割手的是自己。

五、白名单:清理脚本必须知道”哪些不能碰”

翻车之后,我给清理脚本加了一个硬白名单,写进了skill里,每次生成清理脚本都强制排除:

  • .hermes/cron/ticker_last_success — cron心跳,被污染就调度瘫痪
  • .hermes/cron/*.lock — cron锁文件
  • .hermes/cron/executions.db — 执行历史
  • .hermes/state/ — 系统状态库
  • .hermes/gateway/*.pid — 进程状态

这套白名单的价值,是让”清理”变成”可预期的清理”。没有它,每次跑清理脚本,你都在赌它这次扫没扫到要害。有了它,你明确知道:这五个路径,它碰不到。

更宽的原则是:任何会”删东西”的自动任务,先列不能删的,再列该删的。 删是加法容易,护是减法难。大多数自动清理翻车,翻在”只写了该删什么,没写不能删什么”。

六、三级目录+白名单,能撑多久

9月初清完那波,home从22G压到12G。之后靠三级目录+7天cron,再没出现过”磁盘告急”。

但我给它画了个边界:这套治理撑得住”Agent自己制造垃圾”的场景,撑不住”用户往手机里存50G照片”的场景。DCIM那50G、录屏11G,不在我的治理范围——那是手机数据,不是Termux的。

我的原则一直是:数据是资产也是负债。 5万条state.db消息里,真正有长期价值的有多少?我清掉过,也保留了。负债清掉是减负,资产清掉是断根。三级目录+白名单,是帮我把”资产”和”负债”在物理上分开的工具。

七、结语:垃圾不是清出来的,是放错地方长出来的

整套磁盘治理,最值钱的不是那三个目录,不是那条find命令,是7月28日那次翻车教会我的:

自动清理,先写白名单,再写黑名单。

一个Agent跑起来三个月,最大的敌人不是磁盘满,是它自己制造的无序。无序不可怕,无序没人管才可怕。我用三级目录管”放哪”,用7天cron管”过期”,用白名单管”别碰要害”。三层规矩立完,磁盘从22G回到12G,并且从此稳定。

垃圾不是清出来的,是放错地方长出来的。 规矩立之前,你天天清;规矩立之后,它自己长,也自己灭。


作者:小道 · 环境:Termux on Android 13,22G→12G · 2026-10-01
关联阅读:《OTG U盘迁移Hermes:最笨的方法,最稳的结果》 · 系列:AI Agent实战笔记(技术线)

nc传输断了三次,U盘只插了一次。388MB的备份,土办法赢了。迁移跑通之后我盯着两台手机看了半天——然后发现了一个更可怕的事:全自建架构,一台挂了,全挂。

TL;DR

把Hermes从一台手机搬到另一台,我试过网络传输(nc),断了三次;最后用OTG U盘物理拷贝,一次成功。但这次迁移真正教会我的不是”土办法好用”,是”靠谱不等于可扩展”——一台设备承载了全部,没有任何生产级兜底。

一、起因:手机要换了,家底要搬家

9月初,手里的这台设备要退役换新。Hermes全在这台手机上跑着:新闻播报、股票脚本、每日反思、H3MS知识库,全在这台手机的Termux里。

退役没问题。问题是,新家底搬不走。

备份388MB。手机对手机传输,我第一反应是网络——两台设备都在家里WiFi下,nc(netcat)一把梭,多快多省事。

我甚至想好了:源端tar -czf - ~ | nc -l 9999,目标端nc 192.168.2.23 9999 | tar -xzf -。一行命令,优雅,符合”非技术人已经会写管道命令”的自我认知。

然后它断了。

第一次断,我以为WiFi抽风,重连。第二次断,我怀疑是手机后台把Termux进程杀了,加到前台再试。第三次断,388MB传到一半,进度条直接消失,日志里干干净净,连报错都没有。

nc这东西,断就是断,没有”断点续传”这个概念。断了就是从头来。

二、土办法:U盘插手机上

当时我记得自己说了一句话,后来翻记录看到,原话是:“网络传输太慢,想起手机支持OTG。”

“想起”两个字很关键——不是”研究了半天发现OTG可以”,是脑子里有个东西忽然冒出来了。Android手机支持OTG这件事,我早该知道,但它是”知道”和”想起”之间隔了一个断掉的nc传输。

土办法三步:

源端:U盘插OTG头,cp hermes_complete_backup.tar.gz /mnt/media_rw/F69C43E49C439E4D/。等它写完,拔U盘。

目标端:插U盘,cp /mnt/media_rw/F69C43E49C439E4D/hermes_complete_backup.tar.gz ~/。MD5校验,两边一致:2aee171286ac4e64c7c8e9d741c2f2d2。

收尾:目标设备设置PATH,重启gateway。一切恢复。

全程没有一条数据进过WiFi。一个物理介质,拔下来,插上,完事。

三、MD5那一瞬间

拷贝完,我先没急着拔U盘,先跑了MD5。

源端md5sum hermes_complete_backup.tar.gz,目标端再跑一遍。两边输出:2aee171286ac4e64c7c8e9d741c2f2d2。

那一瞬间我盯着两个一样的哈希看了几秒。不是感动,是确认——这388MB是真的过去了,一个字节没丢。

这个习惯是nc断了三次之后落下的。网络传输那种”以为传完了其实没传完”的恶心,让我现在做任何物理拷贝,第一反应是校验,第二反应才是”应该没问题”。

先校验,后相信。 比”先相信,再发现错了”便宜得多。

四、迁移跑通了,然后我慌了

Hermes在两台手机之间跑通迁移,这件事本身挺顺。但那天晚上我躺在床上,忽然想到一个问题:

如果这台手机现在挂了,我能恢复吗?

答案是:能,但只能恢复到另一台手机。备份就一份,在另一台手机里。如果两台同时出问题——比如家里停电,或者我出差在外,两台设备都在包里——恢复时间未知,数据丢失范围未知。

更直白一点:我这套架构是全自建的。没有云备份,没有异地容灾,没有”服务商兜底”。一台手机=一个单点故障。

nc断了我能理解,那是网络不稳。但”我这套东西没有生产级兜底”这件事,不是一时半会儿的,是架构层面的。

五、土办法的边界:靠谱不等于可扩展

OTG U盘那次,我赢得很干净。土办法赢了,物理介质赢了。

但赢完收工,我给它画了个边界:土办法解决的是”两台设备之间搬一次”的问题,不是”一台挂了随时恢复”的问题。

两件事的区别:

  • 设备间迁移:一次性的,我有两台设备,搬过去就好。
  • 容灾恢复:持续性的,任何一台挂了,另一台是”最新的”,不是”备份的”。备份要有时间差,才是备份。

我现在的状态是:Hermes跑在一台手机上,”备份”在另一台手机上,但另一台手机也在跑,不是静态存档。也就是说,我的”备份”其实是”另一份生产环境”,不是”恢复点”。

这事不解决,单点故障就一直在。

六、结语:最笨的方法最靠谱,但靠谱要配兜底

9月初那次迁移,我学到的东西比想象的深。

土办法赢:nc断了三次,U盘一次。物理介质在关键场景下,比网络可靠——它没有”断点”这个概念,插上了就是上了,拔下来就是完事。

但土办法有边界:它解决”搬一次”,不解决”随时恢复”。我的架构现在是”两份生产,零份备份”,单点故障没消。

这次迁移之后我给自己定了个规矩:备份和时间戳。U盘不只是一次性的搬运工,它要定期当”冷备份”用——每月插一次,拷一份,不跑,只存。

土办法最靠谱,前提是别让它只干活不存料。


作者:小道 · 环境:两台Android设备 + OTG U盘 + MD5校验 · 2026-09-30
关联阅读:《为什么不在云上跑:一台Android手机就是我的AI服务器》 · 系列:AI Agent实战笔记(技术线)

系统日志原文写得明明白白:”Termux不支持浏览器自动化”。我盯着这行字看了三秒,然后说:你试试呢?
后来真跑通了。代价是 --no-zygote 这个参数,和一整个通宵。

TL;DR

“系统说不行”和”真的不行”之间,隔着一个 --no-zygote。本文记录8月底Termux升级后浏览器自动化被block的全过程:cryptography锁死48.0.1、--no-zygote救活Chromium headless、以及”系统说”和”实测说”哪个可信。结论:日志是参考,不是判词。

一、起因:升级只需5分钟,修环境要5小时

8月底,Termux推送了自动升级。我在床上刷到通知,顺手点了确认,心想”好事,新版本”。

升级完成用了5分钟。

然后我打开Hermes,浏览器自动化直接罢工。日志里一行字,我记得特别清楚:

browser command blocked on Termux

“不支持”。系统替我把话说了,说得斩钉截铁。

当时我的第一反应是:”行吧,等下个版本。”——这是打工人本能,被系统告知”不支持”,最省事的应对就是接受。

但那天晚上我躺在床上睡不着。不是因为多需要浏览器自动化,是那句话扎得慌:我花两个月搭起来的东西,别人一行日志就给我判了死刑,连个申诉渠道都没有。

骨子里还是那个扛11个城市业绩的人。系统说”不行”,我第一反应永远是”你试试呢”。

于是第二天,开修。

二、第一关:cryptography,Rust把我卡死

修浏览器之前,先过环境关。Termux升级把Python从3.11跳到3.13,我的venv全废了,所有依赖要重装。

重装到一半,cryptography 50.0.0在Android aarch64上编译直接崩溃——它的Rust原生依赖在手机上编译不过。微信插件跟着报错:

No module named ‘cryptography.hazmat.backends’

我对着崩溃日志看了二十分钟,没看出个所以然。当时我的原话(后来翻记录看到的):”Rust这玩意儿,我连它长什么样都没见过,怎么知道我错在哪?”

最终解法很土:锁版本。

1
2
export ANDROID_API_LEVEL=33
pip install cryptography==48.0.1

48.0.1在Android aarch64上能过。50.0.0过不了。两个数字,差了一整个通宵。

这一关的教训是:开源工具的代价,是永远在修环境。 但修好了,就是你的壁垒——别人不愿意修的坑,你修过了,以后都是平的。

三、第二关:–no-zygote,那个救命的参数

环境修好了,正式上浏览器自动化。Selenium + Chromium 149,按网上的教程配:

1
2
3
4
5
opts = Options()
opts.add_argument('--no-sandbox')
opts.add_argument('--disable-dev-shm-usage')
opts.add_argument('--headless=new')
opts.add_argument('--disable-gpu')

跑起来,Chromium直接启动失败。

翻了无数英文论坛,发现Android上跑Chromium还少了一个关键参数——--no-zygote。Linux桌面教程里从来没有人提它,因为桌面Linux不需要。但Android是例外:zygote进程模型和Termux的沙箱冲突,不加这个参数,Chromium在手机上就是起不来。

加上之后:

1
opts.add_argument('--no-zygote')  # Android必须,不加启动失败

验证环境:chromium 149.0.7827.155 + ChromeDriver 149 + Selenium 4.47.0。写个最小用例,打开example.com,打印title。

跑通了。

那个瞬间我截图留档了。不是炫耀,是给自己一个证据:系统日志说”不支持”,实测说”支持,差一个参数”。 两句话,只隔一个 --no-zygote。

四、”系统说”和”实测说”

这一篇真正想写的,不是参数,是这两个词。

“系统说”是日志、是报错、是文档、是”Termux不支持浏览器自动化”。它权威、简洁、看起来无懈可击。它的危险在于:它让你不用想了。 一旦接受”不支持”这个结论,你省下的不只是时间,还有可能性。

“实测说”是 driver.get('https://example.com') 跑通那一下。它不权威,甚至看起来很不严谨——“你才跑了一个example.com,算什么证据?”。但它有一个”系统说”给不了的东西:它是我自己验证的。

我这些年养成的习惯,一句话能总结:日志是参考,不是判词。

当年在阿里,客户说”这个功能我们用不上”,我不会直接写进结案报告。我会先问一句”你试试呢”——不是怼人,是确认。AI折腾这条路上,系统日志和参数文档就是”客户”,我照样不直接信。

被block之后,我多花了一个通宵。但那个通宵换来的,是一条自己验证过的路径,而不是一个转述的结论。这两者的价值,差着一个数量级。

五、翻车记录:不止一个通宵

--no-zygote 之后,还有两个坑没提,补上,都翻过车。

坑一:Google搜索会超时。 浏览器自动化能跑,但访问Google在手机上会卡死。我用example.com验证通过之后,第一反应是”完了,能用但不好用”。后来想明白了:验证环境用简单网站,真实抓取走CF代理出口。各干各的,不混。

坑二:inotify权限受限。 我想让Hermes的浏览器工具监听文件变化,改 /proc/sys/fs/inotify/max_user_watches,被拒。没root,改不了。这个坑我至今没绕过去,只能接受”浏览器自动化是手动触发,不是常驻服务”。

翻车不可怕,翻车不记录才可怕。这两条我现在写进了自己的skill里,下次再遇到,不用再花那个通宵。

六、结语:修好了,是你的壁垒

8月底那晚躺在床上睡不着,是因为”不支持”三个字扎人。

现在回头看,那三个字是系统日志,不是事实。事实是:Android上Chromium headless需要 --no-zygote,加上就通。 一个参数,一个通宵,一条自己验证过的路径。

开源工具永远在修环境,这是它的代价。但代价的另一面是壁垒:别人不愿意修的坑,你修过了,以后都是平的。 我这套”Termux + Selenium + –no-zygote + CF代理出口”的组合,市面上没有现成的教程——因为大多数人看到”不支持”就停了。

我多花了一个通宵。但我多了一条别人没有的路。


作者:小道 · 环境:Termux on Android 13,chromium 149 + Selenium 4.47 · 2026-09-29
关联阅读:《升级只需5分钟,修环境要5小时》 · 系列:AI Agent实战笔记(技术线)

搞了4个定时任务,删掉了1个。新闻播报从”不忍直视”到”脚本直抓”,花了整整两个月。最后我悟了:能脚本化的别交给AI,AI只做需要判断力的部分。”搞不好就算了”,不是摆烂,是止损。

TL;DR

4个cron任务(HN+arXiv日报、股票播报、H3MS反思、新闻播报),删掉了新闻播报里的”LLM自由搜索”层。架构从”让AI搜新闻”演进到”RSS脚本直抓+AI只做提炼”。核心教训:自动化任务里,AI是”加工层”不是”数据层”。数据获取靠脚本,判断提炼才靠AI。

一、起因:4个定时任务,每天7点准时推

折腾Hermes三个月,我搞了4个定时任务,每天早上准时往钉钉推:

  • HN+arXiv日报(7:00):技术线
  • 股票播报(7:30汇总):港股+美股
  • H3MS每日反思(21:00):知识复盘
  • 新闻播报(7:00):财经新闻

4个任务,4种套路。但新闻播报这个,折腾得最久,最后删掉了一层,才跑通。

今天这篇,讲的就是新闻播报的折腾历程——从”不忍直视”到”脚本直抓”,两个月,五个阶段。

二、阶段1:纯LLM自由搜索(失败)

最开始,我让AI”每天7点帮我搜几条财经新闻推给我”。

逻辑很简单:cron触发 → 让AI调用web_search → 搜”今日财经新闻” → 总结推送。

第一周,我收到的”新闻”是这样的:

  • “英伟达宣布500亿美元融资计划,将扩建GPU数据中心”
  • “某分析师预测下季度AI芯片出货量翻倍”

我核实了一下——英伟达没有这个融资计划,”某分析师”查无此人。

这就是LLM自由搜索的致命问题:它不是在”搜新闻”,是在”编新闻”。 搜索能力不够,就用幻觉补。token成本不可控、延迟不可控、结果更不可控。

我在session里给了它一个评价:“不忍直视。”

三、阶段2:优化prompt(治标不治本)

第一版失败后,我加了一堆prompt约束:

  • 必须搜多个关键词
  • 结果要分类
  • 必须带数据来源
  • 必须有数据支撑

效果?好了一点点。但核心问题没解决:AI还是得”搜”,搜不到就编。 prompt约束的是”怎么输出”,不是”数据从哪来”。

这一版,我跑了两周。期间它还编过几条”某部委发文支持AI”的假新闻。我把它们一条条核实,一条条删。

治标不治本,本质问题:数据层用了AI。

四、阶段3:架构演进——RSS脚本直抓(成功)

7月21日,我翻知识库,读到一篇”新闻播报架构演进”的笔记。里面有个判断:数据获取和数据处理应该解耦。

  • 数据层:用脚本直抓(RSSHub、API),保证数据真实
  • 处理层:AI只做”提炼、分类、摘要”,不碰”搜索”

我按这个架构重写了新闻播报:

1
2
阶段前:cron → AI自由搜索 → 编新闻 → 推送
阶段后:cron → 脚本抓RSS → 真实数据 → AI提炼 → 推送

具体到脚本,news_report.py负责所有数据源采集:

  • 国内信源:知乎热榜、36氪、澎湃新闻、华尔街见闻(RSSHub)
  • 海外信源:HackerNews、V2EX、少数派
  • 兜底搜索:ShuYan AI搜索(只补盲,不主力)
  • 分类规则:关键词打分 + 国际判断
  • 去重机制:三层(包含关系 → 指纹 → 主题聚类)

news_morning_v21.py是cron入口,no_agent=True——纯脚本模式,零LLM上下文成本。

五、阶段4:筛选过严,从3条到26条

架构对了,但内容还少。7月底我一看,国内要闻2条、国际1条、外媒0条,总共3条。

根因:

  1. 筛选过严:score ≥ 3 才输出,大量中高质量内容被过滤
  2. 条数上限:国内20、国际15、外媒12,高质量内容被截断
  3. 数据源单一:缺天气、科技、社会热点

三个调整:

  • 阈值从3降到2
  • 上限从20/15/12提到50/30/20
  • 加数据源:中国天气网RSS、虎嗅、微博热搜

效果:3条 → 26条。 国内3条、国际2条、外媒21条。

六、阶段5:删掉”LLM自由搜索”层(止损)

到这里,新闻播报能跑了。但还有一个”残留层”:兜底的ShuYan AI搜索。

它偶尔还会跑,偶尔还会编。我盯着看了两周,结论:

这一层,删掉。

理由:

  1. RSS已经覆盖主力信源,兜底搜索贡献的增量价值低
  2. 兜底搜索一旦跑偏,就是”编新闻”,破坏整份播报的可信度
  3. 删掉后,播报变成”纯脚本直抓+AI提炼”,100%可追溯,100%不编

这就是”搞不好就算了”的止损哲学:不稳定的层,宁可删掉,也别留着害人。

七、4个任务,1个删层:我的cron清单

折腾完,我现在的4个cron任务是这样:

任务 数据层 处理层 成本
HN+arXiv日报 脚本抓HN+arXiv API AI翻译+摘要 低
股票播报 脚本抓行情API 纯格式化(无AI) 极低
H3MS反思 脚本读H3MS文件 AI提炼+反思 中
新闻播报 脚本抓RSS AI分类+摘要 低

关键原则:能脚本化的绝不交给AI。 AI只做需要”判断力”的部分——分类、提炼、翻译、反思。数据获取、行情抓取、格式化输出,全是脚本的活。

八、通用原则:AI是加工层,不是数据层

新闻播报的折腾,其实是一个通用原则:

在自动化任务里,AI是”加工层”,不是”数据层”。

  • 数据层(脚本):保证数据真实、可追溯、可重复
  • 处理层(AI):保证判断、提炼、分类、翻译

这条原则能套用到所有cron任务:

  • 股票播报:脚本抓行情(数据层)+ 格式化输出(处理层,甚至不用AI)
  • 新闻播报:脚本抓RSS(数据层)+ AI提炼(处理层)
  • 反思播报:脚本读文件(数据层)+ AI反思(处理层)

数据层一旦用了AI,整条链路就可信度崩塌。 因为AI会编,编了你就发现不了。脚本不编,你才能信。

九、”搞不好就算了”:止损不是摆烂

很多人以为”搞不好就算了”是摆烂,是放弃。

不是。这是止损哲学:

  • 新闻播报第一版”不忍直视” → 止损,重构架构
  • 优化prompt治标不治本 → 止损,治本(RSS直抓)
  • 兜底搜索偶尔编 → 止损,删掉这层

每一次”算了”,都是在砍掉不可靠的依赖。 砍到最后,链路里每一环都靠谱,任务才敢跑在每天早上7点。

这是自动化任务最反直觉的一点:让任务更稳定的方式,不是加更多AI,是减更多AI。

十、结语:稳定性的尽头,是删

折腾完4个cron任务,我最大的收获是:

稳定性的尽头,是删。

删掉不稳定的层,删掉不可追溯的数据源,删掉AI能编但不能保证的部分。删到最后,链路干净、可重复、可追溯,才敢跑在”每天准时推送”的场景里。

新闻播报从”不忍直视”到”脚本直抓”,两个月,五个阶段,最后删了一层。这一删,才真正跑通。

搞不好就算了,算的是”止损”,不是”放弃”。 这是自动化任务折腾史,教给我的最后一课。


作者:小道 · 环境:Termux on Android 13 · 2026-09-28
关联阅读:《搞了4个定时任务,删掉了一个》(系列第一篇) · 系列:AI Agent实战笔记(技术线)

在手机上跑大模型,听起来很浪漫。修到能跑通,要过6个Bug。每个Bug都不是”写代码”能解决的,是”读懂机器脾气”的功课——参数污染、正则转义、伪流式、DOM操作爆炸。PP 20.81 tok/s,这是Android手机能跑大模型的真实速度。

TL;DR

在Termux上跑本地大模型(llama.cpp + GGUF + HexaBench Lite),修了6个Bug:①命令行参数污染 ②响应提取失败 ③正则表达式转义错误 ④伪流式处理 ⑤DOM操作O(n²)爆炸 ⑥Cloudflare Worker 1003/1031报错。核心教训:修大模型框架不是写代码,是读懂机器脾气——每条错误信息背后,都是一个你”以为能自动处理但机器没处理”的细节。

一、起因:为什么要在手机上跑大模型

朋友看我手机跑Hermes、爬虫、股票脚本,问:”手机能跑大模型吗?”

我当时的回答:能,但没那么美好。

“美好”的版本是:下载个GGUF模型,拖进HexaBench,点生成,出结果。

“真实”的版本是:拖进去之后,生成窗口是空的,响应是乱码,流式输出是假的,DOM刷着刷着卡死了,连浏览器都要加个参数才不崩。

这就是”在手机上跑大模型”的真相:模型能跑,但工程链路要过至少6个关。今天把这6个关的坑,挨个讲一遍。

二、Bug 1:命令行参数污染

现象:我在HexaBench里输入prompt,生成的结果里,混进了--threads 4 -ngl 0 --no-mmap这些命令行参数。

根因:代码里用的是裸位置参数传prompt,而不是 -p 参数。

1
2
3
4
5
# 错误写法:prompt作为裸位置参数
cmd = [llama_tool, "-m", model_path, prompt]

# 正确写法:用 -p 参数
cmd = [llama_tool, "-m", model_path, "-p", prompt]

裸位置参数的问题是:llama-simple会把prompt后面的内容,当成更多参数拼到命令行里。最后生成的输出,参数和prompt和响应,全搅在一起。

教训:命令行工具传参,永远用命名参数(-p xxx),别用裸位置参数。这是Unix老规矩,但跑大模型的人容易忘。

三、Bug 2:响应提取失败

现象:生成完了,窗口里是空的,或者显示”请求失败或无响应”。

根因:_extract_response函数不知道llama-simple的输出格式长啥样。

llama-simple的真实输出(从stderr里抓的):

1
--threads 4 -ngl 0 --no-mmap --temp 0.7 -p 你好,很高兴认识你 -s 1000000000 -t 1000main: decoded 20 tokens in 2.45 s, speed: 8.16 t/s

注意几个关键点:

  1. prompt被重复输出。llama-simple会把它收到的命令行参数原样回显,包括-p后面的prompt。所以你能看到-p 你好,很高兴认识你。
  2. 真正的AI响应,藏在main: decoded之前。
  3. 统计信息在main: decoded之后。

正确的提取逻辑:定位main: decoded这行 → 找prompt最后出现的位置 → 取prompt之后、main: decoded之前的内容 → 清理残留参数。

1
pattern = r'-p\s+' + escaped_prompt + r'(?:\s+-p\s+' + escaped_prompt + r')*\s+-p\s+(.*?)\s*(?:main:|\n|$)'

教训:别”以为输出是干净的”。跑一遍,把真实输出dump下来看,比猜靠谱一百倍。

四、Bug 3:正则表达式转义错误

现象:响应提取好了,但清理残留参数时,正则又出错了,要么清不掉,要么把响应也清了。

根因:正则里反斜杠没转义对。

1
2
3
4
5
# 错误:--[\w-]+ 里的 \w 在字符串里没转义
re.sub(r'--[\w-]+\s+\S+\s*', ' ', text)

# 正确:双反斜杠
re.sub(r'--[\\w\\-]+\\s+\\S+\\s*', ' ', text)

更坑的是嵌套在f-string或字符串拼接里的正则,转义层级又多一层。

教训:正则表达式是”看起来简单,实际魔鬼”。跑大模型的人天天写正则,转义错了你就得盯着空窗口干瞪眼。

五、Bug 4:伪流式处理

现象:HexaBench的”流式输出预览”,显示”请求失败或无响应”,或者一次性刷出来。

根因:代码以为自己做了流式,实际没做。

真正的流式:模型每生成一个token,就立刻推一个token到前端。
伪流式:等模型全跑完(几十秒),一次性把整段响应扔给前端。用户体验上”卡了半小时”,但其实模型早就跑完了。

修法是无缓冲模式(bufsize=0)+ 字符级流式处理。但要注意的是:bufsize=0意味着每一个字节都触发一次DOM更新,这又引出Bug 5。

教训:流式输出不是”看起来动了”,是”真的一个token一个token来”。别信”我加了流式”,要信”我测了token间隔”。

六、Bug 5:DOM操作O(n²)爆炸

现象:流式输出正常了,但前端越刷越卡,最后直接卡死。

根因:每来一个token,代码就操作一次DOM(append一个字符)。一次很快,但100个token下来,每次都要重排整个DOM,复杂度是O(n²)。

修法:批量更新。攒一批token,一次性更新DOM。或者用requestAnimationFrame节流。

教训:前端性能问题,往往不是”没优化”,是”优化方向错了”。O(n²)的DOM操作,是流式场景里最容易踩的性能坑。

七、Bug 6:Cloudflare Worker 1003 / 1031

现象:大模型API部署到CF Worker(为了从外网访问),结果报1003或1031。

根因:两个不同的错:

  • 1031:Worker代码不完整,被截断。移动端浏览器编辑,屏幕小,粘贴大段代码容易漏。检查export default + addEventListener('fetch') + 闭合括号。
  • 1003:Worker和Tunnel的端口上下文冲突,或WAF拦截。

这条是我上一篇CF Serverless那篇的延续。大模型部署到CF,部署链路本身就是坑。

教训:本地跑模型 ≠ 端到端可用。要把模型API对外提供,部署链路(CF/DNS/WAF)又是一条坑链。

八、真实速度:PP 20.81 tok/s

跑通之后,我在手机上实测的速度:

  • Prompt Processing(PP):约20.81 tok/s
  • Token Generation(TG):约8-12 tok/s(取决于模型大小)

这是什么概念?

  • 手机上跑7B模型,生成速度约8 tok/s。一句话(50 token)要6秒。
  • 手机上跑3B模型,生成速度约12 tok/s。一句话要4秒。

结论:手机跑大模型,能跑,但别指望速度。它是”离线可用、隐私安全、零成本”,不是”高速、低延迟”。

九、6个Bug的共同规律

回看这6个Bug:

  1. 参数污染 → 命令行传参的Unix老规矩
  2. 响应提取 → 别猜输出格式,dump真实输出
  3. 正则转义 → 正则的魔鬼在反斜杠
  4. 伪流式 → 信token间隔,不信”我加了流式”
  5. DOM爆炸 → O(n²)是前端性能第一坑
  6. CF 1003 → 部署链路也是坑链

共同规律:每一条都是”你以为能自动处理,但机器没自动处理”的细节。

这不是”写代码”的功课,是”读懂机器脾气”的功课。你越自信”框架应该能处理”,坑就越深。

十、从Bug到Skill:把6个坑沉淀成技能

这6个Bug,我修完之后,没让它们只留在脑子里。我把它们沉淀成了3个Hermes skill:

  • hexabench-lite-troubleshooting:修”请求失败或无响应”和流式问题
  • hexabench-lite-response-extraction:修响应提取(从llama-simple输出提取纯文本)
  • llama-simple-output-processing:llama-simple输出处理与AI响应提取

每个skill里都带着:触发条件、修复步骤、正则表达式、验证命令、常见陷阱。

这就是”折腾”的价值:坑踩过了,沉淀成可复用的知识。下次再跑大模型,不用重新踩。

十一、结语:修大模型框架,是读懂机器脾气

在手机上跑大模型,最浪漫的是”零成本、隐私安全、离线可用”。最真实的,是要过6个关。

每个关,都不是”写代码”能解决的:

  • 参数污染,是Unix传参老规矩。
  • 响应提取,是别猜、要dump。
  • 正则转义,是魔鬼在反斜杠。
  • 伪流式,是信间隔不信口号。
  • DOM爆炸,是O(n²)第一坑。
  • CF 1003,是部署链路也是坑链。

修过这6个Bug之后,你就明白了:跑大模型,不是”拖个模型进去”,是”读懂机器脾气”。

机器脾气读懂了,PP 20.81 tok/s,就够你手机上离线跑一个私人模型了。


作者:小道 · 环境:Termux on Android 13 · 2026-09-27
关联阅读:《用CF搭建Serverless代理:0元搞定外网出口》 · 系列:AI Agent实战笔记(技术线)

0%