<?xml version="1.0" encoding="UTF-8"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>掘金本周最热</title><link>https://juejin.im/recommended?sort=weekly_hottest</link><atom:link href="http://rsshub.umzzz.com/juejin/trending/all/weekly" rel="self" type="application/rss+xml"></atom:link><description>掘金本周最热 - Powered by RSSHub</description><generator>RSSHub</generator><webMaster>contact@rsshub.app (RSSHub)</webMaster><language>en</language><lastBuildDate>Sun, 19 Jul 2026 12:27:14 GMT</lastBuildDate><ttl>5</ttl><item><title>前端圈7月大地震：TS 7发布、Bun 11天从Zig迁Rust、Kimi K3登顶、大厂裁员50%</title><description>&lt;h2 data-id=&quot;heading-0&quot;&gt;前端圈7月大地震：TS 7发布、Bun 11天从Zig迁Rust、Kimi K3登顶、大厂裁员50%&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;2026年7月，前端圈几乎一天一个大新闻。TypeScript 7.0正式发布，编译器用Go重写、速度暴涨10倍；Bun用11天把78万行代码从Zig迁到Rust，测试100%通过；Kimi K3在Frontend Code Arena登顶，力压Claude Fable 5；与此同时，阿里飞猪传出测试和前端岗位裁撤比例达50%，大厂裁员潮仍在蔓延。这个7月，前端圈正在经历冰火两重天。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;一、7月8日：TypeScript 7.0正式发布，14年来最大变革&lt;/h3&gt;
&lt;p&gt;2026年7月8日，微软正式发布了TypeScript 7.0。&lt;/p&gt;
&lt;p&gt;这是TypeScript自2012年诞生以来&lt;strong&gt;最重大的一次底层重构&lt;/strong&gt;。整个编译器从TypeScript/JavaScript被逐行移植到了Go语言，带来了&lt;strong&gt;原生代码速度、共享内存多线程以及一系列新优化&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-2&quot;&gt;1.1 性能数据：最高12倍&lt;/h4&gt;
&lt;p&gt;微软官方公布的基准测试数据非常震撼：&lt;/p&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项目&lt;/th&gt;&lt;th&gt;TypeScript 6.0&lt;/th&gt;&lt;th&gt;TypeScript 7.0&lt;/th&gt;&lt;th&gt;提升倍数&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;VS Code（约230万行）&lt;/td&gt;&lt;td&gt;125.7秒&lt;/td&gt;&lt;td&gt;&lt;strong&gt;10.6秒&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;11.9倍&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sentry&lt;/td&gt;&lt;td&gt;139.8秒&lt;/td&gt;&lt;td&gt;&lt;strong&gt;15.7秒&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;8.9倍&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bluesky&lt;/td&gt;&lt;td&gt;24.3秒&lt;/td&gt;&lt;td&gt;&lt;strong&gt;2.8秒&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;8.7倍&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Playwright&lt;/td&gt;&lt;td&gt;12.8秒&lt;/td&gt;&lt;td&gt;&lt;strong&gt;1.47秒&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;8.7倍&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;tldraw&lt;/td&gt;&lt;td&gt;11.2秒&lt;/td&gt;&lt;td&gt;&lt;strong&gt;1.46秒&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;7.7倍&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;在VS Code项目中，完整构建从将近&lt;strong&gt;两分钟&lt;/strong&gt;压缩到了&lt;strong&gt;十秒钟&lt;/strong&gt;。编辑器端的响应速度同样惊人——当开发者打开一个包含错误的文件时，7.0版本定位首个错误的时间从此前约17.5秒缩短至约1.3秒，响应速度提升约&lt;strong&gt;13倍&lt;/strong&gt;。内存占用也明显改善，在VS Code项目中降幅约18%，在Bluesky项目中降幅约26%。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-3&quot;&gt;1.2 为什么能快10倍？&lt;/h4&gt;
&lt;p&gt;过去十四年，TypeScript编译器一直采用 &lt;strong&gt;“自托管”方式&lt;/strong&gt;——用TypeScript本身写编译器，再编译成JavaScript在Node.js上运行。这套方案有三个硬性天花板：单线程瓶颈、JIT预热、GC不匹配。&lt;/p&gt;
&lt;p&gt;Go一次性移除了这三个天花板：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编译成原生机器码，没有JIT预热和JavaScript解释开销&lt;/li&gt;
&lt;li&gt;goroutine实现了跨CPU核心的&lt;strong&gt;真正共享内存并行&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Go的并发垃圾回收器不会长时间暂停执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-id=&quot;heading-4&quot;&gt;1.3 升级方式：一行命令&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npm install -D typescript@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TypeScript 7.0在VS Code、Visual Studio和WebStorm等主流编辑器中&lt;strong&gt;开箱即用&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;不过需要注意：&lt;strong&gt;对Vue、Svelte、Astro或MDX的开发者来说，由于缺少程序化API，这些框架的完整编辑器支持需要等待TypeScript 7.1&lt;/strong&gt;。微软发布了兼容性包&lt;code&gt;@typescript/typescript6&lt;/code&gt;，支持6.0与7.0并行共存。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;二、Bun 11天从Zig迁到Rust：78万行代码，100%通过&lt;/h3&gt;
&lt;p&gt;7月8日，就在TypeScript 7.0发布的同一天，JavaScript运行时Bun的创始人Jarred Sumner在官方博客发布了一条令整个技术社区震惊的声明。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;经过仅仅11天的高强度工作，Bun的全部1448个Zig文件已被机械式转换为Rust代码，测试套件实现100%通过率，新版本v1.4.0已通过canary渠道发布&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;78万行代码，11天，100%通过。这个速度是怎么做到的？答案是&lt;strong&gt;AI主导重构&lt;/strong&gt;。整个转换过程由AI辅助完成，实现了大规模代码库的机械式迁移。&lt;/p&gt;
&lt;p&gt;这意味着什么？&lt;strong&gt;前端工具链的“换芯”革命正在加速&lt;/strong&gt;。Bun从Zig迁移到Rust，加入了一个越来越长的名单：Vite从Go的esbuild+rollup换成了Rust的Rolldown，Astro从Go编译器换成了Rust编译器，现在连Bun也加入了Rust阵营。前端工具链正在从“JavaScript写工具”全面转向“Rust写工具”。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;三、7月16日：Kimi K3发布，Frontend Code Arena登顶&lt;/h3&gt;
&lt;p&gt;2026年7月16日，月之暗面（Moonshot AI）上线推出了Kimi K3模型。&lt;/p&gt;
&lt;p&gt;这是Kimi迄今能力最强的模型，拥有&lt;strong&gt;2.8万亿参数，100万Tokens上下文&lt;/strong&gt;，主要面向长程编程与端到端知识工作。价格方面，每100万Tokens输入费用为2元（缓存命中）/20元（缓存未命中），输出费用为100元。&lt;/p&gt;
&lt;p&gt;架构上，Kimi K3基于&lt;strong&gt;Kimi混合线性注意力机制（Kimi Delta Attention）和注意力残差（Attention Residuals）技术&lt;/strong&gt;构建，原生支持视觉理解。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最让前端圈震动的是性能数据&lt;/strong&gt;：在Frontend Code Arena中，Kimi K3以&lt;strong&gt;1679分超越Claude Fable 5，位居第一&lt;/strong&gt;。@arena官方账号表示：“在前端领域，Kimi-K3在7个领域中的6个位居#1：品牌与营销、基于参考的设计、数据与分析、消费产品、模拟以及内容创建工具，仅在游戏领域位列#2，落后于Fable 5。”&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前端代码生成能力，正在被中国模型刷新纪录。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;四、Gemini 3.5 Pro泄露：前端“一次成型”&lt;/h3&gt;
&lt;p&gt;同样是7月，Gemini 3.5 Pro的泄露版本让整个前端圈沸腾。&lt;/p&gt;
&lt;p&gt;综合多位开发者的反馈，泄露版本在“前端与视觉代码生成”上出现了一次明显的能力跳变：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;设计品味更好&lt;/strong&gt;：生成的界面不再是“程序员审美”，配色、留白、层次更接近专业设计师&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI更干净&lt;/strong&gt;：一次成型的前端页面结构清晰，冗余更少&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SVG生成显著增强&lt;/strong&gt;：复杂矢量图形能一次画对&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完成度更高&lt;/strong&gt;：一句话生成一个像模像样的页面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在开发者圈子里甚至流行起了一个词来形容它的表现—— &lt;strong&gt;“mogging”（彻底压制）&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;不过，前端封神不等于全面封神。在最硬核的Agent任务、仓库级软件工程和长程任务上，Gemini 3.5 Pro依然打不过Fable 5或GPT-5.6。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-8&quot;&gt;五、大厂裁员：飞猪传前端裁撤50%&lt;/h3&gt;
&lt;p&gt;技术突破的另一面，是残酷的行业现实。&lt;/p&gt;
&lt;p&gt;截止到2026年7月，社交平台传出阿里旗下飞猪进行大规模人员调整，其中甚至出现**测试和前端岗位裁撤比例达到50%**的说法。尽管具体数字尚未获得官方确认，但类似传闻并不是孤例：小米、B站、网易、科大讯飞、美团等公司也先后陷入技术岗、产研岗和基础外包岗位大幅收缩的舆论风波。&lt;/p&gt;
&lt;p&gt;美团官方回应称近两个月实际离职不足2000人，占全员比例不到2%，属于正常的业务优化。但行业整体收缩的态势已经非常明显。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;曾经一个需要五个前端干上一个月的后台管理系统，现在只需一个产品经理对着Codex疯狂输出提示词，三天就能拼凑出一个能跑、能看、甚至带动画的完整项目&lt;/strong&gt;。代码的产出效率被提高了十几倍，于是各大厂的高层一拍脑袋：既然AI写得这么快，那我们为什么还需要养这么多初中级前端？&lt;/p&gt;
&lt;h3 data-id=&quot;heading-9&quot;&gt;六、同一时期：还有四件大事&lt;/h3&gt;
&lt;h4 data-id=&quot;heading-10&quot;&gt;6.1 Deno 2.9发布：前端框架直接打包成桌面应用&lt;/h4&gt;
&lt;p&gt;Deno 2.9的亮点功能是&lt;code&gt;deno desktop&lt;/code&gt;，它支持把Next/Nuxt等前端框架项目转化为一个独立的原生桌面应用，最终产物是一个跨平台分发的二进制文件，&lt;strong&gt;无需借助Electron/Tauri等桌面应用框架&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-11&quot;&gt;6.2 Vercel skills狂揽2.4万星&lt;/h4&gt;
&lt;p&gt;Vercel推出的Skills项目上线五个月便在GitHub获得&lt;strong&gt;2.4万星标&lt;/strong&gt;。通过一行命令&lt;code&gt;npx skills add &amp;lt;package&amp;gt;&lt;/code&gt;，开发者可以为Claude Code、Cursor等多种AI工具快速安装能力包。榜首&lt;code&gt;find-skills&lt;/code&gt;安装量已超&lt;strong&gt;230万次&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-12&quot;&gt;6.3 HeroUI v3正式发布&lt;/h4&gt;
&lt;p&gt;HeroUI（前身为NextUI）发布了v3版本，针对React和React Native从头进行了重写，并基于Tailwind CSS v4构建。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-13&quot;&gt;6.4 Yuku开源：Zig重构前端工具链&lt;/h4&gt;
&lt;p&gt;2026年7月14日，基于Zig语言从零构建的JavaScript/TypeScript工具链&lt;strong&gt;Yuku&lt;/strong&gt;正式开源。前端工具链的“换芯”大战，又多了一个新玩家。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-14&quot;&gt;七、把七月这些事放在一起看&lt;/h3&gt;
&lt;p&gt;2026年7月，前端圈几乎一天一个大新闻：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;7月8日&lt;/strong&gt;：TypeScript 7.0正式发布，10倍提速；同日Bun宣布11天从Zig迁到Rust&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7月14日&lt;/strong&gt;：Yuku开源，Zig重构前端工具链&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7月16日&lt;/strong&gt;：Kimi K3发布，Frontend Code Arena登顶&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7月&lt;/strong&gt;：Gemini 3.5 Pro泄露，前端“一次成型”；Vercel skills狂揽2.4万星；Deno 2.9支持桌面应用；大厂裁员潮持续&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;放在一起看，四个趋势已经非常清晰：&lt;/strong&gt;&lt;/p&gt;
&lt;h4 data-id=&quot;heading-15&quot;&gt;趋势一：前端工具链正在“全面换芯”&lt;/h4&gt;
&lt;p&gt;TypeScript 7.0用Go重写编译器、Bun从Zig迁到Rust、Astro用Rust重写编译器、Vite 8用Rust的Rolldown取代Go的esbuild+rollup——&lt;strong&gt;前端工具链正在从“JavaScript写工具”全面转向“系统级语言写工具”&lt;/strong&gt;。甚至连Zig都开始入场了（Yuku）。从打包工具到编译器，从linter到formatter，所有“吃性能”的环节都在被重写。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-16&quot;&gt;趋势二：AI正在重新定义“前端开发”&lt;/h4&gt;
&lt;p&gt;Gemini 3.5 Pro的前端生成能力跃升、Kimi K3在Frontend Code Arena登顶、AI编程工具全面爆发——&lt;strong&gt;当AI能完成过去需要数小时甚至数天才能完成的工作时，前端开发者的角色正在从“写代码的人”变成“指挥AI的人”&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-17&quot;&gt;趋势三：裁员与技术突破并存&lt;/h4&gt;
&lt;p&gt;TS 7发布、Bun迁移、Kimi登顶——技术层面的好消息不断。但与此同时，飞猪传前端裁撤50%、美团等大厂技术岗收缩。&lt;strong&gt;行业正在经历“冰火两重天”&lt;/strong&gt;：技术越强，对初级岗位的需求越少。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-18&quot;&gt;趋势四：AI编程能力正在“中国化”&lt;/h4&gt;
&lt;p&gt;Kimi K3在Frontend Code Arena登顶，力压Claude Fable 5。中国大模型在前端代码生成这个细分领域，正在改写全球排名。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-19&quot;&gt;写在最后&lt;/h3&gt;
&lt;p&gt;2026年7月，前端圈几乎一天一个大新闻。&lt;/p&gt;
&lt;p&gt;TypeScript 7.0把编译速度提升了10倍。Bun用11天把78万行代码从Zig迁到Rust。Kimi K3在Frontend Code Arena登顶。Gemini 3.5 Pro让前端代码“一次成型”。Vercel skills狂揽2.4万星。Deno 2.9让前端框架直接变成桌面应用。与此同时，大厂裁员潮仍在蔓延。&lt;/p&gt;
&lt;p&gt;这个7月，是前端圈&lt;strong&gt;冰火两重天&lt;/strong&gt;的7月。&lt;/p&gt;
&lt;p&gt;一边是技术突破的速度在加快——工具链在换芯、AI在进化、新框架在涌现。另一边是行业在收缩——初级岗位在消失、大厂在裁员、焦虑在蔓延。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这两个趋势并不矛盾。它们是同一枚硬币的两面：技术越强，对人的要求越高。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;三年前，前端是“写页面的人”。2026年7月，前端是“指挥AI写页面、用Rust工具链构建、用Deno打包成桌面应用、在Kimi K3和Gemini 3.5 Pro的夹缝中找自己位置的人”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这个月发生的事，比去年整个下半年加起来还多。而你，跟上了吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;评论区聊聊：2026年7月，哪个消息最让你震撼？你升级TypeScript 7.0了吗？&lt;/p&gt;</description><link>https://juejin.cn/post/7663095491467411462</link><guid isPermaLink="false">https://juejin.cn/post/7663095491467411462</guid><pubDate>Fri, 17 Jul 2026 01:11:52 GMT</pubDate><author>涛涛ing</author><category></category><category>前端</category></item><item><title>停更的这一年，All In AI、陪媳妇生娃、还考了个研</title><description>&lt;h2 data-id=&quot;heading-0&quot;&gt;停更的这一年，All In AI、陪媳妇生娃、还考了个研&lt;/h2&gt;
&lt;p&gt;打开掘金 App，看了一眼自己的最近更新——停在了整整一年前。&lt;/p&gt;
&lt;p&gt;不是不想写，是这一年确实被塞得太满了。如果非要用几个关键词来概括，那就是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;All In AI；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;媳妇怀孕 → 生娃；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在职考研。
&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今天终于坐下来，想好好聊聊这一年发生的事，也算给自己一个阶段性的交代。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;一、All In AI：在浪潮里拼命折腾，却发现自己始终在岸边&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;我所在的公司主营 SaaS 业务，去年开始转型，几乎整个团队都押注 AI。&lt;/p&gt;
&lt;p&gt;于是我从第一天起，就被裹挟进一场没有终点的学习马拉松：&lt;/p&gt;
&lt;p&gt;GitHub Copilot、智谱、Kimi、DeepSeek、ChatGPT、Claude Code……工具换了一茬又一茬，模型迭代快得让人喘不过气。&lt;/p&gt;
&lt;p&gt;很多时候，刚摸清一个工具的边界，下一代版本就已经把你之前的经验直接覆盖掉。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;坦白说，这一年在技术深度上，我的成长并不大。&lt;/p&gt;
&lt;p&gt;大部分时间都花在了 AI 应用层——理解客户的真实需求，用工程化能力把 AI 落地到具体的业务场景里。&lt;/p&gt;
&lt;p&gt;至于框架层、核心逻辑的参与很少，看着别人写底层架构，心里确实羡慕。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;不过，软技能的提升是实实在在的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跟客户沟通需求，不再只讲技术术语，而是真正听懂他们在业务上的痛点；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对几个垂直行业的业务流程，也有了更体系化的理解；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;学会了在快速变化中保持自己的节奏，而不是被焦虑牵着鼻子走。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;虽然没有深入工程化能力，但我也没让自己闲着。如果你也在做 AI 工程化落地，我推荐一些资料，或许能给你一些启发：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Ftime.geekbang.org%2Fcolumn%2Fintro%2F101113501%3Ftab%3Dcatalog&quot; target=&quot;_blank&quot; title=&quot;https://time.geekbang.org/column/intro/101113501?tab=catalog&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;time.geekbang.org/column/intr…&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Ftime.geekbang.org%2Fcolumn%2Fintro%2F101162601&quot; target=&quot;_blank&quot; title=&quot;https://time.geekbang.org/column/intro/101162601&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;time.geekbang.org/column/intr…&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;后面如果有空，我会单独写一些 All In AI 过程中踩过的坑，以及那些真正让我成长的点。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;二、媳妇怀孕 → 生娃：从两个人到一个家，取舍比想象中更具体&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;从媳妇怀孕那天起，家里就不再是我和她两个人的事了。&lt;/p&gt;
&lt;p&gt;吃什么、怎么吃、她爱吃什么、产检陪不陪、孩子出生后谁带、怎么带——每一件都是具体到每天的问题。&lt;/p&gt;
&lt;p&gt;说实话，不是没吵过架，也不是没手忙脚乱过，但好在最后家庭还算和睦，娃也健康落地。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;决定要孩子，本质上就是一次生活资源的重新分配：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;放弃了随心所欲的二人世界；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;生活质量肉眼可见地下降（时间、金钱、精力都吃紧）；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;个人爱好基本搁置；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;社交圈自动收缩，能推的局全推了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;但换来的，是一个会冲你笑、会半夜哭醒、会一天天长大的小家伙。&lt;/p&gt;
&lt;p&gt;晒一张我家潮娃的照片。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/508ba0e68e4f4c06a130f4abe1f15cf8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR5pivQWxsZW4=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784792868&amp;amp;x-signature=%2Bky5GiPTP3HirPh5vx3FEz1em%2BQ%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;另外，说来也巧合，我们带着娃做了童模，顺手尝试做了母婴赛道，抖音和小红书都开了号，算是给这段经历留点额外产出。虽然收入甚微，但也留下了美好的回忆。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8976258fd0954fb5b605857e00ea3877~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR5pivQWxsZW4=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784792868&amp;amp;x-signature=PrW2fg2n2OdVPsZGIgHfjY3ikLI%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3655b3c08289403fa9c7df0b40392c1e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR5pivQWxsZW4=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784792868&amp;amp;x-signature=8JbdmGzGaspBNH76wc7yyGtYq8c%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;三、考研：34 岁，硬着头皮跟自己较劲&lt;/p&gt;
&lt;p&gt;最后聊聊考研。&lt;/p&gt;
&lt;p&gt;我考的是在职研究生，不是全日制。&lt;/p&gt;
&lt;p&gt;原因很简单：学历太低，见识太少，经济下行，年纪越来越大。&lt;/p&gt;
&lt;p&gt;我害怕 35 岁真的成为我个人职业生涯的危机，光靠技术文章弥补不了学历短板——有 HR 跟我说过，“你的学历是硬伤”，我就知道这句话意味着什么。&lt;/p&gt;
&lt;p&gt;那就考吧，34 岁又怎样？&lt;/p&gt;
&lt;p&gt;拼一拼，单车也许真能变摩托。
&amp;nbsp;&lt;/p&gt;
&lt;p&gt;收到录取通知书那天，心情很复杂。&lt;/p&gt;
&lt;p&gt;喜悦当然是有的，但也同样沉重：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;接下来要花更多时间在学业上；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;陪伴孩子的时间会被进一步压缩；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;学费又是一笔不小的开销。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;回过头看这一年，我自己都不知道是怎么坚持下来的。&lt;/p&gt;
&lt;p&gt;离开校园已经十年，底子本来就差，重新捡起书本需要很大的勇气。&lt;/p&gt;
&lt;p&gt;所以我的节奏很简单：每天下班回家，吃完饭，带娃一小时，然后坐到书桌前，看书、做题、记笔记。&lt;/p&gt;
&lt;p&gt;日复一日，一坐就是一年。&lt;/p&gt;
&lt;p&gt;没有捷径，也没有奇迹，只有硬扛。&lt;/p&gt;
&lt;p&gt;我对自己的要求就一条：人笨，就多花时间。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a127d2a8624b48be80986f672ebcbdb5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR5pivQWxsZW4=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784792868&amp;amp;x-signature=ywfQdp%2FGAFXCyY0Ym765LHceLb8%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;四、写在最后&lt;/p&gt;
&lt;p&gt;1、&amp;nbsp; 这一年，我没有输出多少技术文章，但输出了一段很真实精彩的人生。尝试了从未尝试过的事，也是以前不敢想象的事。&lt;/p&gt;
&lt;p&gt;2、&amp;nbsp; AI 还在学，娃还在长，研究生还要继续读。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;如果你也处在类似的阶段——焦虑、迷茫、被生活推着走——我想说，不要给自己设限，多尝试尝试，也许真的会看到不一样的风景。&lt;/p&gt;</description><link>https://juejin.cn/post/7662691781214470180</link><guid isPermaLink="false">https://juejin.cn/post/7662691781214470180</guid><pubDate>Thu, 16 Jul 2026 06:49:11 GMT</pubDate><author>我是Allen</author><category></category><category>前端</category><category>后端</category><category>产品经理</category></item><item><title>曾经人手一个的Superpowers，为什么现在都在卸</title><description>&lt;p&gt;一个GitHub上有超过25万星标的项目，用户正在集体卸载它。&lt;/p&gt;
&lt;p&gt;这个项目叫Superpowers，是Claude Code生态里最火的skill插件，没有之一。装上之后，它会给你的Agent注入14个skill模块，强制每个任务走brainstorm、spec、plan、TDD、code、review这一整套流程。&lt;/p&gt;
&lt;p&gt;听起来很美好对吧？&lt;/p&gt;
&lt;p&gt;但最近我身边的朋友一个接一个把它卸了。我问为什么，得到的答案出奇的一致，太慢了，太吃token了，而且现在的Agent已经不需要这些东西了。&lt;/p&gt;
&lt;p&gt;我一开始是不信的。直到我自己也卸了。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;🔹 &amp;nbsp;先说说Superpowers到底干了什么&lt;/h2&gt;
&lt;p&gt;Superpowers刚出来的时候，确实解决了一个真实的痛点。&lt;/p&gt;
&lt;p&gt;那时候的Agent还比较「莽」。你丢一个需求过去，它上来就开始写代码，不规划，不测试，写完可能一堆bug。你得反复让它改，效率其实很低。&lt;/p&gt;
&lt;p&gt;Superpowers的思路是，既然Agent自己不够自律，那就给它加一套流程约束。每个任务必须先头脑风暴，再写spec，再做计划，再TDD，再写代码，最后review。相当于给一个冲动的实习生套上了一整套SOP。&lt;/p&gt;
&lt;p&gt;2025年秋天它发布的时候，整个开发者社区都在安利。GitHub星标一路飙过25万，进了Anthropic官方市场。&lt;/p&gt;
&lt;p&gt;但问题是，那是2025年的Agent。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;🔹 &amp;nbsp;25万星标背后的代价&lt;/h2&gt;
&lt;p&gt;我真正动了卸载念头，是因为一个朋友跟我吐槽。他让Claude Code帮他改一个很小的bug，就是把一个变量名从驼峰改成下划线。&lt;/p&gt;
&lt;p&gt;正常来说，这个事情十秒钟就搞定了。&lt;/p&gt;
&lt;p&gt;但装了Superpowers之后，它先花了一分钟做brainstorm，然后写了一份spec，接着做了一个plan，然后才开始改那个变量名。改完还要跑一遍review。&lt;/p&gt;
&lt;p&gt;一个十秒钟的事，搞了五分钟。&lt;/p&gt;
&lt;p&gt;他跟我说完我就去GitHub上翻了一下issue，发现有这种感觉的人真不少。&lt;/p&gt;
&lt;p&gt;有个用户专门做了测试，装上Superpowers之后，Claude Code启动就要吃掉22000个token，还没开始干活就先用掉了11%的上下文窗口。再加上系统本身的占用，有效工作空间大打折扣。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c97398a498504a699dbe6b1fc9ae914d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Y2h5Y2h572X54m55a2mQUk=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784789277&amp;amp;x-signature=WMxGeo4rqP6tLrH9bDLTcGy1srI%3D&quot; alt=&quot;GitHub Issue #190：启动消耗 22k+ token&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡&lt;/p&gt;
&lt;p&gt;GitHub地址：github.com/obra/superpowers/issues/190&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;还有个更离谱的，有人说他一个简单任务，5分钟就把整个token配额打满了。原话是「after 5 minutes i went from 0% to 100% quota reached」。&lt;/p&gt;
&lt;p&gt;一个本来是帮你省力的工具，结果反过来成了最大的资源消耗源。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;🔹 &amp;nbsp;不止是慢，它还可能让Agent变蠢&lt;/h2&gt;
&lt;p&gt;这个是我没想到的。&lt;/p&gt;
&lt;p&gt;有个Hacker News用户的评论让我印象特别深，他说「I personally don&#39;t like superpowers very much. My boss does. I think Claude makes more mistakes when using superpowers than when not」。连他老板都觉得好用，但他自己用下来的体验是，装了之后Claude反而犯更多错了。&lt;/p&gt;
&lt;p&gt;你想想看，这其实说得通。Agent的上下文窗口是有限的，你塞了14个skill进去，每个skill都有一堆指令和规则，Agent在处理你的需求的同时还要兼顾这些规则，注意力被分散了。就像你让一个人干活的同时还要背诵一本操作手册，他反而更容易出错。&lt;/p&gt;
&lt;p&gt;维护者自己也意识到了这个问题。后来专门做了一次大优化，把14个skill的代码从3150行砍到了977行，砍掉了69%。&lt;/p&gt;
&lt;p&gt;但砍完之后核心问题还在，它依然会在每个任务前面强制插入一套完整流程。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;🔹 &amp;nbsp;最让我觉得有意思的一个对比&lt;/h2&gt;
&lt;p&gt;有个叫DizzyMii的开发者做了一个叫fable-skills的项目，只有6个轻量skill，思路跟Superpowers完全相反，不搞强制流程，只在关键节点轻轻引导一下。&lt;/p&gt;
&lt;p&gt;他用Opus 4.8做了多轮压力测试来打磨这6个skill，得出的结论是，轻量引导完全够用。&lt;/p&gt;
&lt;p&gt;不需要14个，6个就够了。&lt;/p&gt;
&lt;p&gt;这说明什么？不是skill越多越好，也不是流程越复杂越好。Agent不需要你给它套那么多规矩，它需要的是在关键节点被轻轻推一下就够了。&lt;/p&gt;
&lt;p&gt;Agent不是不听话的小孩，它是一个需要适度引导的成年人。你给它发一份员工手册就够了，不需要派一个监工24小时盯着。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;🔹 &amp;nbsp;那Agent到底变强了多少&lt;/h2&gt;
&lt;p&gt;说真的，这半年Agent的进化速度是肉眼可见的。&lt;/p&gt;
&lt;p&gt;我自己最直观的感受是，Fable 5出来之后，很多以前需要skill才能做到的事，它自己就会了。&lt;/p&gt;
&lt;p&gt;以前的Agent你不告诉它「先想清楚再动手」，它真的会上来就莽。现在不一样了，你丢一个复杂需求给Fable 5，它会自己先去看相关文件，理清依赖关系，想好方案，然后才开始改。改完还会自己跑测试验证。&lt;/p&gt;
&lt;p&gt;MCP Directory有篇专题文章说得很直白，「Fable 5 investigates before acting and verifies its own work with less prompting」。模型自己已经会规划和验证了，不需要外挂一套流程来教它。&lt;/p&gt;
&lt;p&gt;文章最后的建议是，如果你用Fable 5，最多保留brainstorm和review两个模块就够了，其他的全删。&lt;/p&gt;
&lt;p&gt;WebDevCody，YouTube上很有名的一个开发者，也公开发推说卸载了。他的原话是「I guess I&#39;m just not a fan of having to babysit it the entire time and answer its 20 questions to implement a simple feature. I rather let Claude yolo it and reprompt a bad first iteration」。&lt;/p&gt;
&lt;p&gt;为了实现一个简单功能，要回答20个问题。他宁可让Claude先莽一遍，不行再重来，也不想被流程绑着走。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b741b56d954e45f1a3ab242de9cdaf2a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Y2h5Y2h572X54m55a2mQUk=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784789277&amp;amp;x-signature=nA%2Fl15uXic5Jy%2FsIdy9d7T%2FQtJA%3D&quot; alt=&quot;WebDevCody 发推卸载 Superpowers&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡&lt;/p&gt;
&lt;p&gt;X推文地址：x.com/webdevcody/status/2006458368387596696&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说真的我完全理解这种感觉。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;🔹 &amp;nbsp;这其实是一个很经典的规律&lt;/h2&gt;
&lt;p&gt;你回想一下智能手机刚出来的时候。&lt;/p&gt;
&lt;p&gt;那时候iPhone上什么都要装app。手电筒要装一个app，计算器要装一个app，指南针要装一个app，扫码要装一个app，甚至量尺寸都要装一个app。&lt;/p&gt;
&lt;p&gt;后来呢？系统自带了。手电筒内置了，计算器内置了，指南针内置了，扫码用相机就行了。那些曾经下载量百万的工具类app，安静地消失了。&lt;/p&gt;
&lt;p&gt;没有人怀念它们。&lt;/p&gt;
&lt;p&gt;AI开发工具正在经历完全一样的事情。早期模型能力不够，需要外挂skill来补能力，就像早期手机功能不全需要第三方app来补功能。但模型能力上来之后，这些外挂的skill就变成了冗余。&lt;/p&gt;
&lt;p&gt;当底层能力足够强的时候，上层的补丁自然会退场。这不是skill做得不好，是它完成了自己的历史使命。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-6&quot;&gt;🔹 &amp;nbsp;但我不是说skill完全没用了&lt;/h2&gt;
&lt;p&gt;这话我得说清楚。&lt;/p&gt;
&lt;p&gt;Superpowers对有些人来说依然有价值。如果你是一个刚开始用AI写代码的新手，你可能确实需要一套流程来帮你建立好的工作习惯。如果你在一个团队里，需要统一所有人的开发规范，强制走review流程，那Superpowers的思路也是合理的。&lt;/p&gt;
&lt;p&gt;还有一些特别复杂的、跨多个文件和系统的大型重构，有时候一个轻量的plan skill确实能帮Agent理清思路。&lt;/p&gt;
&lt;p&gt;关键是，skill应该是「按需启用」的，而不是「全套安装」的。&lt;/p&gt;
&lt;p&gt;就像你不会在手机上装14个效率app然后全部开着后台运行一样。你需要哪个就开哪个，不需要的时候就关掉。&lt;/p&gt;
&lt;p&gt;反正我觉得，2026年下半年的正确姿势是，CLAUDE.md写好项目规范，必要的时候挂一两个轻量skill做特定场景的辅助，其他的交给Agent自己来。&lt;/p&gt;
&lt;p&gt;Agent已经长大了，你得学会放手。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-7&quot;&gt;🔹 &amp;nbsp;说到底&lt;/h2&gt;
&lt;p&gt;工具生态的演化跟自然界其实是一个道理。早期物种靠外骨骼保护自己，后来进化出了内骨骼，外骨骼就退化了。不是外骨骼不好，是内在能力强到不需要它了。&lt;/p&gt;
&lt;p&gt;Superpowers是一个好产品，它在Agent还不够成熟的时候提供了真实的价值。但技术的车轮不等人，模型在进化，Agent在进化，用户的需求也在进化。&lt;/p&gt;
&lt;p&gt;能力被内化，补丁就退场。&lt;/p&gt;
&lt;p&gt;这不是谁的失败，这是进步本身。&lt;/p&gt;
&lt;p&gt;你现在还在用Superpowers或者其他skill插件吗？觉得哪些该留哪些该卸？评论区聊聊，我每条都看。顺手点个赞，点个在看，星标⭐加一个，下次更新第一时间见。&lt;/p&gt;
&lt;p&gt;谢谢你看我的文章，我们，下次再见。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡&lt;/p&gt;
&lt;p&gt;/ 作者：卡卡罗特 / 投稿或爆料，请联系邮箱：&lt;a href=&quot;https://link.juejin.cn/?target=mailto%3A19331922086%40163.com&quot; target=&quot;_blank&quot; title=&quot;mailto:19331922086@163.com&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;19331922086@163.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><link>https://juejin.cn/post/7662691781214437412</link><guid isPermaLink="false">https://juejin.cn/post/7662691781214437412</guid><pubDate>Thu, 16 Jul 2026 06:47:57 GMT</pubDate><author>卡卡罗特学AI</author><category>人工智能</category><category>程序员</category></item><item><title>Harness 企业级落地(二) - 让 AI 读懂项目</title><description>&lt;blockquote&gt;
&lt;p&gt;上一篇，我们描述了 Harness 的框架和整体设计：一套稳健的软件工程设计，约束 AI 在工程里稳定的工作。开源地址：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FWxqKb%2Fcow-harness&quot; target=&quot;_blank&quot; title=&quot;https://github.com/WxqKb/cow-harness&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;cow-harness&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://juejin.cn/post/7641912628643528738&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/post/7641912628643528738&quot;&gt;AI Harness 企业级落地实践（一）&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这一篇我们继续深究，一个团队如何能成长为：AI 全栈开发，可以同时维护 APP、后台、网页等多端代码。&lt;/p&gt;
&lt;p&gt;AI 时代下，我们认为程序员不应该局限于某一门技术，&lt;strong&gt;应该以顶层思维看待整个项目,了解整个系统的设计和数据流向。&lt;/strong&gt; &lt;br&gt;
这样不仅能够提高个人的知识广度，更能够独立且高效地完成具体的某个模块，从而加快产品的迭代速度，实现快速的想法验证。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;一、顶层设计思维&lt;/h2&gt;
&lt;p&gt;要完成 AI 全栈，得先做到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把我们的&lt;code&gt;全栈项目汇总管理起来&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;让 AI &lt;code&gt;读懂每个子项目&lt;/code&gt;的代码风格、框架分层、设计理念，并沉淀下来&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;进而达到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无论什么模型，都能快速地知道你的需求，&lt;code&gt;需要动到具体哪一个端&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;编码符合这个端的风格，代码也不会出现低级失误&lt;/li&gt;
&lt;li&gt;编写完毕之后，能够自动启动各个端，然后自己做跨端的e2e 全流程测试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;二、基于 git submodule 的项目结构&lt;/h2&gt;
&lt;p&gt;针对全栈协作的场景，APP、后端和网页端等各个端，会有各自有独立的代码仓库，同时迭代节奏和分支管理也有所不同。&lt;/p&gt;
&lt;p&gt;所以我们先维护一个组合根仓库，把业务子项目通过 &lt;strong&gt;Git submodule 的方式去汇合起来&lt;/strong&gt;，常见的结构大致是这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;fullstack-workspace/
├── cow-harness/                    &lt;span class=&quot;hljs-comment&quot;&gt;# 全栈入口与通用 Harness&lt;/span&gt;
├── .ai-harness/
│   └── workspace-map.md            &lt;span class=&quot;hljs-comment&quot;&gt;# 业务模块地图&lt;/span&gt;
├── apps/mobile/                    &lt;span class=&quot;hljs-comment&quot;&gt;# APP 端代码（git submodule）&lt;/span&gt;
├── services/backend/               &lt;span class=&quot;hljs-comment&quot;&gt;# 后端代码（git submodule）&lt;/span&gt;
└── apps/web/                       &lt;span class=&quot;hljs-comment&quot;&gt;# 网页端代码（git submodule）&lt;/span&gt;
│ 
└── .gitmodules     
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;.gitmodules&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记录仓库来源和落盘路径，根仓库记录每个子仓库此刻应使用的分支。这样子团队任何人拉下根仓库，都能拿到同一组前后端代码版本；&lt;/li&gt;
&lt;li&gt;submodule 本身不会影响子项目的分支策略，分支规范、提交习惯和代码目录仍由各子仓库自己维护。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;workspace-map.md&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;盘点子项目分别属于什么领域、是否已经初始化等；&lt;/li&gt;
&lt;li&gt;一张地图，解决“这个任务先去哪里”。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;三、让 AI 深度读懂整个项目&lt;/h2&gt;
&lt;p&gt;“读懂” 不是让 AI 把整个仓库扫一遍，然后给你写一份看上去很专业的总结；而是要&lt;strong&gt;非常精准的知道每个项目的设计、风格、规范约束、安全性能指标等。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为此，我们特意为这个环节编写了一个 SKILL：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FMinLeeV5%2Fdomain-init-skill%2Ftree%2Fmain&quot; target=&quot;_blank&quot; title=&quot;https://github.com/MinLeeV5/domain-init-skill/tree/main&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;domain-init&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这个 SKILL 拥有非常完整的项目识别能力，不仅接入到 cow-harness，也独立进行了开源，需要自取：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FMinLeeV5%2Fdomain-init-skill%2Ftree%2Fmain&quot; target=&quot;_blank&quot; title=&quot;https://github.com/MinLeeV5/domain-init-skill/tree/main&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/MinLeeV5/do…&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-id=&quot;heading-3&quot;&gt;1. 前置介绍&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;domain-init&lt;/code&gt; 会先做领域识别：从构建文件、依赖、入口、测试工具和目录结构里找信号，判断当前项目是哪个端（如：更接近 React 前端、Go 后端、移动端、CLI...）。&lt;/p&gt;
&lt;p&gt;确定领域后，&lt;code&gt;会采样真实代码&lt;/code&gt;，识别项目已经在使用的架构设计、组件规范、接口分层、测试夹具和验证命令等等，&lt;code&gt;再把这些事实变成可 review 的规则草案&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;核心重点：代码是事实源，规则只是对事实的结构化表达。&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h4 data-id=&quot;heading-4&quot;&gt;2. 四大原则&lt;/h4&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;原则&lt;/th&gt;&lt;th&gt;它解决的问题&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;信号优先&lt;/td&gt;&lt;td&gt;先根据项目里的依赖、入口和构建文件判断领域，避免一份前端规范误用到后端或客户端。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;证据先行&lt;/td&gt;&lt;td&gt;每条约定都要能回到项目代码中找到出处，避免模型凭记忆造出“理论正确、项目错误”的规则。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;按领域过滤&lt;/td&gt;&lt;td&gt;前端重点看设计系统、状态和可访问性；后端重点看接口、数据和可观测性。相关的才进入上下文。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;人不缺席&lt;/td&gt;&lt;td&gt;领域判断、扫描范围、规则草案和最终写入都有确认点。AI 负责归纳，人负责判断哪些是约定、哪些只是历史包袱。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 data-id=&quot;heading-5&quot;&gt;3.最佳实践&lt;/h4&gt;
&lt;p&gt;如果只是从已有项目里抽取，会有另一个风险：&lt;code&gt;可能原本项目就设计得不是很好，然后 AI 就会依照这个规范越写越烂。&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;于是 &lt;code&gt;domain-init&lt;/code&gt; 还提供了一些最佳实践 references。&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;参考文件&lt;/th&gt;&lt;th&gt;设计作用&lt;/th&gt;&lt;th&gt;避免&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;detection-signals.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;定义领域识别的优先级、降级路径和人工确认机制。&lt;/td&gt;&lt;td&gt;把项目类型猜错。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;domain-matrix.md&lt;/code&gt; 与 &lt;code&gt;dimension-pool.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;用领域矩阵过滤规则、Skill 和 Agent 的适用维度。&lt;/td&gt;&lt;td&gt;把所有治理维度一次性塞给每个项目。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;project-index.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;为不同问题指定开源质量标杆和应参考的关键文件。&lt;/td&gt;&lt;td&gt;只会套空泛的“最佳实践”。&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;output-formats.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;规定 rule、skill、agent 的结构、代码示例和证据要求。&lt;/td&gt;&lt;td&gt;生成只有口号、没有执行性的产物。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;code&gt;project-index.md&lt;/code&gt; ：关键的质量索引，引用了大量的优秀实践，不同的问题，我们去找不同的标杆。比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编码约定可以参考 &lt;code&gt;everything-claude-code&lt;/code&gt; 的分语言规则&lt;/li&gt;
&lt;li&gt;前端性能和组件架构可以参考 Vercel 的 agent skills&lt;/li&gt;
&lt;li&gt;测试策略和验证门控可以看 &lt;code&gt;get-shit-done&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;安全审查则有 &lt;code&gt;gstack&lt;/code&gt; 和 Trail of Bits 的工作流&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时，使用这些优秀实践时，不是把别人仓库的内容拷过来。核心是&lt;strong&gt;让 AI 学习它如何组织规则、如何表达硬约束、如何把验证写进流程&lt;/strong&gt;；然后再回到当前项目的代码事实，生成适合自己的内容。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;验证链路：&lt;strong&gt;领域判断有信号，规则结论有代码，产物质量有标杆，落盘前有人 review。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-id=&quot;heading-6&quot;&gt;四、初始化产物&lt;/h2&gt;
&lt;p&gt;初始化完成后，每个子项目里都会有一组**能被后续任务反复读取的资产。**这些资产不会放在组合根仓库，而是放在各自的业务子项目里。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;services/backend/
├── AGENTS.md                       &lt;span class=&quot;hljs-comment&quot;&gt;# AI 进入项目的入口&lt;/span&gt;
├── cow-harness/
│   └── skills/domain-init/          &lt;span class=&quot;hljs-comment&quot;&gt;# 嵌套的领域初始化 skill&lt;/span&gt;
├── .ai-harness/
│   ├── project.profile.md           &lt;span class=&quot;hljs-comment&quot;&gt;# 项目画像&lt;/span&gt;
│   ├── context-map.md               &lt;span class=&quot;hljs-comment&quot;&gt;# 模块、入口与边界&lt;/span&gt;
│   ├── verification.md              &lt;span class=&quot;hljs-comment&quot;&gt;# 验证方式与命令&lt;/span&gt;
│   └── domain-init-report.md        &lt;span class=&quot;hljs-comment&quot;&gt;# 检测依据、确认范围和结果&lt;/span&gt;
├── .agents/                         &lt;span class=&quot;hljs-comment&quot;&gt;# 当前项目选择的平台规则、skills、agents&lt;/span&gt;
└── .ai-runtime-artifacts/           &lt;span class=&quot;hljs-comment&quot;&gt;# 需求、计划、验证与决策记录&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;project.profile.md&lt;/code&gt; ：回答“这是什么项目、关键约束是什么”；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;context-map.md&lt;/code&gt; ：回答“代码应该改在哪里、边界在哪里”；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;verification.md&lt;/code&gt; 回答“改完怎么证明它没问题”。&lt;/p&gt;
&lt;p&gt;另外还会生产一些模型层的入口&lt;/p&gt;
&lt;p&gt;&lt;code&gt;domain-init-report.md&lt;/code&gt; ：把领域判断的依据、用户确认过的范围和生成结果保留下来，避免这些结论变成无从追问的黑盒；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.agents/&lt;/code&gt; ：这个项目真正会被 AI 加载的规则、skills 和 agents；&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.ai-runtime-artifacts/&lt;/code&gt; ：保存需求分析、计划、验证记录和架构决策。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-7&quot;&gt;五、初始化后，如何执行任务&lt;/h2&gt;
&lt;p&gt;当一个任务从全栈组合根目录进入时&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;AI 先读 &lt;code&gt;workspace-map.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;任务里出现明确的项目路径、模块名、接口名或界面名，就用这些证据定位业务子项目&lt;/li&gt;
&lt;li&gt;结合相关的多个项目，开始判定任务体量，决定是否进行 spec 拆解&lt;/li&gt;
&lt;li&gt;项目一旦选定，读取顺序也固定下来：先通过 &lt;code&gt;AGENTS.md&lt;/code&gt; 进入项目，再加载 &lt;code&gt;cow-harness/core/&lt;/code&gt; 的通用流程，以及当前项目的 &lt;code&gt;project.profile.md&lt;/code&gt;、&lt;code&gt;context-map.md&lt;/code&gt; 和 &lt;code&gt;verification.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;然后 AI 会遵循 harness 的规范，去使用 superpower 和 omx 开始干活&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2bf63dd5a293469fac6481088e3873c5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgS2FybF93ZWk=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784741812&amp;amp;x-signature=qDGFZwR%2FQUjgXA0qZHar67DbgCo%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;六、快速接入&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;维护好全栈组合仓库，先把所有子模块拉到组合根仓库锁定的版本：&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;hljs language-css&quot; lang=&quot;css&quot;&gt;git submodule update &lt;span class=&quot;hljs-attr&quot;&gt;--init&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;--recursive&lt;/span&gt;
git submodule status &lt;span class=&quot;hljs-attr&quot;&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.  &lt;code&gt;cow-harness&lt;/code&gt;也作为 submodule 加入到你的项目中&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;git submodule &lt;span class=&quot;hljs-keyword&quot;&gt;add&lt;/span&gt; git&lt;span class=&quot;hljs-variable&quot;&gt;@github&lt;/span&gt;.com:WxqKb&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;cow&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;harness.git cow&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;harness
git submodule &lt;span class=&quot;hljs-keyword&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;--init --recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.  接下来让&lt;code&gt;cow-harness&lt;/code&gt; 开始为你初始化子项目：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;hljs language-swift&quot; lang=&quot;swift&quot;&gt;请先读取 cow&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;harness&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;hljs-type&quot;&gt;README&lt;/span&gt;.md&lt;span class=&quot;hljs-operator&quot;&gt;、&lt;/span&gt;cow&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;harness&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;fullstack&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;bootstrap.prompt.md
和 cow&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;harness&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;skills&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;domain&lt;span class=&quot;hljs-operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;hljs-operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;hljs-type&quot;&gt;SKILL&lt;/span&gt;.md&lt;span class=&quot;hljs-operator&quot;&gt;。&lt;/span&gt;

这是一个由多个业务子项目组成的全栈项目&lt;span class=&quot;hljs-operator&quot;&gt;。&lt;/span&gt;请先运行
git submodule status &lt;span class=&quot;hljs-operator&quot;&gt;--&lt;/span&gt;recursive，区分业务子项目&lt;span class=&quot;hljs-operator&quot;&gt;、&lt;/span&gt;&lt;span class=&quot;hljs-type&quot;&gt;Harness&lt;/span&gt; 和第三方依赖；
展示候选业务子项目并等待我选择&lt;span class=&quot;hljs-operator&quot;&gt;。&lt;/span&gt;只初始化我确认的子项目，
不要在组合根目录生成混合的领域规则，也不要自动改写未选择的子项目&lt;span class=&quot;hljs-operator&quot;&gt;。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-id=&quot;heading-9&quot;&gt;七、写在最后&lt;/h2&gt;
&lt;p&gt;实际上，各大基模的在 coding 的发力下，&lt;strong&gt;AI 对程序员行业的冲击是致命的&lt;/strong&gt;，在大公司体感是十分明显的。&lt;/p&gt;
&lt;p&gt;比方说：接收到的一句话需求，能让 AI 全面了解拆分，快速搭建出 A/B 方案，并发布给天使用户测试。这个流程验证以往可能要投入一周的时间，但是 AI +harness 2 天就能搞定。&lt;code&gt;而这种提效方式，对个人和业务都会产生不容小视的价值，而且早已不是天方夜谭。&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Harness 全栈说白了，也会卷掉一波人。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但笔者想说的是，在这个大环境下我们尽量去成长。当编码技术不再是壁垒的时候，我们应该更快速的去利用好 AI，&lt;code&gt;让 AI 全面扩宽我们的知识面和业务边界。&lt;/code&gt; 沉淀成为我们的核心竞争力，那我相信当环境好起来后，你依然是那个香饽饽～&lt;/p&gt;
&lt;p&gt;下一篇，我们会继续深入讲解 harness 中，是如何使用 openspec 和 omx 工作流，进行高质量的工作的。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FWxqKb%2Fcow-harness&quot; target=&quot;_blank&quot; title=&quot;https://github.com/WxqKb/cow-harness&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;cow-harness&lt;/a&gt; 开源仓库，欢迎使用！&lt;/p&gt;</description><link>https://juejin.cn/post/7662586328122982415</link><guid isPermaLink="false">https://juejin.cn/post/7662586328122982415</guid><pubDate>Wed, 15 Jul 2026 17:36:52 GMT</pubDate><author>Karl_wei</author><category>人工智能</category><category>OpenAI</category><category>全栈</category><category>程序员</category></item><item><title>掘金VibeLaunch 沸点秀 来啦🚀</title><description>&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0ee799f8979a44ad8e3b7440dd2e370a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5rK454K55bCP5Yqp5omL:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784708833&amp;amp;x-signature=66lxd4sgLlq24%2FEtVRLpSPiX8zs%3D&quot; alt=&quot;求职招聘宣传公众号首图 (1).jpg&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;不用死磕代码，用 Prompt 指挥 AI，分分钟把脑洞变成能跑的项目——这就是 Vibe‑Coding 的魔力。&lt;/p&gt;
&lt;p&gt;现在，掘金请你来「沸点」晒出你的 AI 编程成果！&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-0&quot;&gt;✅ 参与方式&lt;/h3&gt;
&lt;p&gt;带&lt;strong&gt;话题&lt;/strong&gt; &lt;a href=&quot;https://juejin.cn/pin/topic/7662229855023988763&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/pin/topic/7662229855023988763&quot;&gt;#VibeLaunch 沸点秀&lt;/a&gt;，在 &lt;a href=&quot;https://juejin.cn/pin/club/7461650741493497865&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/pin/club/7461650741493497865&quot;&gt;VibeLaunch &lt;strong&gt;圈子&lt;/strong&gt;&lt;/a&gt;下发沸点，包括但不限于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目简介 + 实现思路&lt;/li&gt;
&lt;li&gt;成果截图 / 演示视频（加分）&lt;/li&gt;
&lt;li&gt;附上 Prompt 或代码片段（更容易拿奖哦）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/31deb12e2348414c926732799b5330aa~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5rK454K55bCP5Yqp5omL:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784708833&amp;amp;x-signature=0tG%2FLFEAFrr4GwTJUuE5nla5uaQ%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h4 data-id=&quot;heading-1&quot;&gt;📅 参与时间&lt;/h4&gt;
&lt;p&gt;7月15日-7月24日 23：59&lt;/p&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;📮 内容参考&lt;/h3&gt;
&lt;p&gt;✔️ 可运行项目：前端页面、自动化脚本、组件 Demo、小工具、简易应用……通通欢迎&lt;/p&gt;
&lt;p&gt;✔️ 经验干货：Prompt 编写技巧、开发思路、踩坑复盘&lt;/p&gt;
&lt;p&gt;✔️ 标配三件套：项目介绍 + 运行截图/视频 +项目地址（获奖概率飙升）&lt;/p&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;🎁 奖励清单&lt;/h3&gt;
&lt;p&gt;🥇 一等奖（3人）：SZCOOL 无线蓝牙音箱&lt;/p&gt;
&lt;p&gt;🥈 二等奖（5人）：联想异能者笔记本散热器&lt;/p&gt;
&lt;p&gt;🎉 基础奖：符合活动要求且话题帖互动 ≥5，再得5000矿石/人&lt;/p&gt;
&lt;h3 data-id=&quot;heading-4&quot;&gt;🏅 评选标准&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;热度参考：根据沸点的点赞、评论、收藏数据作为基础参考。&lt;/li&gt;
&lt;li&gt;官方评审：从创意（项目新颖度）、完成度（可运行性&amp;amp;功能完整）、干货价值（Prompt技巧&amp;amp;经验分享）三个维度综合打分。&lt;/li&gt;
&lt;li&gt;综合考评：一二等奖由“热度+评审”综合得分排序产生。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目不分大小，练手 Demo 也能大胆秀！&lt;/p&gt;
&lt;p&gt;来沸点一起交流 Prompt 技巧，玩转 Vibe‑Coding，奖品矿石等你抱走～&lt;/p&gt;
&lt;p&gt;现在就带话题发帖，下一个获奖者就是你！&lt;/p&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;☝️活动规则&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;无意义水评论、刷赞等违规行为，剔除获奖资格；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁止引战/制造冲突/谩骂内容，或者发现引战内容剔除获奖资格；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本人发帖点赞/评论互动数据不计入互动量；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;矿石将在申诉时间截止后 3 个工作日内发放；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;活动最终解释权归稀土掘金所有；&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description><link>https://juejin.cn/post/7662552601268322313</link><guid isPermaLink="false">https://juejin.cn/post/7662552601268322313</guid><pubDate>Wed, 15 Jul 2026 08:26:06 GMT</pubDate><author>沸点小助手</author><category>人工智能</category><category>AI编程</category><category>AIGC</category></item><item><title>不自己造轮子：在小艺开放平台搭一个真实的健康小助手</title><description>&lt;p&gt;之前一直是自己那台跑在 127.0.0.1 上的 Python 网关在撑场面。这次反过来，一行代码不写，看小艺开放平台自己能不能把一个能用的智能体从零跑起来。场景选了健康小助手：算体重、看一顿饭吃得怎么样、给点吃得更好的建议，都是手机健康 App 的老套路，拿这个来试平台的完整度，够用了。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;新建项目，先卡在选哪种模式&lt;/h2&gt;
&lt;p&gt;小艺开放平台首页那句&quot;鸿蒙智能全新升级，基于鸿蒙生态和 AI 大模型能力，为你提供鸿蒙智能体一站式开发解决方案&quot;，第一眼看跟大多数产品首页的宣传语没什么两样。真进去点了才发现，这句话背后确实对应一整套从创建到调试的网页工具链。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/018703b9cf0748d8ae3bdf0ab93da75d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=Oj0zCOVxvbvUCStwDiNhlDe3Sr4%3D&quot; alt=&quot;小艺开放平台首页&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;点&quot;新建项目&quot;，顶上先要选智能体还是 Skill。侧边栏里 Skill 广场挂着一堆现成的能力，kuaidi100-user、fitness-coach、autonomous-tasks、news-extractor 这些，说明 Skill 更像是能被智能体调用的一个个功能模块，智能体才是真正跟用户对话的那个东西。这次做的是健康小助手，选智能体。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/255f9ef08ee24f86b7a5c785e022d339~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=mWr%2B0bO1tkaOPuN%2BrUGS1mY7W20%3D&quot; alt=&quot;新建项目选择智能体还是 Skill&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;选完还有一层开发模式：端 A2A（HarmonyOS 应用里通过 AgentAbility 开发）、云 A2A（三方模型驱动）、云工作流（编排步骤清晰的业务）、OpenClaw（个人专属的 7×24 智能体）。OpenClaw 那个描述挺吸引人，翻文档才知道要求接入方是 HarmonyOS NEXT 真机，手上没有这台设备，只能放弃，选了云工作流模式。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/83c7797c809740b4982373f1d237b312~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=d0kY65qNF79cPssE4j0Ba7bwCTs%3D&quot; alt=&quot;选择开发模式&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;选完云工作流，又弹出一层：单 Agent 模式还是多 Agents 模式。健康小助手就三件事，体重、饭菜、建议，逻辑谈不上复杂，用不上多智能体协作，选了单 Agent。这层选择最后落到编排页顶部一个不起眼的下拉框上，写着&quot;LLM 模式&quot;，如果不是一步步点过来，光看编排页面根本猜不出前面还套了两层选择。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f2666a12e22a437a8e846c3812c0cfad~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=VHJsyCqNDOMaZHJxHbaHOKhhpRk%3D&quot; alt=&quot;单 Agent 模式与多 Agents 模式&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;名字和描述先填&lt;/h2&gt;
&lt;p&gt;进编排页之前要填名称和头像，&quot;健康小助手&quot;，头像用了默认的机器人图标，没细抠。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/738c2746034f4ca5b533d9535bdb5a1a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=8%2BmHRbiaodrJy6%2FS2g2G2stZbIs%3D&quot; alt=&quot;填写智能体名称和头像&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;描述填的是&quot;关注你的健康，体现我的价值&quot;，13 个字。页面在旁边标了两处用法：智能体主页点&quot;更多&quot;会显示这段话，小艺广场搜索的时候它也会被当关键词检索。写的时候没想那么多，后来才反应过来，这句话其实决定了用户搜什么词能搜到这个智能体，跟随便写一句自我介绍不是一回事。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f0895ef0b2ec4df2b0a5fcc1bfb1012e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=qEEMy3T46v9oxCc%2FyszuZndAxBs%3D&quot; alt=&quot;智能体描述及其展示位置&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;开场语、角色指令，填的时候右边就在预览&lt;/h2&gt;
&lt;p&gt;编排页里模型选的是 DeepSeek-V3 增强版，平台自带的选项，不用自己申请 API Key。这点跟自建 Gateway 那几篇比起来省心不少，那几篇每次截图前都要检查有没有不小心把 Key 露出来。&lt;/p&gt;
&lt;p&gt;开场语：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;你好，我是健康小助手。把你的身高体重告诉我，我能帮你看看体重是不是在正常范围；把你这顿饭吃了什么说给我听，我能帮你估算营养搭配，再给你一点吃得更好的具体建议。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配了三条开场引导，分别对应三项能力：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;我身高170cm，体重68kg，这个体重正常吗？
帮我看看：一碗红烧肉盖饭配一杯奶茶，这顿饭健康吗？
我最近想瘦一点，帮我出一份一周晚餐的饮食建议。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;填的时候右侧调试预览面板会同步渲染成对话气泡，能直接看到用户点开这个智能体第一眼看到的样子，这个即时反馈比自己写 ArkUI 页面再跑一遍 Previewer 快多了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/11b56018f1dd44939b785e08f494ea86~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=EcOKAJVJpJ7h1Ugd8hnbXUtyRyo%3D&quot; alt=&quot;开场语与开场引导的实时预览&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;角色指令填在编排页中间那一栏，这次特意把能力边界写得跟能力清单一样详细，没有只堆功能：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;你是&quot;健康小助手&quot;，帮助普通用户理解自己的身体指标和饮食情况，服务日常健康管理，不替代医生诊断。

你的核心能力：
1. 体重体脂分析：根据用户提供的身高、体重（可选年龄、性别），计算 BMI，说明所处区间（偏瘦/正常/超重/肥胖），给出简明解读。
2. 饭菜分析：根据用户描述的菜品，估算大致热量和主要营养构成（蛋白质/脂肪/碳水/蔬菜占比），指出这顿饭的优点和不足。
3. 饮食建议：结合前两项结果，给出可执行的饮食调整建议，兼顾口味和现实可行性，不要求用户吃极端节食餐单。

回答规则：
- 先给结论（比如 BMI 数值和区间），再给 1-3 条具体建议，不堆砌大段理论。
- 用户信息不全时，先友好追问缺失的关键信息（身高、体重、这顿饭具体吃了什么），不要凭空编数据。
- 涉及疾病、用药、极端节食等超出日常健康管理范围的问题，建议咨询医生或专业营养师，不给诊断性结论。
- 语言口语化、简洁，不用夸张营销话术，不用&quot;亲&quot;&quot;宝子&quot;这类称呼。
- 不确定的估算要注明&quot;估算&quot;，不用绝对化语气呈现不确定的数据。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f9b52add96bd408f8ce204c7302fe788~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=YZM1pYCrm1gejlz0OqzZsuv6ZeE%3D&quot; alt=&quot;完整的角色指令内容&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;填完这两块，右上角&quot;上架&quot;提示从三项未完成降到两项未完成，剩下的估计是基础信息里还漏了什么，配置页那边再补。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;提示词只是一小块，插件和知识库才是重头&lt;/h2&gt;
&lt;p&gt;角色指令往下翻，还有一堆东西。用户问题建议，打开后有系统配置 Prompt 和自定义 Prompt 两种，打开了它，回答完会自动带几条追问建议，用户不用自己想接下来问什么。往下是快捷指令（最多 30 条），背景图片，角色声音，再往下是插件（50）、工作流（20）、触发器（10）、关联应用（20）、知识库（10）、变量，最后是长期记忆，这项默认就是开着的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b9d32f1b2cb9469299b0937026711269~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=AKc3dcltsXqgUiU4o%2FOFeASBBR8%3D&quot; alt=&quot;用户问题建议、快捷指令与能力矩阵&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;这一整屏东西这次基本没碰。工具接入需要额外的授权和服务配置，这次的目标就是看纯提示词驱动能不能撑起一个可用的智能体，插件和知识库留白了，没打算装样子说都用上了。但看着这些选项摆在那儿，能感觉到如果真要往下做，接一个真实体重秤、接一份用户历史饮食记录，都是平台原生支持的路，不用自己另起炉灶写接口。&lt;/p&gt;
&lt;p&gt;长期记忆默认开着这件事倒是没想到会顺手帮上忙——健康类对话本来就该记住用户报过的身高体重，不然每次问饮食建议都要重新说一遍，体验会很差。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;上架前要过合规这一关&lt;/h2&gt;
&lt;p&gt;保存后进&quot;配置&quot;页，基础信息和隐私协议服务旁边有一栏内容合规，要如实回答两个问题：这个智能体是否包含人工智能生成的文件，是否接入了非小艺开放平台提供的三方大模型。旁边还有一段条款要勾选确认，写着要按《生成式人工智能服务管理暂行办法》《互联网信息服务深度合成管理规定》《人工智能生成合成内容标识办法》对上架的智能体做审视，隐瞒信息要担责任。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/07e8e6173a02488c9b1e0a830e646a4d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=35%2B0oioi%2Bl0335JlGeiQLyDnu2o%3D&quot; alt=&quot;内容合规声明页面&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;自己写那台 Python 网关的时候完全不会碰到这种东西，本机服务想怎么跑没人管。放到官方平台准备上架，这几部法规的名字直接印在表单上，接不接三方大模型这种细节也要如实报。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;调试面板里问了两个问题&lt;/h2&gt;
&lt;p&gt;角色指令填完，直接在右边调试面板里试。第一句用的是开场引导第一条：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;我身高170cm，体重68kg，这个体重正常吗？
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.916 秒后回来：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;根据你的身高和体重，你的BMI是23.53，在正常范围内（18.5-23.9为正常）。不过，接近超重了，可以适当关注一下饮食和运动。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;算出了具体的 BMI 数值，给了区间，还多说了一句&quot;接近超重&quot;，没有停在&quot;体重正常&quot;这四个字上敷衍过去。下面自动带出三条追问：哪些运动适合我减重、帮我分析如何控制体重、推荐一些健康饮食方案，点一条就能接着聊，不用自己重新组织问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5b914d690fdf45469903d1c81389aef4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=TAGyxO1tE5zOxKfomCMymx91iL0%3D&quot; alt=&quot;体重分析的真实调试结果&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;第二句是开场引导第三条：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;我最近想瘦一点，帮我出一份一周晚餐的饮食建议。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;9.62 秒后拿到一份具体到每天菜名的七天计划，周一蒸鸡胸肉配西兰花糙米饭，周二烤鱼菠菜沙拉红薯，一路排到周日，末尾补了一句&quot;这些建议都是低脂高蛋白，帮助你健康减重&quot;。调试面板右上角还有个朗读入口，带自动播放声音的开关，回答生成后能直接听，这个东西自己那台网关短时间做不出来。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/65ad9fbe4bc54250af9ee7f48085057e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697583&amp;amp;x-signature=%2FcxNxn2DkktYTesJ%2FG%2F6bqIuq9A%3D&quot; alt=&quot;饮食建议的真实调试结果与朗读功能&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-6&quot;&gt;没测完的地方&lt;/h2&gt;
&lt;p&gt;角色指令里写了三项能力，实际调试只测过体重分析和饮食建议，两次都拿到了具体的、不是套模板的回应。第三项饭菜分析虽然配进了开场引导，但调试过程没问到这条，一碗红烧肉盖饭加奶茶到底会被分析出什么结果，现在还不知道，这里不拿写好的提示词冒充已经验证过的效果。角色指令里&quot;涉及用药建议咨询医生&quot;这条边界，也还没拿一个真的越界问题去试过，回答会不会真的被拦住，同样是没做完的部分。&lt;/p&gt;
&lt;p&gt;这次全程没用本机的服务，也没写一行代码，从选开发模式到填角色指令，从内容合规声明到两次调试结果，证据都在小艺开放平台的网页控制台里。一个普通的个人开发者账号，没有真机，没有企业资质，能做到这一步。&lt;/p&gt;</description><link>https://juejin.cn/post/7662376768221364233</link><guid isPermaLink="false">https://juejin.cn/post/7662376768221364233</guid><pubDate>Wed, 15 Jul 2026 05:19:43 GMT</pubDate><author>一只牛博</author><category>人工智能</category></item><item><title>Oracle 迁移评估时，我把这两类问题列在了检查清单最前面</title><description>&lt;p&gt;接手一个 Oracle 迁移评估任务时，大家习惯先看语法兼容性：这个存储过程能不能跑、这个函数有没有对应实现、这张视图的写法要不要改。这些问题好查，工具能扫，跑一遍报错日志就知道改哪。真正让人头疼的不是这些——是那些&lt;strong&gt;语法完全合法、迁移后照样能跑通、只是结果跟原来不一样&lt;/strong&gt;的地方。这类问题不报错，不会出现在任何迁移报告的&quot;失败项&quot;里，只会在业务侧发现报表对不上、对账差了几行的时候才暴露出来，而且往往已经是上线之后了。&lt;/p&gt;
&lt;p&gt;这次评估里踩到两个这样的问题，一个是外连接消除，一个是空字符串到底算不算 NULL。前者排第一，因为老系统里到处都是 &lt;code&gt;(+)&lt;/code&gt; 写法的历史 SQL，谁都说不清当初是不是故意要保留左表全量；后者第二，因为它牵扯到&quot;KES 跟 Oracle 到底像不像&quot;这个问题本身没有固定答案，得看配置。环境是 &lt;code&gt;KES V009R001C010&lt;/code&gt;，业务账号连接：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;ksql -h 127.0.0.1 -p 54321 -U app_user -d app_db
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;先搭场景：客户表和客户等级表&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;table&lt;/span&gt; app_schema.t_mig_customer (
  cust_id &lt;span class=&quot;hljs-type&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;primary&lt;/span&gt; key,
  cust_name &lt;span class=&quot;hljs-type&quot;&gt;varchar&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;50&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;,
  grade_code &lt;span class=&quot;hljs-type&quot;&gt;varchar&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt;)
);

&lt;span class=&quot;hljs-keyword&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;table&lt;/span&gt; app_schema.t_mig_grade (
  grade_code &lt;span class=&quot;hljs-type&quot;&gt;varchar&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;primary&lt;/span&gt; key,
  grade_name &lt;span class=&quot;hljs-type&quot;&gt;varchar&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;,
  grade_level &lt;span class=&quot;hljs-type&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;
);

&lt;span class=&quot;hljs-keyword&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;into&lt;/span&gt; app_schema.t_mig_customer(cust_id, cust_name, grade_code) &lt;span class=&quot;hljs-keyword&quot;&gt;values&lt;/span&gt;
  (&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;customer-a&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;G1&#39;&lt;/span&gt;),
  (&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;customer-b&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;G2&#39;&lt;/span&gt;),
  (&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;customer-c&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;),
  (&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;customer-d&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;G3&#39;&lt;/span&gt;);

&lt;span class=&quot;hljs-keyword&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;into&lt;/span&gt; app_schema.t_mig_grade(grade_code, grade_name, grade_level) &lt;span class=&quot;hljs-keyword&quot;&gt;values&lt;/span&gt;
  (&lt;span class=&quot;hljs-string&quot;&gt;&#39;G1&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;silver&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;),
  (&lt;span class=&quot;hljs-string&quot;&gt;&#39;G2&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;gold&#39;&lt;/span&gt;,   &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;customer-c&lt;/code&gt; 从来没定过级，&lt;code&gt;grade_code&lt;/code&gt; 是 NULL；&lt;code&gt;customer-d&lt;/code&gt; 的 &lt;code&gt;grade_code&lt;/code&gt; 是 &lt;code&gt;G3&lt;/code&gt;，但等级表里压根没有 G3 这一级——这是很多老系统的常态，等级表维护跟不上业务扩张，历史数据里留着一堆对不上号的外键值。查&quot;所有客户&quot;的场景下，这两个客户理论上都应该被保留，只是等级信息显示为空。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;陷阱一：&lt;code&gt;(+)&lt;/code&gt; 语法本身没毛病，加个条件就变味了&lt;/h2&gt;
&lt;p&gt;先确认 KES 对 Oracle 这个老写法的兼容程度。&lt;code&gt;(+)&lt;/code&gt; 标在哪一边，哪一边就是外连接里可以为空的一侧，最基础的写法：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt; c.cust_id, c.cust_name, g.grade_name
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer c, app_schema.t_mig_grade g
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; c.grade_code &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; g.grade_code(&lt;span class=&quot;hljs-operator&quot;&gt;+&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3bac916ee51c4864b7f576fcc3951011~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=qvQiJuUPJD27D3ZmNHmoNE4XZ24%3D&quot; alt=&quot;plus语法基础用法保留全部客户&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;四个客户全部返回，&lt;code&gt;customer-c&lt;/code&gt;、&lt;code&gt;customer-d&lt;/code&gt; 的 &lt;code&gt;grade_name&lt;/code&gt; 是空。这一步没什么好说的，&lt;code&gt;(+)&lt;/code&gt; 语法接得很到位，老代码原样搬过来完全能用，这也是 KES 主打 Oracle 兼容的地方确实兑现了。&lt;/p&gt;
&lt;p&gt;麻烦出在老系统里更常见的写法上：关联条件之外，业务上往往还要再加一层过滤，比如&quot;只看正式定级（等级值大于等于 1）的客户&quot;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt; c.cust_id, c.cust_name, g.grade_name
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer c, app_schema.t_mig_grade g
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; c.grade_code &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; g.grade_code(&lt;span class=&quot;hljs-operator&quot;&gt;+&lt;/span&gt;)
  &lt;span class=&quot;hljs-keyword&quot;&gt;and&lt;/span&gt; g.grade_level &lt;span class=&quot;hljs-operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b0fc4ad6bc9444998427d9b8516f906e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=whj5AJbfXV801xzoAkuYcr%2B5uxU%3D&quot; alt=&quot;老系统plus写法迁移后行数对比&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;只返回 2 行，&lt;code&gt;customer-a&lt;/code&gt;、&lt;code&gt;customer-b&lt;/code&gt;。&lt;code&gt;customer-c&lt;/code&gt;、&lt;code&gt;customer-d&lt;/code&gt; 不见了——这条 SQL 里明明写着 &lt;code&gt;(+)&lt;/code&gt;，摆明了想要外连接的语义，结果却只剩下内连接才会有的行数。&lt;/p&gt;
&lt;p&gt;跑一下执行计划确认这背后发生了什么：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;explain analyze
&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt; c.cust_id, c.cust_name, g.grade_name
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer c, app_schema.t_mig_grade g
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; c.grade_code &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; g.grade_code(&lt;span class=&quot;hljs-operator&quot;&gt;+&lt;/span&gt;)
  &lt;span class=&quot;hljs-keyword&quot;&gt;and&lt;/span&gt; g.grade_level &lt;span class=&quot;hljs-operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2993cac572434cd59c0c5fd582770264~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=qbX35PPvTsv5KXBQn4Dzy4%2B5D88%3D&quot; alt=&quot;执行计划确认plus写法被消除&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Hash Join&lt;/code&gt;，没有 &lt;code&gt;Left&lt;/code&gt; 或者 &lt;code&gt;Right&lt;/code&gt; 字样，纯内连接。原因不难理解：&lt;code&gt;g.grade_level &amp;gt;= 1&lt;/code&gt; 这个条件是加在右表上的，&lt;code&gt;customer-c&lt;/code&gt;、&lt;code&gt;customer-d&lt;/code&gt; 对应的 &lt;code&gt;g.grade_level&lt;/code&gt; 是 NULL，&lt;code&gt;NULL &amp;gt;= 1&lt;/code&gt; 的结果是&quot;未知&quot;，在 &lt;code&gt;WHERE&lt;/code&gt; 里等于被扔掉。既然这些因为外连接才该保留的行反正都会被这个条件滤掉，&quot;外连接 + 这个过滤&quot;和&quot;内连接 + 这个过滤&quot;结果完全一样，优化器就选了开销更小的内连接去跑——这就是外连接消除，跟 &lt;code&gt;(+)&lt;/code&gt; 写没写没关系，&lt;code&gt;(+)&lt;/code&gt; 只是外连接的一种写法，底层判断逻辑跟 ANSI 的 &lt;code&gt;LEFT JOIN&lt;/code&gt; 是同一套。&lt;/p&gt;
&lt;p&gt;为了确认这一点，把同样的逻辑换成 ANSI 写法再跑一遍，作为迁移验收阶段常用的排查方式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;explain analyze
&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt; c.cust_id, c.cust_name, g.grade_name
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer c
&lt;span class=&quot;hljs-keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;join&lt;/span&gt; app_schema.t_mig_grade g
  &lt;span class=&quot;hljs-keyword&quot;&gt;on&lt;/span&gt; c.grade_code &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; g.grade_code
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; g.grade_level &lt;span class=&quot;hljs-operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cd37b95d1ba84bbfaa6845583115f1f3~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=E%2B1YfB11C80H1k%2FLN8nK8%2BeXokc%3D&quot; alt=&quot;验收阶段执行计划审计left-join&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;同样是 &lt;code&gt;Hash Join&lt;/code&gt;，同样没有 &lt;code&gt;Left&lt;/code&gt; 字样，跟 &lt;code&gt;(+)&lt;/code&gt; 写法的表现完全一致。这也提醒做迁移验收的人：不管老系统用的是 &lt;code&gt;(+)&lt;/code&gt; 还是转译后的 &lt;code&gt;LEFT JOIN&lt;/code&gt;，只要 &lt;code&gt;WHERE&lt;/code&gt; 里对右表字段做了这种会把 NULL 判定为假的过滤，这个坑就跑不掉，光看语法转译对不对没用，得拿执行计划和行数说话。&lt;/p&gt;
&lt;p&gt;修复办法是把这个过滤条件挪进关联条件里：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt; c.cust_id, c.cust_name, g.grade_name
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer c
&lt;span class=&quot;hljs-keyword&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;join&lt;/span&gt; app_schema.t_mig_grade g
  &lt;span class=&quot;hljs-keyword&quot;&gt;on&lt;/span&gt; c.grade_code &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; g.grade_code
  &lt;span class=&quot;hljs-keyword&quot;&gt;and&lt;/span&gt; g.grade_level &lt;span class=&quot;hljs-operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2df8110236a44edfb40fdb296964d4a3~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=x5eFQ0RqIBn8kQYSOTe%2BB%2BiOuU8%3D&quot; alt=&quot;条件下推到on后行数恢复到4&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;四行全部回来，&lt;code&gt;customer-c&lt;/code&gt;、&lt;code&gt;customer-d&lt;/code&gt; 的等级字段照常显示为空。这不是换个位置随便试出来的，&lt;code&gt;ON&lt;/code&gt; 决定的是&quot;怎么连&quot;，先按条件筛一遍右表再去外连接；&lt;code&gt;WHERE&lt;/code&gt; 决定的是&quot;连完之后再筛掉什么&quot;，条件放这儿就已经是连接做完之后的事了，NULL 行躲不掉。&lt;/p&gt;
&lt;p&gt;迁移验收阶段发现这类问题没有捷径：对每一条涉及外连接的存量 SQL，迁移前后的行数必须逐条比对，光看&quot;能不能跑通&quot;是不够的。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;陷阱二：空字符串算不算 NULL，得看这一套环境怎么配置&lt;/h2&gt;
&lt;p&gt;这一节动笔之前，先把两件事确认清楚，不能凭&quot;KES 内核衍生自 PostgreSQL&quot;这种直觉去猜：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;show&lt;/span&gt; database_mode;
&lt;span class=&quot;hljs-keyword&quot;&gt;show&lt;/span&gt; ora_input_emptystr_isnull;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/729662b651704150943061cadec72932~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=vsMvu7LPUfl3bzNyo3IHrvgH%2ByU%3D&quot; alt=&quot;数据库兼容模式和空字符串参数确认&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;database_mode&lt;/code&gt; 是 &lt;code&gt;oracle&lt;/code&gt;，&lt;code&gt;ora_input_emptystr_isnull&lt;/code&gt; 是 &lt;code&gt;on&lt;/code&gt;。这套环境默认走的是 Oracle 兼容模式——很多人下意识觉得&quot;内核是 PG 系的，行为应该跟 PG 一致&quot;，这个假设在这里是不成立的，还是要先确定兼容模式，除非建库时特意指定成 PG 模式。而 &lt;code&gt;ora_input_emptystr_isnull&lt;/code&gt; 这个参数，顾名思义就是用来复刻 Oracle 那个经典行为：把长度为零的字符串当成 NULL 处理。&lt;/p&gt;
&lt;p&gt;实测验证一下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;into&lt;/span&gt; app_schema.t_mig_customer(cust_id, cust_name, grade_code)
&lt;span class=&quot;hljs-keyword&quot;&gt;values&lt;/span&gt; (&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;customer-e&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;&#39;&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-sql&quot; lang=&quot;sql&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;select&lt;/span&gt;
  cust_id, cust_name, grade_code,
  grade_code &lt;span class=&quot;hljs-keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;as&lt;/span&gt; is_null_flag,
  length(grade_code) &lt;span class=&quot;hljs-keyword&quot;&gt;as&lt;/span&gt; code_len
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; app_schema.t_mig_customer
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; cust_id &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/93b5bbf7b4f24f70bbe6593119d951a2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiA5Y-q54mb5Y2a:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784697509&amp;amp;x-signature=rcCkkEemY5TWZwTQ%2BkLh2B3%2FDPw%3D&quot; alt=&quot;插入空字符串后is-null判定结果&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;插入的空字符串 &lt;code&gt;&#39;&#39;&lt;/code&gt;，查出来 &lt;code&gt;is_null_flag&lt;/code&gt; 是 &lt;code&gt;t&lt;/code&gt;——被当成 NULL 存了，&lt;code&gt;code_len&lt;/code&gt; 也是空白，不是 &lt;code&gt;0&lt;/code&gt;。这跟很多人预想的&quot;PostgreSQL 体系不会这样&quot;正好相反，KES 在 Oracle 兼容模式下把 Oracle 这个特有行为原样复刻了下来。&lt;/p&gt;
&lt;p&gt;对迁移读者来说，这其实是个好消息：如果老系统的 PL/SQL 或者业务代码依赖了&quot;空字符串等于 NULL&quot;这个假设（比如用 &lt;code&gt;col = &#39;&#39;&lt;/code&gt; 判断&quot;未填写&quot;），只要迁移后的 KES 还在 Oracle 兼容模式下，这批代码不用改，行为跟原来一致。真正要小心的是反过来的情况——如果运维后续把数据库切换成 PG 兼容模式，或者手动关掉了这个参数，这批老代码会在没有任何报错的情况下悄悄失效。这也是这个坑最值得记住的地方：它不是一个写死的结论，是随兼容模式和参数走的，迁移评估阶段必须在目标环境里把这两项亲自确认一遍，不能凭经验预判。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;迁移避坑清单&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;对所有涉及外连接（&lt;code&gt;LEFT/RIGHT JOIN&lt;/code&gt; 或 &lt;code&gt;(+)&lt;/code&gt;）的存量 SQL 做台账登记，迁移前先跑一遍拿到基准行数。&lt;/li&gt;
&lt;li&gt;迁移后同样的 SQL 在 KES 上重跑，行数逐条比对，光凭&quot;能不能跑通&quot;判断不了对错。&lt;/li&gt;
&lt;li&gt;审查 &lt;code&gt;WHERE&lt;/code&gt; 子句里是否有对右表（Nullable 一侧）字段的过滤，且没有对称写 &lt;code&gt;(+)&lt;/code&gt; 或没有下推到 &lt;code&gt;ON&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;迁移前先确认目标环境的 &lt;code&gt;database_mode&lt;/code&gt; 和 &lt;code&gt;ora_input_emptystr_isnull&lt;/code&gt;，把&quot;空字符串算不算 NULL&quot;这件事钉死，再决定这部分代码要不要改。&lt;/li&gt;
&lt;li&gt;涉及财务、库存、审批类的判断逻辑，这两类问题都不会报错，只会悄悄改变结果，验收时间再紧也不能省这两项检查。&lt;/li&gt;
&lt;/ol&gt;</description><link>https://juejin.cn/post/7662370300848275502</link><guid isPermaLink="false">https://juejin.cn/post/7662370300848275502</guid><pubDate>Wed, 15 Jul 2026 05:18:29 GMT</pubDate><author>一只牛博</author><category>后端</category><category>数据库</category></item><item><title>Vue 和 React 真正的差距，不在语法，而在团队犯错成本</title><description>&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4582f26e46344fb694665d7cd0458ee2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784627030&amp;amp;x-signature=JJ%2FbHvkfLyh9o2FSPPS23nyN7UE%3D&quot; alt=&quot;vue-vs-react-featured-img-cd686c31-25d0-411c-8038-76558831bb73.jpg&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;前端圈的鄙视链里，一直流传着一个极其傲慢的错觉：写 &lt;code&gt;React&lt;/code&gt; 的看不起写 &lt;code&gt;Vue&lt;/code&gt; 的，认为前者更贴近底层，是真正的编程；而后者只是包了一层厚厚语法糖的玩具🫡。&lt;/p&gt;
&lt;p&gt;每年的框架之争，大家都在喋喋不休地争论 &lt;code&gt;JSX&lt;/code&gt; 是否比 &lt;code&gt;Template&lt;/code&gt; 更灵活，或者 &lt;code&gt;Hooks&lt;/code&gt; 是否比 &lt;code&gt;Composition API&lt;/code&gt; 更纯粹。&lt;/p&gt;
&lt;p&gt;但在真正带过几十人团队、给无数线上故障擦过屁股的前端架构师眼里，这些语法层面的争论，简直肤浅得不值一提🤷‍♂️。&lt;/p&gt;
&lt;p&gt;在真实的业务交付战场上，评判一个框架的核心标准从来不是 &lt;strong&gt;它能让你飞得多高&lt;/strong&gt;，而是 &lt;strong&gt;它能在别人犯蠢时，提供多厚的安全气垫&lt;/strong&gt;。&lt;code&gt;Vue&lt;/code&gt; 和 &lt;code&gt;React&lt;/code&gt; 之间那条真正不可逾越的鸿沟，其实是&lt;strong&gt;团队的犯错成本&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-0&quot;&gt;极其自由的 React&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;React&lt;/code&gt; 的核心设计哲学非常迷人：&lt;strong&gt;一切皆为函数，一切皆为 JavaScript&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这种无与伦比的自由度, 你可以随心所欲地组装高阶组件，在渲染流里玩出各种花样。&lt;/p&gt;
&lt;p&gt;但现实情况是，你手下的团队不是由十个顶级开发组成的。国内大多数业务线的现状是：开发的每一个环节都是流水线，团队里充斥着刚刚转正的新人、甚至外包同学。&lt;/p&gt;
&lt;p&gt;把 &lt;code&gt;React&lt;/code&gt; 交给这样一支水平参差不齐的团队，这种&lt;strong&gt;自由&lt;/strong&gt;瞬间就会变成灾难。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;React&lt;/code&gt; 里，想要写出一个能跑的页面很容易，但想要写出一个&lt;strong&gt;不乱重渲染、没有内存泄漏&lt;/strong&gt;的页面，门槛极高。开发者必须时刻在大脑里与底层的渲染机制做斗争。你需要手动去判断什么时候该用 &lt;code&gt;useMemo&lt;/code&gt;，什么时候该套 &lt;code&gt;useCallback&lt;/code&gt;，甚至要时刻警惕那个反人类的 &lt;code&gt;useEffect&lt;/code&gt; 依赖数组😖。&lt;/p&gt;
&lt;p&gt;任何一个新手，只要少写了一个依赖，或者多传了一个匿名函数，你的页面就会陷入无限循环，或者彻底僵死在陈旧的闭包里。在 &lt;code&gt;React&lt;/code&gt; 里，犯错的门槛实在太低了，但排查错误的成本却极其高昂。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;依赖数组与自动追踪&lt;/h3&gt;
&lt;p&gt;我们来看一个在业务中每天都会上演的经典场景：根据传入的 &lt;code&gt;userId&lt;/code&gt; 去拉取数据。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;React&lt;/code&gt; 的世界里，新手极其容易写出下面这种代码：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-tsx&quot; lang=&quot;tsx&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// 表面看毫无问题的 React 代码，实则埋下了闭包陷阱&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;UserDashboard&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;{ userId }&lt;/span&gt;) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; [data, setData] = &lt;span class=&quot;hljs-title function_&quot;&gt;useState&lt;/span&gt;(&lt;span class=&quot;hljs-literal&quot;&gt;null&lt;/span&gt;);
  
  &lt;span class=&quot;hljs-comment&quot;&gt;// 容易漏写依赖，或者写错依赖导致无限循环&lt;/span&gt;
  &lt;span class=&quot;hljs-title function_&quot;&gt;useEffect&lt;/span&gt;(&lt;span class=&quot;hljs-function&quot;&gt;() =&amp;gt;&lt;/span&gt; {
    &lt;span class=&quot;hljs-title function_&quot;&gt;fetchData&lt;/span&gt;(userId).&lt;span class=&quot;hljs-title function_&quot;&gt;then&lt;/span&gt;(setData);
  }, []); &lt;span class=&quot;hljs-comment&quot;&gt;// 漏掉了 userId，导致父组件切换用户时，这里的数据永远不更新&lt;/span&gt;
  
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; (
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;Header&lt;/span&gt; /&amp;gt;&lt;/span&gt; {/* 父组件状态一变，这个毫无关系的 Header 跟着白白重渲染 */}
      &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;UserProfile&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;data&lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt;{data}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为了修补这些漏洞，你不得不强制团队去配置 &lt;code&gt;ESLint&lt;/code&gt; 插件，甚至在 &lt;code&gt;Code Review&lt;/code&gt; 时拿着放大镜去查依赖数组。这就是极其高昂的&lt;strong&gt;心智负担&lt;/strong&gt;😒。&lt;/p&gt;
&lt;p&gt;相比之下，&lt;code&gt;Vue&lt;/code&gt; 在底层直接做了一次降维打击。它剥夺了你手动管理的自由，用底层的 &lt;code&gt;Proxy&lt;/code&gt; 代理机制接管了一切。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-html&quot; lang=&quot;html&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!-- Vue 用底层的依赖追踪，帮你兜底了绝大多数的心智负担 --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;template&lt;/span&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;Header&lt;/span&gt; /&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;&amp;lt;!-- Vue 的细粒度更新，保证了 data 变化绝对不会波及 Header --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;UserProfile&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;:data&lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt;&quot;data&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;template&lt;/span&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;setup&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;lang&lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt;&quot;ts&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; { ref, watchEffect } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&#39;vue&#39;&lt;/span&gt;;

&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; props = defineProps&amp;lt;{ &lt;span class=&quot;hljs-attr&quot;&gt;userId&lt;/span&gt;: string }&amp;gt;();
&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; data = &lt;span class=&quot;hljs-title function_&quot;&gt;ref&lt;/span&gt;(&lt;span class=&quot;hljs-literal&quot;&gt;null&lt;/span&gt;);

&lt;span class=&quot;hljs-comment&quot;&gt;// 框架自动收集底层的依赖，根本不需要你手动去维护那个反人类的依赖数组&lt;/span&gt;
&lt;span class=&quot;hljs-title function_&quot;&gt;watchEffect&lt;/span&gt;(&lt;span class=&quot;hljs-keyword&quot;&gt;async&lt;/span&gt; () =&amp;gt; {
  data.&lt;span class=&quot;hljs-property&quot;&gt;value&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;fetchData&lt;/span&gt;(props.&lt;span class=&quot;hljs-property&quot;&gt;userId&lt;/span&gt;);
});
&lt;/span&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这个场景下，&lt;code&gt;Vue&lt;/code&gt; 的开发者甚至不知道什么是闭包。框架底层的响应式系统充当了最严厉的质量检测，无论新手的水平多差，这套机制都能保证代码在及格线以上稳稳运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;React 考验的是开发者的内功，而 Vue 考验的是框架底层的工艺。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;组件重新渲染引起的问题&lt;/h3&gt;
&lt;p&gt;如果说闭包只是前端的局部阵痛，那么&lt;strong&gt;全局重复渲染&lt;/strong&gt;就是大型业务线的灾难。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1a2f78214d9d417eb283f1a428dba8ca~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784627030&amp;amp;x-signature=wpxvoOh6%2FdblxcyYKDr%2B9Id0lOc%3D&quot; alt=&quot;ChatGPT Image 2026年7月14日 17_16_09.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;React&lt;/code&gt; 的默认渲染逻辑极其粗暴：只要父组件的状态发生改变，所有子组件必须无条件跟着重新执行一遍。如果你不手动用 &lt;code&gt;React.memo&lt;/code&gt; 把组件一层层包裹起来，一个顶层的数据状态更新，能让成百上千个毫无关联的底层组件跟着陪跑。&lt;/p&gt;
&lt;p&gt;在真实的深水区业务中，当一个毫无经验的初级开发把一个高频更新的状态（比如页面的滚动位置）挂载到了顶层的 &lt;code&gt;Context&lt;/code&gt; 时，整个应用的性能就会瞬间被榨干，哪怕你用着顶级配置的电脑，页面也会卡成 &lt;code&gt;PPT&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;而在 &lt;code&gt;Vue&lt;/code&gt; 的世界里，这种页面崩溃是不存在的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Vue&lt;/code&gt; 采用了&lt;strong&gt;细粒度更新&lt;/strong&gt;的架构。通过编译时的静态分析和运行时的依赖收集，当一个状态发生改变时，&lt;code&gt;Vue&lt;/code&gt; 精确地知道这个数据只绑定在了某几个具体的 &lt;code&gt;DOM&lt;/code&gt; 节点上，只需要更新需要更新的地方即可。&lt;/p&gt;
&lt;p&gt;这就意味着，即使你的团队里有人乱写逻辑，把状态满天乱飞，&lt;code&gt;Vue&lt;/code&gt; 底层的防线依然能保证项目不至于彻底瘫痪。这就是架构层面的&lt;strong&gt;工程兜底&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;咱们必须得承认团队的平庸🫡&lt;/h3&gt;
&lt;p&gt;技术圈往往有一种慕强心理，大家都觉得越难驾驭的工具越高级。&lt;/p&gt;
&lt;p&gt;但真正的业务闭环是不认这些的。作为前端负责人，你的首要目标是保证业务按时上线，保证代码稳定运行，而不是证明你的团队个个都是 &lt;code&gt;JavaScript&lt;/code&gt; 大师😒。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;React&lt;/code&gt; 是一个非常灵活的前端框架，但稍微不慎会引起线上事故。它极度依赖严苛的团队规范和极高水平的 &lt;code&gt;Code Review&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Vue&lt;/code&gt; 则是自带防误系统的。它虽然限制了你的语法写法，甚至有些语法看起来像是在写配置，但它把团队的&lt;strong&gt;下限&lt;/strong&gt;拉到了一个极高的位置🙌。&lt;/p&gt;
&lt;p&gt;如果你带领的是一支精英小队，去挑战极限的交互体验，&lt;code&gt;React&lt;/code&gt; 绝对是不二之选。但如果你的团队成员水平参差不齐，且面临着高压的业务迭代，拥抱 &lt;code&gt;Vue&lt;/code&gt; 是你的首选🫵。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;框架从来没有好坏，适合你团队的才是最好的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你们怎么看？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f0675ad08a164f42b6251e3df6268608~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784627030&amp;amp;x-signature=Mklgg4St%2Bxzg2x0h5bSIOq6lkgE%3D&quot; alt=&quot;Suggestion.gif&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;</description><link>https://juejin.cn/post/7661802823036338214</link><guid isPermaLink="false">https://juejin.cn/post/7661802823036338214</guid><pubDate>Tue, 14 Jul 2026 09:39:25 GMT</pubDate><author>ErpanOmer</author><category>前端</category><category>JavaScript</category><category>程序员</category></item><item><title>Codex 小白入门：从安装到插件、MCP、Skills，一篇把配置讲明白</title><description>&lt;h2 data-id=&quot;heading-0&quot;&gt;Codex 小白入门：从安装到插件、MCP、Skills，一篇把配置讲明白&lt;/h2&gt;
&lt;p&gt;最近老粉丝群里有不少同学一直催我：能不能出一篇 Codex 的基础教程，不要只讲“很强”“很好用”，而是把安装、配置、插件、Skills、MCP、记忆、连接 App 这些东西一次讲清楚。我理解这个需求。&lt;/p&gt;
&lt;p&gt;我这边也有一些AI Coding（SDD Agent AI工具等） 和 Node技术交流交流群，感兴趣的可以加微信&amp;nbsp;&lt;strong&gt;ikoala520&lt;/strong&gt;&amp;nbsp; 进群，一起学习，共同进步。&lt;/p&gt;
&lt;p&gt;因为新手用 Codex 最大的问题，往往不是不会提问，而是不知道 Codex 的“几层配置”分别管什么。你可能已经装好了 Codex，也能让它改代码、写文章、解释报错，但一看到 &lt;code&gt;config.toml&lt;/code&gt;、&lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;MCP&lt;/code&gt;、&lt;code&gt;Plugins&lt;/code&gt;、&lt;code&gt;Skills&lt;/code&gt;、&lt;code&gt;Memory&lt;/code&gt;，脑子里马上变成一团线。这篇文章就解决这件事。&lt;/p&gt;
&lt;p&gt;我不会把它写成官方文档翻译，也不会一上来堆一堆参数。我们按一个小白真正上手的顺序来：先装起来，再让 Codex 懂你的项目，然后一点点接上插件、MCP、Skills、记忆和 App。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/30e3057534f5437b89b6b9c5aaa6dc6d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=NeEIgrEzdAAbV01HKQxhrQRrI9M%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
先说明一下：Codex 更新很快。本文写作时，我本机验证的 CLI 版本是 &lt;code&gt;codex-cli 0.140.0-alpha.2&lt;/code&gt;，时间是 2026 年 6 月 14 日。具体命令以你本机的 &lt;code&gt;codex --help&lt;/code&gt; 和官方文档为准。本文重点讲方法和配置思路，命令只是帮你建立第一套可运行的骨架。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;你先记住一句话&lt;/h3&gt;
&lt;p&gt;Codex 不是只有一个聊天框。&lt;/p&gt;
&lt;p&gt;更准确地说，它像一个可以被你配置的工作台：&lt;/p&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;你要解决的问题&lt;/th&gt;&lt;th&gt;应该放在哪里&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;这一次任务的要求&lt;/td&gt;&lt;td&gt;当前对话 / prompt&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;这个项目长期遵守的规则&lt;/td&gt;&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;你的全局默认设置&lt;/td&gt;&lt;td&gt;&lt;code&gt;~/.codex/config.toml&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;某类任务的标准流程&lt;/td&gt;&lt;td&gt;&lt;code&gt;Skills&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;一组打包好的能力&lt;/td&gt;&lt;td&gt;&lt;code&gt;Plugins&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;外部系统和工具接口&lt;/td&gt;&lt;td&gt;&lt;code&gt;MCP servers&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;你的长期偏好&lt;/td&gt;&lt;td&gt;&lt;code&gt;Memory&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Gmail、GitHub、Chrome 这类真实应用&lt;/td&gt;&lt;td&gt;&lt;code&gt;Apps / Connectors&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/47fa6f782f12497abbdb40e8a210818a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=rZxx1hdMEZt0rHI8334luCTbD1Q%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
很多新手一开始容易犯的错，是把所有东西都塞进 prompt。&lt;/p&gt;
&lt;p&gt;比如你每次都对 Codex 说：“请先阅读项目结构，遵守我们的代码规范，运行测试，不要乱改文件，写完给我总结。”&lt;/p&gt;
&lt;p&gt;这当然能用，但很累。更好的方式是把长期规则沉淀到 &lt;code&gt;AGENTS.md&lt;/code&gt;，把默认行为放到 &lt;code&gt;config.toml&lt;/code&gt;，把重复工作流写成 &lt;code&gt;Skill&lt;/code&gt;，把外部能力交给 &lt;code&gt;MCP&lt;/code&gt; 和插件。&lt;/p&gt;
&lt;p&gt;这样 Codex 才会从“一个会回答问题的窗口”，变成“一个适合你工作流的助手”。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;第一步：先把 Codex 装起来&lt;/h3&gt;
&lt;p&gt;Codex 现在有几种常见使用方式。&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;入口&lt;/th&gt;&lt;th&gt;更适合谁&lt;/th&gt;&lt;th&gt;你可以怎么理解&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Codex CLI&lt;/td&gt;&lt;td&gt;程序员、经常在终端工作的人&lt;/td&gt;&lt;td&gt;在项目目录里直接让 Codex 读代码、改代码、跑命令&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Codex Desktop App&lt;/td&gt;&lt;td&gt;想用图形界面、插件、连接 App 的人&lt;/td&gt;&lt;td&gt;更像一个完整工作台&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IDE 扩展&lt;/td&gt;&lt;td&gt;长时间待在编辑器里的人&lt;/td&gt;&lt;td&gt;让 Codex 跟你的代码编辑环境贴近&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cloud / Web 任务&lt;/td&gt;&lt;td&gt;想把任务交给云端跑的人&lt;/td&gt;&lt;td&gt;适合并行处理或长任务&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;如果你是小白，我建议从 &lt;strong&gt;Codex Desktop App + CLI&lt;/strong&gt; 这套组合开始。桌面 App 适合看插件、连接 App、管理线程；CLI 适合进入具体项目干活。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-3&quot;&gt;1. Codex Desktop App 怎么安装&lt;/h4&gt;
&lt;p&gt;桌面 App 的官方入口是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;https://developers.openai.com/codex/app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你想直接下载安装包，也可以按系统选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;macOS Apple Silicon：下载 &lt;code&gt;Codex.dmg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;macOS Intel：下载 &lt;code&gt;Codex-latest-x64.dmg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Windows：通过 Microsoft App Installer 安装&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对应直达地址如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;macOS Apple Silicon:
https://persistent.oaistatic.com/codex-app-prod/Codex.dmg

macOS Intel:
https://persistent.oaistatic.com/codex-app-prod/Codex-latest-x64.dmg

Windows:
https://get.microsoft.com/installer/download/9PLM9XGG6VKS?cid=website_cta_psi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;macOS 安装步骤很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先确认自己的芯片类型。点左上角苹果图标，选择“关于本机”，看芯片是 Apple Silicon 还是 Intel。&lt;/li&gt;
&lt;li&gt;下载对应的 &lt;code&gt;.dmg&lt;/code&gt; 文件。&lt;/li&gt;
&lt;li&gt;双击打开安装包，把 Codex 拖到 Applications / 应用程序。&lt;/li&gt;
&lt;li&gt;打开 Codex App，按提示登录 OpenAI 账号。&lt;/li&gt;
&lt;li&gt;如果 macOS 提示安全确认，在系统设置里允许打开。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Windows 安装步骤也类似：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开 Windows 下载地址。&lt;/li&gt;
&lt;li&gt;按 Microsoft Store / App Installer 的提示安装。&lt;/li&gt;
&lt;li&gt;安装完成后启动 Codex。&lt;/li&gt;
&lt;li&gt;登录 OpenAI 账号。&lt;/li&gt;
&lt;li&gt;在 App 里检查插件、连接器和本地工作区权限。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你已经装了 CLI，也可以在终端里运行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令会启动 Codex Desktop App。如果本机还没装 App，它会引导你去安装。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-4&quot;&gt;2. Codex CLI 怎么安装&lt;/h4&gt;
&lt;p&gt;CLI 的官方入口是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;https://developers.openai.com/codex/cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在更推荐用官方 standalone installer。macOS / Linux 可以这样安装：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;curl -fsSL https://chatgpt.com/codex/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Windows PowerShell 可以这样安装：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-powershell&quot; lang=&quot;powershell&quot;&gt;irm https://chatgpt.com/codex/install.ps1 | iex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你习惯用包管理器，也可以选下面几种方式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# npm&lt;/span&gt;
npm install -g @openai/codex

&lt;span class=&quot;hljs-comment&quot;&gt;# Homebrew&lt;/span&gt;
brew install --cask codex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你想手动下载二进制文件，可以去 GitHub Releases：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;https://github.com/openai/codex/releases
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;装好 CLI 以后，先跑这几个命令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex --version
codex login
codex doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;codex login&lt;/code&gt; 用来登录账号。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;codex doctor&lt;/code&gt; 用来检查本地安装、配置、认证和运行时健康状态。新手遇到“为什么不能用”“为什么工具不生效”“为什么 MCP 连接不上”时，先跑它，比直接猜原因靠谱。&lt;/p&gt;
&lt;p&gt;你还可以看完整命令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我本机看到的常用命令包括：&lt;/p&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;命令&lt;/th&gt;&lt;th&gt;用途&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex&lt;/code&gt;&lt;/td&gt;&lt;td&gt;启动交互式 CLI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex exec&lt;/code&gt;&lt;/td&gt;&lt;td&gt;非交互执行一次任务&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex review&lt;/code&gt;&lt;/td&gt;&lt;td&gt;做代码审查&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex login&lt;/code&gt; / &lt;code&gt;logout&lt;/code&gt;&lt;/td&gt;&lt;td&gt;管理登录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex doctor&lt;/code&gt;&lt;/td&gt;&lt;td&gt;诊断环境&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex mcp&lt;/code&gt;&lt;/td&gt;&lt;td&gt;管理 MCP server&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex plugin&lt;/code&gt;&lt;/td&gt;&lt;td&gt;管理插件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex app&lt;/code&gt;&lt;/td&gt;&lt;td&gt;启动桌面 App&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;codex update&lt;/code&gt;&lt;/td&gt;&lt;td&gt;更新 Codex&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;你不用一开始全记住。小白阶段只要记住：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex
codex login
codex doctor
codex --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;够用了。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;第二步：理解 &lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;如果只能先学一个配置文件，我建议先学 &lt;code&gt;AGENTS.md&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;它的作用很简单：告诉 Codex，这个项目该怎么工作。&lt;/p&gt;
&lt;p&gt;比如项目怎么启动、怎么测试、代码风格是什么、哪些目录不要乱动、提交前要跑什么命令、回答时要注意什么。你可以把它理解成“写给 AI 同事看的项目说明书”。&lt;/p&gt;
&lt;p&gt;一个最小版本可以这样写：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-markdown&quot; lang=&quot;markdown&quot;&gt;&lt;span class=&quot;hljs-section&quot;&gt;# AGENTS.md&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Project overview&lt;/span&gt;

This is a Next.js project. The main app is in &lt;span class=&quot;hljs-code&quot;&gt;`apps/web`&lt;/span&gt;.

&lt;span class=&quot;hljs-section&quot;&gt;## Common commands&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Install dependencies: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm install`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Start dev server: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm dev`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Run typecheck: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm typecheck`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Run tests: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm test`&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Coding rules&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Follow existing file structure and naming style.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Prefer small, focused changes.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Do not rewrite unrelated files.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Do not add new dependencies unless necessary.

&lt;span class=&quot;hljs-section&quot;&gt;## Verification&lt;/span&gt;

Before saying the task is complete, run the relevant check:

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; UI changes: run &lt;span class=&quot;hljs-code&quot;&gt;`pnpm typecheck`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Logic changes: run related tests
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Large changes: run &lt;span class=&quot;hljs-code&quot;&gt;`pnpm test`&lt;/span&gt;

If a command was not run, say it clearly.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里最关键的不是写得多，而是写得准。&lt;/p&gt;
&lt;p&gt;我建议你在 &lt;code&gt;AGENTS.md&lt;/code&gt; 里优先放四类内容：&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;内容&lt;/th&gt;&lt;th&gt;示例&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;项目结构&lt;/td&gt;&lt;td&gt;前端在哪里、后端在哪里、配置在哪里&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;常用命令&lt;/td&gt;&lt;td&gt;安装、启动、测试、构建&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;编码约束&lt;/td&gt;&lt;td&gt;不要改哪些文件、用什么风格、怎么命名&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;验收方式&lt;/td&gt;&lt;td&gt;什么情况下跑类型检查，什么情况下跑测试&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;有的小伙伴可能会问：这些东西为什么不直接写在 prompt 里？&lt;/p&gt;
&lt;p&gt;因为 prompt 是临时的，&lt;code&gt;AGENTS.md&lt;/code&gt; 是长期的。你今天让 Codex 改登录，明天让它改列表，后天让它写测试，这些任务都应该遵守同一套项目规矩。把规矩写进 &lt;code&gt;AGENTS.md&lt;/code&gt;，后面就不用每次重复念一遍。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;第三步：理解 &lt;code&gt;config.toml&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AGENTS.md&lt;/code&gt; 管“项目规矩”，&lt;code&gt;config.toml&lt;/code&gt; 管“Codex 自己怎么运行”。&lt;/p&gt;
&lt;p&gt;最常见的位置是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-text&quot; lang=&quot;text&quot;&gt;~/.codex/config.toml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它通常用来配置模型、沙箱、审批策略、MCP、profile、环境变量策略等内容。&lt;/p&gt;
&lt;p&gt;你也可以临时覆盖配置。比如 CLI 帮助里可以看到这种写法：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex -c model=\&quot;o3\&quot;
codex -c &lt;span class=&quot;hljs-string&quot;&gt;&#39;sandbox_permissions=[\&quot;disk-full-read-access\&quot;]&#39;&lt;/span&gt;
codex -c shell_environment_policy.inherit=all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这说明一个重要思路：&lt;code&gt;config.toml&lt;/code&gt; 是长期默认值，&lt;code&gt;-c&lt;/code&gt; 是本次临时覆盖。&lt;/p&gt;
&lt;p&gt;小白阶段，不建议一上来改很多。你可以先理解这几个配置方向：&lt;/p&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;配置方向&lt;/th&gt;&lt;th&gt;你应该怎么理解&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;model&lt;/td&gt;&lt;td&gt;默认使用哪个模型&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sandbox&lt;/td&gt;&lt;td&gt;Codex 跑命令时能访问哪些文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;approval&lt;/td&gt;&lt;td&gt;哪些操作需要你确认&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;MCP&lt;/td&gt;&lt;td&gt;外部工具怎么接进来&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;profiles&lt;/td&gt;&lt;td&gt;给不同场景准备不同配置&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;features&lt;/td&gt;&lt;td&gt;开启或关闭某些实验能力&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;举个偏保守的理解方式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-toml&quot; lang=&quot;toml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# ~/.codex/config.toml&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# 示例：按你账号和当前 Codex 版本可用模型调整&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;model&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;o3&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# 新手建议不要急着开到最高权限。&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# 真正需要全权限时，再在可信项目里单独开启。&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;sandbox_mode&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;workspace-write&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# 是否需要人工确认，取决于你的使用场景。&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# 日常交互可以保守一点，自动化脚本可以更明确地限制。&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;approval_policy&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;on-request&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不同版本字段可能会有变化。如果你打开后发现字段名不一样，不要慌，先看：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
codex doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以及你当前 Codex 版本对应的官方文档。&lt;/p&gt;
&lt;p&gt;这里有一个很实用的经验：&lt;strong&gt;别把新手配置成 &lt;code&gt;danger-full-access&lt;/code&gt; 起步。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;danger-full-access&lt;/code&gt; 很强，但也意味着 Codex 执行命令时拥有非常大的文件系统权限。它适合你非常信任当前工作区、并且知道自己在做什么的场景。刚开始用的时候，先用较保守的沙箱和审批策略，熟悉之后再逐步放开。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;第四步：Plugins 是什么&lt;/h3&gt;
&lt;p&gt;很多人听到插件，以为就是“多一个按钮”。&lt;/p&gt;
&lt;p&gt;在 Codex 里，插件更像一个能力包。一个插件里可能包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个或多个 &lt;code&gt;Skills&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MCP server 配置&lt;/li&gt;
&lt;li&gt;App / Connector 能力&lt;/li&gt;
&lt;li&gt;脚本、资源、模板&lt;/li&gt;
&lt;li&gt;插件自己的说明和元数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以用命令查看插件相关能力：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex plugin --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常见子命令包括：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex plugin list
codex plugin add &amp;lt;plugin&amp;gt;
codex plugin remove &amp;lt;plugin&amp;gt;
codex plugin marketplace list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装插件时，命令形态大概是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex plugin add sample@debug
codex plugin add sample --marketplace debug
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你使用桌面 App，也可以在插件入口里搜索、安装、启用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a576ba3bd4f74d7b873d50c9c68beb8c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=w2GTIiw7juX5xhTpsiqC2GfIxxU%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
小白阶段，我不建议你一口气装一堆插件。你可以按工作流选：&lt;/p&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;你的场景&lt;/th&gt;&lt;th&gt;优先考虑&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;写代码、看 PR&lt;/td&gt;&lt;td&gt;GitHub、Browser、Chrome&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;写文章、报告&lt;/td&gt;&lt;td&gt;Documents、Browser、Data Analytics&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;做 PPT&lt;/td&gt;&lt;td&gt;Presentations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;处理表格&lt;/td&gt;&lt;td&gt;Spreadsheets&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;做产品和界面&lt;/td&gt;&lt;td&gt;Product Design、Figma、Browser&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;操作网页或桌面&lt;/td&gt;&lt;td&gt;Chrome、Computer Use&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;插件的价值，不是“看起来很高级”，而是让 Codex 能接触真实材料、调用真实工具、交付真实文件。&lt;/p&gt;
&lt;p&gt;比如你装了 GitHub 相关插件后，它不只是告诉你“应该怎么 review”，而是可以读取 PR、看评论、查 CI、给出修改建议。你装了 Presentations，它不只是写 PPT 文案，而是能生成真正的演示稿文件。&lt;/p&gt;
&lt;p&gt;这就是插件和普通 prompt 的差别。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-8&quot;&gt;第五步：Skills 是什么&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Skills&lt;/code&gt; 很适合小白理解成：把一套固定做事方法写成文件。&lt;/p&gt;
&lt;p&gt;比如你经常写公众号文章，每次都要经历：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;定选题&lt;/li&gt;
&lt;li&gt;查资料&lt;/li&gt;
&lt;li&gt;搭大纲&lt;/li&gt;
&lt;li&gt;写初稿&lt;/li&gt;
&lt;li&gt;做配图&lt;/li&gt;
&lt;li&gt;预览&lt;/li&gt;
&lt;li&gt;改节奏&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果每次都在 prompt 里说一遍，很麻烦。你可以把这套流程写成一个 &lt;code&gt;SKILL.md&lt;/code&gt;，以后只要任务匹配，Codex 就能按这个方法走。&lt;/p&gt;
&lt;p&gt;Codex 的Skills 的位置在 ，注意是在这里&lt;code&gt;~/.codex/skills&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4f15045924ce4dce8d79f2026b99d663~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=CV9YQNi8ySKcFPV4JBBVOAEXf0M%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
一个 Skill 通常长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-markdown&quot; lang=&quot;markdown&quot;&gt;---
name: ai-article-writer
&lt;span class=&quot;hljs-section&quot;&gt;description: Use when writing long-form AI technical articles.
---&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;# AI Article Writer&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Workflow&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;1.&lt;/span&gt; Clarify the target reader and article angle.
&lt;span class=&quot;hljs-bullet&quot;&gt;2.&lt;/span&gt; Collect reliable references.
&lt;span class=&quot;hljs-bullet&quot;&gt;3.&lt;/span&gt; Propose title options and outline.
&lt;span class=&quot;hljs-bullet&quot;&gt;4.&lt;/span&gt; Draft the article in Markdown.
&lt;span class=&quot;hljs-bullet&quot;&gt;5.&lt;/span&gt; Add diagrams when useful.
&lt;span class=&quot;hljs-bullet&quot;&gt;6.&lt;/span&gt; Render a local preview.
&lt;span class=&quot;hljs-bullet&quot;&gt;7.&lt;/span&gt; Review readability before final delivery.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意，&lt;code&gt;Skill&lt;/code&gt; 不是单纯的 prompt 模板。&lt;/p&gt;
&lt;p&gt;它更像一套“操作规程”。好的 Skill 会告诉 Codex：&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;要素&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;什么时候使用&lt;/td&gt;&lt;td&gt;&lt;code&gt;description&lt;/code&gt; 写清楚触发场景&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;怎么做&lt;/td&gt;&lt;td&gt;明确步骤&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;用哪些资料&lt;/td&gt;&lt;td&gt;引用相关参考文件&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;用哪些脚本&lt;/td&gt;&lt;td&gt;复用已有脚本，而不是每次重写&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;怎么验收&lt;/td&gt;&lt;td&gt;最后检查什么&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;那 &lt;code&gt;Skill&lt;/code&gt; 和 &lt;code&gt;AGENTS.md&lt;/code&gt; 有什么区别？&lt;/p&gt;
&lt;p&gt;很简单：&lt;/p&gt;

















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;文件&lt;/th&gt;&lt;th&gt;适合放什么&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;这个项目长期遵守的规则&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;某一类任务的标准做法&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;比如“这个项目用 &lt;code&gt;pnpm&lt;/code&gt;，不要用 &lt;code&gt;npm&lt;/code&gt;”，应该放 &lt;code&gt;AGENTS.md&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;比如“写公众号文章前必须先做选题定位，再写大纲”，应该放 &lt;code&gt;Skill&lt;/code&gt;。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-9&quot;&gt;第六步：MCP 是什么&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;MCP&lt;/code&gt; 全称是 Model Context Protocol。你可以先不用记英文，只要记住它解决的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;让 Codex 通过标准协议连接外部工具和数据源。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;

































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;MCP 能连接什么&lt;/th&gt;&lt;th&gt;典型用途&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;GitHub&lt;/td&gt;&lt;td&gt;读取 PR、Issue、文件、CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;数据库&lt;/td&gt;&lt;td&gt;查询业务数据&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;文档系统&lt;/td&gt;&lt;td&gt;读取团队知识库&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;浏览器&lt;/td&gt;&lt;td&gt;打开页面、检查 UI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;搜索服务&lt;/td&gt;&lt;td&gt;查找外部资料&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;内部系统&lt;/td&gt;&lt;td&gt;调用你们自己的工具&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;在 CLI 里可以用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我本机看到的常用子命令包括：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp list
codex mcp get &amp;lt;name&amp;gt;
codex mcp add &amp;lt;name&amp;gt; --url &amp;lt;url&amp;gt;
codex mcp add &amp;lt;name&amp;gt; -- &amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;command&lt;/span&gt;&amp;gt;
codex mcp remove &amp;lt;name&amp;gt;
codex mcp login &amp;lt;name&amp;gt;
codex mcp &lt;span class=&quot;hljs-built_in&quot;&gt;logout&lt;/span&gt; &amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加 MCP server 有两种常见方式。&lt;/p&gt;
&lt;p&gt;第一种是 HTTP 方式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二种是本地命令方式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp add my-tool -- node server.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果需要环境变量，也可以看到类似这种形式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp add my-tool --&lt;span class=&quot;hljs-built_in&quot;&gt;env&lt;/span&gt; API_KEY=&lt;span class=&quot;hljs-variable&quot;&gt;$MY_TOOL_API_KEY&lt;/span&gt; -- node server.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际使用时，不建议把真实密钥直接写在命令里。更好的方式是放在环境变量中，或者使用 Codex / MCP 支持的安全配置方式。&lt;/p&gt;
&lt;p&gt;如果以上cli你都不喜欢，也可以通过codex桌面端安装和使用mcp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/730cecc293c3465ea444d682ba93da25~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=PxMAPl3Wub7oE4T7alc9jEX%2FvFA%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;小白理解 MCP，可以抓住一个判断标准：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;凡是 Codex 需要读取外部系统、调用外部工具、访问实时数据，就优先想 MCP 或 App Connector。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不要让模型凭记忆回答你的私有数据。&lt;/p&gt;
&lt;p&gt;比如你问：“我们项目最近哪个 PR 没过 CI？”&lt;/p&gt;
&lt;p&gt;这类问题不应该让 Codex 猜，也不应该让你复制粘贴一堆网页内容。更合理的方式是接 GitHub，然后让 Codex 直接读取真实 PR 和检查结果。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-10&quot;&gt;第七步：Memory 记忆功能怎么用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Memory&lt;/code&gt; 很容易被误解。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/41780017a8844bfb81f902dd51610bf0~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=fbMaqZbQJBek%2FpLXW6SF7q1nt9M%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
它不是让 Codex 记住所有事实，也不是你的私人数据库。它更适合记住长期偏好和稳定习惯。&lt;/p&gt;
&lt;p&gt;适合放进 Memory 的内容：&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;适合记&lt;/th&gt;&lt;th&gt;示例&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;写作偏好&lt;/td&gt;&lt;td&gt;我喜欢中文技术文章，风格实战、少空话&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;常用工作方式&lt;/td&gt;&lt;td&gt;修改代码后要跑 typecheck&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;长期称呼偏好&lt;/td&gt;&lt;td&gt;回答我时用中文&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;稳定背景&lt;/td&gt;&lt;td&gt;我经常写公众号 AI 工具文章&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;不适合放进 Memory 的内容：&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;不适合记&lt;/th&gt;&lt;th&gt;原因&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;密码、token、密钥&lt;/td&gt;&lt;td&gt;安全风险太高&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;今天的新闻&lt;/td&gt;&lt;td&gt;很快过期&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;某个 PR 当前状态&lt;/td&gt;&lt;td&gt;应该从 GitHub 实时读取&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;临时任务要求&lt;/td&gt;&lt;td&gt;放当前对话就够了&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;一句话：&lt;strong&gt;Memory 记偏好，不记事实；记习惯，不记机密。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你希望 Codex 长期记住“我写文章喜欢实战风格”，放 Memory 很合适。&lt;/p&gt;
&lt;p&gt;如果你希望 Codex 知道“这个项目怎么启动”，放 &lt;code&gt;AGENTS.md&lt;/code&gt; 更合适。&lt;/p&gt;
&lt;p&gt;如果你希望 Codex 知道“GitHub 上这个 PR 当前是否通过 CI”，那应该接 GitHub App 或 MCP。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-11&quot;&gt;第八步：怎么连接 App，让 Codex 真正操作起来&lt;/h3&gt;
&lt;p&gt;Codex 的强大，不只是能写答案，而是能连接真实工具。&lt;/p&gt;
&lt;p&gt;常见 App / Connector 包括：&lt;/p&gt;





































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;App / Connector&lt;/th&gt;&lt;th&gt;能做什么&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;GitHub&lt;/td&gt;&lt;td&gt;读仓库、看 PR、查 Issue、处理 review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Gmail&lt;/td&gt;&lt;td&gt;搜索邮件、总结线程、提取待办、起草回复&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Google Drive / Docs&lt;/td&gt;&lt;td&gt;读取文档、整理资料&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Figma&lt;/td&gt;&lt;td&gt;读取设计稿、辅助设计到代码&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Browser&lt;/td&gt;&lt;td&gt;打开网页、测试本地页面、截图验收&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chrome&lt;/td&gt;&lt;td&gt;使用你的 Chrome 登录状态操作网页&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Computer Use&lt;/td&gt;&lt;td&gt;操作本地桌面应用&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这里要分清楚两个概念：&lt;/p&gt;

















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;类型&lt;/th&gt;&lt;th&gt;更像什么&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;MCP&lt;/td&gt;&lt;td&gt;标准协议接口，适合工具和数据源&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;App / Connector&lt;/td&gt;&lt;td&gt;已授权的真实应用连接&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;举个例子，你要让 Codex 看 GitHub PR，有几种可能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过 GitHub 插件&lt;/li&gt;
&lt;li&gt;通过 GitHub App / Connector&lt;/li&gt;
&lt;li&gt;通过 MCP server&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;gh&lt;/code&gt; CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它们不是互斥的。实际工作中，Codex 往往会优先使用当前环境里已经可用、权限合适、最稳定的入口。&lt;/p&gt;
&lt;p&gt;小白阶段，你只要记住一个安全原则：&lt;strong&gt;读取可以更自动，写入必须谨慎。&lt;/strong&gt; 比如读取 PR、总结邮件、打开网页，一般风险较低。&lt;/p&gt;
&lt;p&gt;但发送邮件、提交表单、删除文件、发布文章、改权限、付款、发消息，这些动作一定要让 Codex 先停下来给你确认。把 AI 当成有人监督的助手，而不是完全放飞的机器人。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-12&quot;&gt;小白第一次配置，按这个顺序来&lt;/h3&gt;
&lt;p&gt;别一开始就追求“全配满”。&lt;/p&gt;
&lt;p&gt;更好的顺序是：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/21cbdb4ef36f43dca73dcddfeefd2675~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgaWtvYWxh:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784609503&amp;amp;x-signature=VVwzjRPC%2Fd2jGVjApiSMtfUhBWk%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;你可以按下面这套路线走：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装 Codex，完成登录。&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;codex doctor&lt;/code&gt;，确认环境正常。&lt;/li&gt;
&lt;li&gt;在项目根目录写一个简单的 &lt;code&gt;AGENTS.md&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;只改必要的 &lt;code&gt;config.toml&lt;/code&gt;，先别开太多高权限。&lt;/li&gt;
&lt;li&gt;先接一个最常用的插件，比如 GitHub 或 Browser。&lt;/li&gt;
&lt;li&gt;如果你经常重复某类任务，再写 Skill。&lt;/li&gt;
&lt;li&gt;需要外部数据时，再配置 MCP。&lt;/li&gt;
&lt;li&gt;最后再考虑把长期偏好放进 Memory。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这套顺序的好处是，你每一步都能验证。&lt;/p&gt;
&lt;p&gt;很多人一上来装十几个插件、配五六个 MCP、写一大堆全局规则，最后出问题时根本不知道是哪一层坏了。小白阶段最重要的不是炫技，而是能定位问题。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-13&quot;&gt;给你一套基础配置模板&lt;/h3&gt;
&lt;p&gt;下面这套模板可以作为起点，不建议无脑复制到所有项目里，但你可以按自己的项目改。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-14&quot;&gt;1. 项目根目录 &lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-markdown&quot; lang=&quot;markdown&quot;&gt;&lt;span class=&quot;hljs-section&quot;&gt;# AGENTS.md&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Project overview&lt;/span&gt;

Briefly describe what this project does and where the main code lives.

&lt;span class=&quot;hljs-section&quot;&gt;## Common commands&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Install: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm install`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Dev: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm dev`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Typecheck: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm typecheck`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Test: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm test`&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Build: &lt;span class=&quot;hljs-code&quot;&gt;`pnpm build`&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Working rules&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Read existing code before editing.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Keep changes focused on the requested task.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Do not rewrite unrelated files.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Follow existing naming and style.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Ask before adding new dependencies.

&lt;span class=&quot;hljs-section&quot;&gt;## Verification&lt;/span&gt;

Before marking work complete:

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Run the most relevant check.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; If checks cannot run, explain why.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Do not claim tests passed unless they were actually run.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-id=&quot;heading-15&quot;&gt;2. 全局 &lt;code&gt;config.toml&lt;/code&gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-toml&quot; lang=&quot;toml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# ~/.codex/config.toml&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Pick the model you normally want Codex to use.&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# 示例：按你账号和当前 Codex 版本可用模型调整&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;model&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;o3&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Conservative default for local coding work.&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;sandbox_mode&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;workspace-write&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Let Codex ask when it needs permission for sensitive operations.&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;approval_policy&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;on-request&quot;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# You can add MCP servers below when needed.&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# [mcp_servers.example]&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# command = &quot;node&quot;&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# args = [&quot;server.js&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你的 Codex 版本提示字段不识别，先不要硬改，跑：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex doctor
codex --&lt;span class=&quot;hljs-built_in&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再根据当前版本调整。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-16&quot;&gt;3. 一个最小 Skill 模板&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-markdown&quot; lang=&quot;markdown&quot;&gt;---
name: project-review
&lt;span class=&quot;hljs-section&quot;&gt;description: Use when reviewing a feature implementation before merge.
---&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;# Project Review&lt;/span&gt;

&lt;span class=&quot;hljs-section&quot;&gt;## Workflow&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;1.&lt;/span&gt; Read the requirement or issue.
&lt;span class=&quot;hljs-bullet&quot;&gt;2.&lt;/span&gt; Inspect changed files.
&lt;span class=&quot;hljs-bullet&quot;&gt;3.&lt;/span&gt; Look for bugs, regressions, missing tests, and risky assumptions.
&lt;span class=&quot;hljs-bullet&quot;&gt;4.&lt;/span&gt; Run or recommend relevant verification commands.
&lt;span class=&quot;hljs-bullet&quot;&gt;5.&lt;/span&gt; Report findings first, then summarize.

&lt;span class=&quot;hljs-section&quot;&gt;## Output&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Findings with file references.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Test gaps.
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; Suggested next steps.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-id=&quot;heading-17&quot;&gt;4. MCP 添加命令模板&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# HTTP MCP server&lt;/span&gt;
codex mcp add &amp;lt;name&amp;gt; --url &amp;lt;server-url&amp;gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Local stdio MCP server&lt;/span&gt;
codex mcp add &amp;lt;name&amp;gt; -- &amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;command&lt;/span&gt;&amp;gt; &amp;lt;args&amp;gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Check configured MCP servers&lt;/span&gt;
codex mcp list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里最重要的是 &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; 要起得清楚，比如 &lt;code&gt;github&lt;/code&gt;、&lt;code&gt;docs&lt;/code&gt;、&lt;code&gt;postgres-readonly&lt;/code&gt;，不要叫 &lt;code&gt;test1&lt;/code&gt;、&lt;code&gt;abc&lt;/code&gt;。后面排查问题时，清楚的名字会救命。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-18&quot;&gt;常见坑&lt;/h3&gt;
&lt;h4 data-id=&quot;heading-19&quot;&gt;1. 把 &lt;code&gt;AGENTS.md&lt;/code&gt; 写成散文&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;AGENTS.md&lt;/code&gt; 不是给人看的项目宣传稿，而是给 Codex 执行任务时用的操作说明。少写愿景，多写命令、约束和验收方式。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-20&quot;&gt;2. 一开始就开最高权限&lt;/h4&gt;
&lt;p&gt;新手刚开始不要追求“无确认自动跑完”。AI 工具越能操作真实系统，越要有边界。先用保守权限跑通工作流，再根据需要放开。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-21&quot;&gt;3. MCP 配好了但忘了验证&lt;/h4&gt;
&lt;p&gt;配完 MCP 后，先跑：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;codex mcp list
codex doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;能列出来只是第一步，真正任务里能不能调用，还要看认证、网络、权限和 server 本身是否正常。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-22&quot;&gt;4. 插件装太多&lt;/h4&gt;
&lt;p&gt;插件不是越多越好。你真正需要的是工作流。&lt;/p&gt;
&lt;p&gt;如果你每天都写代码，先把 GitHub、Browser 这类接好。如果你每天写文章，先把 Documents、Browser、图片生成或预览流程跑通。装一堆不用的插件，只会让你更困惑。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-23&quot;&gt;5. 把 Memory 当事实库&lt;/h4&gt;
&lt;p&gt;Memory 适合记偏好，不适合记实时事实。项目状态、PR 状态、数据库数据、新闻变化，都应该从真实来源读取。&lt;/p&gt;
&lt;h4 data-id=&quot;heading-24&quot;&gt;6. 不区分“读”和“写”&lt;/h4&gt;
&lt;p&gt;让 Codex 读取资料、总结内容、检查页面，风险通常较低。&lt;/p&gt;
&lt;p&gt;让 Codex 发送邮件、发布文章、删除文件、提交表单、改权限，风险就高很多。涉及外部副作用的动作，最好都让它先停下来确认。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-25&quot;&gt;我自己的建议&lt;/h3&gt;
&lt;p&gt;如果你刚开始用 Codex，我建议先别急着研究所有高级配置。&lt;/p&gt;
&lt;p&gt;第一周只做三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每个项目补一个 &lt;code&gt;AGENTS.md&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;学会用 &lt;code&gt;codex doctor&lt;/code&gt; 排查问题。&lt;/li&gt;
&lt;li&gt;只接一个你最需要的插件或 App。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;等你发现某个任务每周都在重复，比如写文章、review PR、整理周报、做 PPT、查数据，再把它沉淀成 Skill 或插件工作流。&lt;/p&gt;
&lt;p&gt;Codex 真正厉害的地方，不是你一次 prompt 写得多华丽，而是你能把自己的工作方式一点点沉淀下来。今天写进 &lt;code&gt;AGENTS.md&lt;/code&gt; 的项目规则，明天接上的 GitHub，后天固化成 Skill 的写作流程，都会让它越来越像你的工作台。&lt;/p&gt;
&lt;p&gt;对小白来说，最好的入门路线不是“学完所有概念再开始用”，而是先跑起来，再把反复出现的问题放到正确的位置。&lt;/p&gt;
&lt;p&gt;这篇文章你如果只记住一张图，就记住前面的七层配置地图：&lt;/p&gt;
&lt;p&gt;临时需求放对话，项目规则放 &lt;code&gt;AGENTS.md&lt;/code&gt;，运行默认值放 &lt;code&gt;config.toml&lt;/code&gt;，重复流程放 &lt;code&gt;Skills&lt;/code&gt;，外部能力交给 &lt;code&gt;Plugins&lt;/code&gt;、&lt;code&gt;MCP&lt;/code&gt; 和 &lt;code&gt;Apps&lt;/code&gt;，个人偏好再放进 &lt;code&gt;Memory&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;把这几层分清楚，Codex 就不再是一堆陌生名词，而是一套你能慢慢搭起来的 AI 工作系统。&lt;/p&gt;
&lt;p&gt;我这边也有一些AI Coding（SDD Agent AI工具等） 和 Node技术交流交流群，感兴趣的可以加我微&amp;nbsp;&lt;strong&gt;ikoala520&lt;/strong&gt;&amp;nbsp; 进群，一起学习，共同进步。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-26&quot;&gt;参考资料&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI Codex 官方文档：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fdevelopers.openai.com%2Fcodex&quot; target=&quot;_blank&quot; title=&quot;https://developers.openai.com/codex&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;developers.openai.com/codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Codex Desktop App：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fdevelopers.openai.com%2Fcodex%2Fapp&quot; target=&quot;_blank&quot; title=&quot;https://developers.openai.com/codex/app&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;developers.openai.com/codex/app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Codex CLI：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fdevelopers.openai.com%2Fcodex%2Fcli&quot; target=&quot;_blank&quot; title=&quot;https://developers.openai.com/codex/cli&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;developers.openai.com/codex/cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Codex GitHub Releases：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fopenai%2Fcodex%2Freleases&quot; target=&quot;_blank&quot; title=&quot;https://github.com/openai/codex/releases&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/openai/code…&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;npm &lt;code&gt;@openai/codex&lt;/code&gt;：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40openai%2Fcodex&quot; target=&quot;_blank&quot; title=&quot;https://www.npmjs.com/package/@openai/codex&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;www.npmjs.com/package/@op…&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Codex CLI 本机帮助：&lt;code&gt;codex --help&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Codex MCP 命令帮助：&lt;code&gt;codex mcp --help&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Codex 插件命令帮助：&lt;code&gt;codex plugin --help&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Model Context Protocol：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fmodelcontextprotocol.io&quot; target=&quot;_blank&quot; title=&quot;https://modelcontextprotocol.io&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;modelcontextprotocol.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>https://juejin.cn/post/7661983059005816858</link><guid isPermaLink="false">https://juejin.cn/post/7661983059005816858</guid><pubDate>Tue, 14 Jul 2026 04:51:43 GMT</pubDate><author>ikoala</author><category></category><category>前端</category><category>后端</category><category>JavaScript</category></item><item><title>Agent 开发 主流 skills推荐</title><description>&lt;h2 data-id=&quot;heading-0&quot;&gt;🔧 通用工程流（几乎必装）&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;1. &lt;strong&gt;Superpowers&lt;/strong&gt;（obra/superpowers）&lt;/h3&gt;
&lt;p&gt;结构化软件工程工作流框架，不是单一 Skill，而是一整套 Agent 方法论：&lt;code&gt;brainstorming → writing plans → TDD → debugging → code review → verification&lt;/code&gt;，复杂任务还能拆给子代理并行推进 。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Claude Code&lt;/span&gt;
/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace

&lt;span class=&quot;hljs-comment&quot;&gt;# 通用（Cursor/Claude Code 都支持）&lt;/span&gt;
npx skills add https://github.com/obra/superpowers -g -a cursor -a claude-code -y
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 Claude Code 用户首推这个；Cursor 用户也可以装，但同源的 &lt;code&gt;systematic-debugging&lt;/code&gt;、&lt;code&gt;test-driven-development&lt;/code&gt;不必重复装。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;2. &lt;strong&gt;spec-driven&lt;/strong&gt;（tlc-spec-driven）&lt;/h3&gt;
&lt;p&gt;项目级四阶段：&lt;code&gt;Specify&lt;/code&gt;（模糊需求→结构化规格）→ &lt;code&gt;Design&lt;/code&gt;（数据模型/API/认证）→ &lt;code&gt;Tasks&lt;/code&gt;（原子任务拆解）→ &lt;code&gt;Implement&lt;/code&gt;（逐个实现 + 验证），中间断开也能从上次位置续上 。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npx @tech-leads-club/agent-skills install -s tlc-spec-driven -a claude-code
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;3. &lt;strong&gt;内置/经典 slash 级&lt;/strong&gt;（Claude Code 自带或可单独装）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/commit&lt;/code&gt;— 按 staged changes 生成 conventional commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/create-pr&lt;/code&gt;— 读 diff 写 PR description 并推送&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/review&lt;/code&gt;— 代码审查（bug / 安全 / 风格）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/security-audit&lt;/code&gt;— 深度安全审计（OWASP Top 10 向）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/test&lt;/code&gt;— 按实现生成单测&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/architect&lt;/code&gt;— 给定需求做系统设计再动笔&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/refactor&lt;/code&gt;— 带目标的重构&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些属于&quot;每天都能用&quot;的，建议先把内置的玩熟，再考虑覆盖自定义版本。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;🎨 前端 / 设计向&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;4. &lt;strong&gt;frontend-design&lt;/strong&gt;（Anthropic 官方）&lt;/h3&gt;
&lt;p&gt;专治 AI 生成页面&quot;千篇一律&quot;的毛病——强制 bold 排版 + 非常规布局，避免 generic UI 。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;5. &lt;strong&gt;taste-skill&lt;/strong&gt;（Leonxlnx/taste-skill）&lt;/h3&gt;
&lt;p&gt;13 合集，前端向最有用的是 &lt;code&gt;design-taste-frontend&lt;/code&gt;（强制设计规范）+ &lt;code&gt;minimalist-skill&lt;/code&gt;+ &lt;code&gt;output-skill&lt;/code&gt;（强制完整可运行代码，无占位）。还有 &lt;code&gt;imagegen-frontend-web/mobile&lt;/code&gt;、&lt;code&gt;brandkit&lt;/code&gt;、&lt;code&gt;moodboard&lt;/code&gt;做视觉素材 。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npx skills add https://github.com/Leonxlnx/taste-skill
&lt;span class=&quot;hljs-comment&quot;&gt;# 或只装核心&lt;/span&gt;
npx skills add https://github.com/Leonxlnx/taste-skill --skill design-taste-frontend
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;6. &lt;strong&gt;ui-ux-pro-max&lt;/strong&gt;（nextlevelbuilder）&lt;/h3&gt;
&lt;p&gt;输入&quot;做个 SPA 落地页&quot;，它会推理行业→配色→字体→反模式提示，交付前还出检查清单（emoji 不能当图标、hover 状态要完整这类细节）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;🛡️ 安全向&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-9&quot;&gt;7. &lt;strong&gt;Anthropic Cybersecurity Skills&lt;/strong&gt;（mukul975/Anthropic-Cybersecurity-Skills）&lt;/h3&gt;
&lt;p&gt;817 个安全技能，覆盖威胁情报 / 漏洞管理 / 渗透测试 / 事件响应 / 合规审计 / 云安全 / AI 安全，每个技能映射到 MITRE ATT&amp;amp;CK、NIST CSF 2.0、D3FEND、NIST AI RMF、MITRE F3、MITRE ATLAS 六大框架 。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-csharp&quot; lang=&quot;csharp&quot;&gt;npx skills &lt;span class=&quot;hljs-keyword&quot;&gt;add&lt;/span&gt; mukul975/Anthropic-Cybersecurity-Skills
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;装完后直接对 Agent 说：&quot;按 MITRE ATT&amp;amp;CK 检测过去 7 天横向移动（T1021.001, T1570）&quot;，它会自动加载对应 SKILL.md 按步骤干。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-10&quot;&gt;8. &lt;strong&gt;Trail of Bits&lt;/strong&gt;（真实安全公司出品）&lt;/h3&gt;
&lt;p&gt;CodeQL + Semgrep + 审计工作流，Verified 级 。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-11&quot;&gt;🔬 科研向&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-12&quot;&gt;9. &lt;strong&gt;Scientific Agent Skills&lt;/strong&gt;（K-Dense-AI/scientific-agent-skills）&lt;/h3&gt;
&lt;p&gt;138 个科研技能，17 个领域（基因组学 / 药物发现 / 临床变异 / 单细胞 RNA-seq 等），直连 100+ 数据库（PubChem、ChEMBL、UniProt…），集成 70+ Python 包（RD-py、Scanpy、BioPython、OpenMM）。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npx skills add K-Dense-AI/scientific-agent-skills
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-13&quot;&gt;🔌 垂直工具向（Cursor Marketplace 为主）&lt;/h2&gt;
&lt;p&gt;这类不是 &lt;code&gt;SKILL.md&lt;/code&gt;标准包，而是 Cursor 的 Plugin / MCP 形态，但效果类似——让 Agent 懂某个垂直工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Composio&lt;/strong&gt; — 1000+ SaaS 集成（OAuth + 结构化 action），一站打通&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shopify&lt;/strong&gt; — 搜文档 + 生成校验 GraphQL / Liquid / UI 扩展&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RevenueCat / Chargebee / Airwallex&lt;/strong&gt; — 支付计费向&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ParadeDB&lt;/strong&gt; — Postgres 里做 Elastic 级搜索（BM25 / 向量）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dagster&lt;/strong&gt; — 数据编排&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Asana / Monday.com / Merge&lt;/strong&gt; — 企业协作（Jira / Salesforce / Slack 等几百种）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-14&quot;&gt;📦 安装方式速记&lt;/h2&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;载体&lt;/th&gt;&lt;th&gt;路径 / 命令&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; 内置 slash&lt;/td&gt;&lt;td&gt;&lt;code&gt;.claude/commands/*.md&lt;/code&gt;，文件名即 &lt;code&gt;/command&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; npx 装第三方&lt;/td&gt;&lt;td&gt;&lt;code&gt;npx skills add &amp;lt;repo&amp;gt;&lt;/code&gt;或 &lt;code&gt;/plugin marketplace add&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;.cursor/skills/*.md&lt;/code&gt;或 Cursor Marketplace 一键装&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;通用（跨 Agent）&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;遵循 &lt;code&gt;SKILL.md&lt;/code&gt;标准，写一次 Cursor/Claude Code/Codex/Gemini CLI 都能吃&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-15&quot;&gt;🎯 新手推荐组合&lt;/h2&gt;
&lt;p&gt;如果你是第一次装，建议这个&quot;起步包&quot;就够用：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;superpowers&lt;/strong&gt;（工程流骨架）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;spec-driven&lt;/strong&gt;（项目级需求→实现）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;frontend-design&lt;/strong&gt; 或 &lt;strong&gt;taste-skill&lt;/strong&gt;（做前端时）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/security-audit&lt;/strong&gt; 或 &lt;strong&gt;Cybersecurity Skills&lt;/strong&gt;（安全向）&lt;/li&gt;
&lt;/ol&gt;</description><link>https://juejin.cn/post/7661924217857884186</link><guid isPermaLink="false">https://juejin.cn/post/7661924217857884186</guid><pubDate>Tue, 14 Jul 2026 04:32:40 GMT</pubDate><author>Jasper_L</author><category>人工智能</category></item><item><title>我和一个德国程序员互不知道对方，却写出了完全一样的AI架构 🤯</title><description>&lt;p&gt;他32岁，在德国写npm包。我21岁，在中国找实习。我们在同一个月份，从完全不同的起点，造出了架构上完全相同的东西。这不是协同合作。这是AI界的&quot;平行发明&quot;——两个天各一方的工程师，面对同一个数学约束，得出了同一个工程答案。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;📖 事情是这样的&lt;/h2&gt;
&lt;p&gt;我在DEV.to上发了5篇技术文章，讲我如何给AI agent装&quot;规则门&quot;——用文件系统检查、退出码、正则表达式来确保agent真的在遵守规则，而不是只在聊天框里说&quot;好的我懂了&quot;然后什么都不做。&lt;/p&gt;
&lt;p&gt;然后一个叫René Zander的德国开发者在评论区甩了个链接：&lt;strong&gt;skillgate&lt;/strong&gt;，一个npm包（&lt;code&gt;@reneza/skillgate&lt;/code&gt;），做的是&lt;strong&gt;完全一样的事情&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我点进去看了。然后我愣住了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;🤝 两个人，同一个约束，同一个答案&lt;/h2&gt;
&lt;p&gt;先看架构对比：&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;设计维度&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;René的skillgate&lt;/th&gt;&lt;th align=&quot;center&quot;&gt;我的paper-validator&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;核心理念&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&quot;模型请求，框架拥有边界&quot;&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;&quot;生成和验证共享同一个分布P(token|context;θ)，所以自我验证不可靠&quot;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;检查方式&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;文件系统纯函数&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;文件系统+正则表达式+退出码&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;模型参与&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;零——模型不在检查回路中&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;零——机械门层模型不在回路中&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;门类型&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;file-exists, file-contains, absent, command, evidence, instruction-sync&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;HealthChecker, QualityGate, WriteGuard, RegenerationValidator&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;发布形式&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;npm包，生产级&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;Python模块，CLI+MCP+原生导入&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;独立收敛日期&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2026年7月&lt;/td&gt;&lt;td align=&quot;center&quot;&gt;2026年7月&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;注意：我们在&lt;strong&gt;同一个月份&lt;/strong&gt;，从&lt;strong&gt;完全不同的起点&lt;/strong&gt;（他在德国做npm包，我在中国写毕业论文），得出了&lt;strong&gt;架构上完全相同的解决方案&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这不可能只是巧合。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;💡 为什么两个人会独立发明同一个东西？&lt;/h2&gt;
&lt;p&gt;因为这个约束是&lt;strong&gt;结构性的&lt;/strong&gt;，不是风格偏好。&lt;/p&gt;
&lt;p&gt;LLM验证自己的输出，就像让考生自己批改自己的考卷——他用的还是同一个脑子里的同一套知识。没有外部标准，没有独立检查。这就是为什么&quot;自我验证&quot;在结构上就不可靠——我把这叫做&lt;strong&gt;Prose Barrier&lt;/strong&gt;（散文壁垒）。&lt;/p&gt;
&lt;p&gt;René的说法不同但意思一样：&quot;一个门只有在agent无法影响的独立进程中才可信。&quot;&lt;/p&gt;
&lt;p&gt;对于我们两个来说，数学指向同一个工程结论：&lt;strong&gt;规则必须用代码而非自然语言编写，且在模型的生成回路之外运行。&lt;/strong&gt; 如果能说服模型违反规则，那就不是规则——只是建议。&lt;/p&gt;
&lt;p&gt;这不是哲学。在我跑过的200次试验（P1-1，后面会讲）中：机械门能覆盖的地方，违规率为零。每一条都为零。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;🏗️ 哪里不同（以及为什么这很重要）&lt;/h2&gt;
&lt;p&gt;skillgate是&lt;strong&gt;生产级、静态、可发布的&lt;/strong&gt;。它做一件事且做得很好：在agent的输出上运行确定性检查。René的instruction-sync gate——跟踪CLAUDE.md、AGENTS.md和.cursor/rules之间的漂移——是我之前没想到的，我打算采用。&lt;/p&gt;
&lt;p&gt;我的系统多了四层：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-arduino&quot; lang=&quot;arduino&quot;&gt;L0 安全层      L1 机械层        L2 神经层         L3 因果层          L4 漂移层
&lt;span class=&quot;hljs-string&quot;&gt;&quot;安全输出？&quot;&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&quot;信息到了吗？&quot;&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&quot;它穿透了吗？&quot;&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&quot;格式路由注意力？&quot;&lt;/span&gt;  &lt;span class=&quot;hljs-string&quot;&gt;&quot;何时会漂移？&quot;&lt;/span&gt;
───────────────────────────────────────────────────────────────────────────────
预加工生成      文件系统检查      令牌概率指纹       格式→注意力         趋势→预测
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;完整的5层架构，skillgate覆盖L1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;🔒 &lt;strong&gt;L0 安全层&lt;/strong&gt;：预加工生成——如果模型因&quot;听起来自信&quot;而被奖励，不确定性就被压制了。一个显式的安全提示（&quot;说&#39;我不知道&#39;不会被惩罚&quot;）在生产前就改变了前提条件。&lt;/p&gt;
&lt;p&gt;✅ &lt;strong&gt;L1 机械门&lt;/strong&gt;：skillgate覆盖的层——文件系统检查、退出码、正则表达式。完全绕过Prose Barrier。不读模型写的内容，只检查文件是否存在、时间是否新、退出码是否为零。&lt;/p&gt;
&lt;p&gt;🧠 &lt;strong&gt;L2 神经门&lt;/strong&gt;：skillgate检查&lt;strong&gt;输出&lt;/strong&gt;。神经门检查&lt;strong&gt;内部处理过程&lt;/strong&gt;。如果你在决策令牌处测量约束条件是否改变了logprob分布，你能看到规则是真的改变了模型的&quot;想法&quot;，还是只改变了措辞。d=+0.578，贝叶斯因子=282,399。DeepSeek实测。&lt;/p&gt;
&lt;p&gt;🔗 &lt;strong&gt;L3 因果编码&lt;/strong&gt;：对于推理质量，三段论规则（IF-THEN-THEREFORE）和祈使规则（MUST DO）哪个更好？答案：都不是——&lt;strong&gt;散文&lt;/strong&gt;规则更好。散文的推理优势比代码规则高出恒定的~0.25 SD，且与门的状态无关。代码+门=完美合规+最浅推理。我把这叫做&quot;清单心态&quot;。&lt;/p&gt;
&lt;p&gt;🔮 &lt;strong&gt;L4 漂移预测&lt;/strong&gt;：12个特征，34个会话的基线数据。在行为退化可见之前发出警告。已构建，预测性验证待定。&lt;/p&gt;
&lt;p&gt;这些额外的层是&quot;学术上好玩&quot;还是&quot;实践上有用&quot;——还不确定。但我不会假装知道。这就是为什么我把所有内容都做成了可复现的实验，放在&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FYuhaoLin2005%2Fpaper-validator&quot; target=&quot;_blank&quot; title=&quot;https://github.com/YuhaoLin2005/paper-validator&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;paper-validator&lt;/a&gt;里——一条命令即可运行审计：&lt;code&gt;python -m paper_validator claim --claim all --trials 30&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;🔥 为什么你应该关心这件事&lt;/h2&gt;
&lt;p&gt;当两个人在不知道对方工作的情况下，独立发明了同一个东西，说明了几件事：&lt;/p&gt;
&lt;p&gt;🔥 &lt;strong&gt;问题不是虚构的。&lt;/strong&gt; AI agent确实会漂移。它们确实会跳过验证。说得天花乱坠却不行动。不是只有我一个人碰到。&lt;/p&gt;
&lt;p&gt;🔥 &lt;strong&gt;解决方案正在收敛。&lt;/strong&gt; 确定性文件系统检查，位于模型控制回路之外——这是正确的架构。不是品味问题。是工程必要性。&lt;/p&gt;
&lt;p&gt;🔥 &lt;strong&gt;整个领域仍处于早期阶段。&lt;/strong&gt; 我们仍在争论agent是否应该用&lt;code&gt;[THINK]:&lt;/code&gt;标签。五年后回头看，会觉得像争论HTML是否应该用&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;做布局一样。&lt;/p&gt;
&lt;p&gt;🔥 &lt;strong&gt;你可以直接试用。&lt;/strong&gt; skillgate是npm上的生产级代码。paper-validator是可复现的研究代码（Python stdlib + requests，没别的依赖）。如果愿意忍受不完美的边缘情况，两个都能跑。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;📬 真实情况&lt;/h2&gt;
&lt;p&gt;DEV.to上的评论区——Mike Czerwinski、Dipankar Sarkar、Max Quimby、René Zander——不是那种&quot;好文！&quot;的水评论。他们问的是&lt;strong&gt;我真没想过要测的东西&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;所以我测了。440次API调用。两次全新实验。一次假设被证明是错的。两次都教会了我一些东西。&lt;/p&gt;
&lt;p&gt;论文、数据以及全部补充分析在这里：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FYuhaoLin2005%2Fhermes-workspace&quot; target=&quot;_blank&quot; title=&quot;https://github.com/YuhaoLin2005/hermes-workspace&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/YuhaoLin200…&lt;/a&gt;。独立验证工具在这里：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FYuhaoLin2005%2Fpaper-validator&quot; target=&quot;_blank&quot; title=&quot;https://github.com/YuhaoLin2005/paper-validator&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/YuhaoLin200…&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果你也在做这个方向——确定性验证、agent漂移监控、格式工程——或者你觉得数据里有不对的地方，我真的很想听听。P1-1和P1-2实验之所以存在，就是因为Mike问了我没想过要问的问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💬 如果这个方向也是你正在做的，评论区聊聊你的方案。&lt;/strong&gt; 你是用文件系统检查还是别的思路？你的agent有没有出现过&quot;嘴上答应、实际不做&quot;的情况？留言告诉我，我也想看看大家的解法。可以的话点个赞+收藏，后续实验数据我会继续发在这边。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;50+会话的数据。13个实验。一台笔记本。我的论文指导老师是我自己的AI agent。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;👋 林宇浩 — FAFU空间信息大三，找2026暑期实习中&lt;/p&gt;</description><link>https://juejin.cn/post/7661915632607625225</link><guid isPermaLink="false">https://juejin.cn/post/7661915632607625225</guid><pubDate>Mon, 13 Jul 2026 17:31:02 GMT</pubDate><author>YuhaoLin2005</author><category>人工智能</category><category>架构</category><category>LLM</category></item><item><title>为啥说男生找对象尽量在25岁前找到？</title><description>&lt;p&gt;先说说结论，催婚的长辈是不可能讲明白为啥要 25 岁前。我替他们算一遍。&lt;/p&gt;
&lt;p&gt;把”一个男生认真考虑恋爱”的窗口期粗略设成 18~35 岁，共 17 年。&lt;/p&gt;
&lt;p&gt;代入 1960 年由数学家 Merrill Flood 提出的”秘书问题”最优解——通俗叫法是 37% 法则——你应该先只看不选前 37% 的时间，记住这段时间里遇到的最好的那个；然后从第 37% 开始，遇到第一个比之前所有人都更好的，立刻拍板。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;观察期 = 17 × 0.37 ≈ 6.3 年
拐点    = 18 + 6.3 ≈ 24.3 岁
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;24 岁以前：在收集样本、建立标准的阶段，遇到再好的也不该锁死。&lt;/li&gt;
&lt;li&gt;24.3 岁之后：进入决断窗口，遇到一个超过你过去 6 年所有人的，立刻 commit。&lt;/li&gt;
&lt;li&gt;拖到 30 岁还在挑更好的：大概率会被迫接受最后一个出场的人——也就是窗口期内的”最后一根稻草”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“25 岁前找对象”这句话翻译过来是在说：25 岁前你应该已经做完观察、开始认真挑了。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-0&quot;&gt;数学是怎么把 25 岁这个数字钉死的&lt;/h3&gt;
&lt;p&gt;为了让这件事可信，我把演算和模拟都做了一遍，数据全部来自我自己写的一个交互式模拟器：&lt;/p&gt;
&lt;p&gt;🔗 &lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fnumfeel.996.ninja%2Fpages%2Foptimal-stopping%2F&quot; target=&quot;_blank&quot; title=&quot;https://numfeel.996.ninja/pages/optimal-stopping/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;numfeel.996.ninja/pages/optim…&lt;/a&gt; （你可以直接打开亲手跑）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/58aa419c95434277aedfaed00a6e05b4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=GbNvvPUHhfiv2bIA4RoHi9qSPqI%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;第一步：把 N=17 代入公式&lt;/h3&gt;
&lt;p&gt;秘书问题最优跳过数的公式：&lt;/p&gt;
&lt;p&gt;我用 demo 里的 theoreticalOptimalR(17) 直接算了一遍：&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;参数&lt;/th&gt;&lt;th&gt;数值&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;N（窗口期年数）&lt;/td&gt;&lt;td&gt;17&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;最优跳过 r&lt;/td&gt;&lt;td&gt;6 年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;占比&lt;/td&gt;&lt;td&gt;35.3%（接近理论的 1/e ≈ 36.8%）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;对应年龄拐点&lt;/td&gt;&lt;td&gt;18 + 6 = 24 岁&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;理论选到”最佳”的概率&lt;/td&gt;&lt;td&gt;38.73%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;注意第三行。N 是离散整数，跑出来 35.3% 比 36.8% 略小一点，对应拐点正好压在 24 岁——这就是知乎/微博上那句”25 岁前”的数学版本。如果你愿意把窗口期开到 18~36（17→18 年），拐点会精确推到 24.6 岁。怎么调都跑不出 25 岁这个量级。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;第二步：跑两万次模拟，看真实成功率&lt;/h3&gt;
&lt;p&gt;光看公式不够，我用模拟器的 Tab 2 直接跑了 N=20、两万次蒙特卡洛。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d9fd42a667234c568848c3c00cf61f76~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=jLFBxtOafabvr1XI0RuQYe541vg%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;结果：&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;策略&lt;/th&gt;&lt;th&gt;选到最佳的概率&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;37% 法则&lt;/td&gt;&lt;td&gt;38.52%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;随机选一个&lt;/td&gt;&lt;td&gt;5.15%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;立刻选第一个出现的&lt;/td&gt;&lt;td&gt;5.04%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;一直等到最后被迫选&lt;/td&gt;&lt;td&gt;5.12%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;37% 法则的命中率是其它三种”瞎搞”策略的约 7.5 倍。&lt;/p&gt;
&lt;p&gt;如果你觉得 N=20 太多，把 N 拉到 10（一辈子只认真考虑 10 个人），结果一样有效：&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;策略 (N=10, 20000 次)&lt;/th&gt;&lt;th&gt;成功率&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;37% 法则&lt;/td&gt;&lt;td&gt;40.16%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;随机选&lt;/td&gt;&lt;td&gt;9.78%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;选第一个&lt;/td&gt;&lt;td&gt;9.93%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;等到最后&lt;/td&gt;&lt;td&gt;9.84%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;注意 N=10 时观察期 r=4，拐点也在 18+(4⁄10)×17 ≈ 24.8 岁，依然是 24~25 之间。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;第三步：用参数扫描验证”24~25 岁”这条线不是巧合哦&lt;/h3&gt;
&lt;p&gt;模拟器的 Tab 3 会把跳过比例从 0% 扫到 100%，画一条成功率曲线。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c5835695572748c0ba54ceeb56f8a75e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=JXVlGTaePqMghK3FLKv3Y%2B4Y%2FDw%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;我跑了 N=17、每个点 5000 次的扫描，截取关键比例：&lt;/p&gt;













































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;跳过比例&lt;/th&gt;&lt;th&gt;实测成功率&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0%（碰到就选）&lt;/td&gt;&lt;td&gt;5.8%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10%&lt;/td&gt;&lt;td&gt;28.0%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;20%&lt;/td&gt;&lt;td&gt;32.5%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;30%&lt;/td&gt;&lt;td&gt;36.5%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;36%（理论最优）&lt;/td&gt;&lt;td&gt;39.1%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;40%&lt;/td&gt;&lt;td&gt;38.5%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;50%&lt;/td&gt;&lt;td&gt;35.4%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;60%&lt;/td&gt;&lt;td&gt;32.4%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80%&lt;/td&gt;&lt;td&gt;16.4%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;峰值精确落在 36~42% 区间，曲线两端塌得很快。跳过太少，你连基准线都没建立好，标准等于乱猜；跳过太多，最好的那个已经走完了，你只能在剩下的次品里挑。&lt;/p&gt;
&lt;p&gt;把这条曲线和”24~25 岁”对照一下：18 岁起算，36% 对应 24.1 岁，40% 对应 24.8 岁。曲线峰值这段平台期，刚好覆盖了所有人嘴里说的”二十四五岁”。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-4&quot;&gt;为什么是 1/e，不是 1/2？&lt;/h3&gt;
&lt;p&gt;很多人第一反应是”看一半再选不就好了”。问题在于 50% 这一格我也跑了——成功率掉到 35.4%。&lt;/p&gt;
&lt;p&gt;观察期太短，基准线偏低，容易把”第 7 名的人”当成”全场第 1”。观察期太长，”全场最佳”很可能已经在你观察期内出场了，后面你再也碰不到比 ta 更好的，被迫顺延到最后一个垃圾桶。对照一下现实可以说是非常真实了。&lt;/p&gt;
&lt;p&gt;1/e 这条线把两边的风险压到一样大。这个模型最后给出来的最优策略只有这一条——告诉你信息收集和行动窗口的最佳切换点。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;但是！但是要来了，现实修正：哪些假设会让”24.3 岁”漂移？&lt;/h3&gt;
&lt;p&gt;理想很丰满，现实很骨感。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;候选人不是均匀出场。 校园池子和职场池子的整体质量分布完全不同。换环境本身就在改变 N 和你的样本分布——这也是为什么有人 22 岁就遇到对的人，有人 32 岁还在等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“不能回头”是硬假设。 现实里前任能复合，被你跳过的人可能还在原地等。所以 24.3 岁这条线并不是死线。但它告诉你一件事：你拖得越久，回头率越低。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;目标到底是”最好的”还是”够好的”？ 经济学家 Herbert Simon 提出过 satisficing（够好就行）。如果你接受 80 分而非 100 分，最优观察期会缩短——大概 22 岁前后就该开始定。所以”宁缺毋滥”的人，反而要等到 24~25 岁。要求越高，越要给观察期留够时间。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;N 是你猜的。 没人知道一生会认真考虑几个人。但只要 N 落在 5~30 这个合理范围，跳过比例都在 33%&lt;del&gt;40% 之间晃，拐点都被锁在 23&lt;/del&gt;25 岁。这个区间硬到让人不舒服。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;如果你现在 24 岁以下？&lt;/h3&gt;
&lt;p&gt;那么你可以按照下面的方法去评估&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把评分维度真正建起来。颜值、身高、收入是表层 feature。真正决定长期匹配度的是”和这个人相处一年后，我变好了还是变差了”。这种东西需要时间样本。&lt;/li&gt;
&lt;li&gt;拓宽样本多样性。同质化的池子会扭曲你的基准线。校园谈、社团谈、朋友介绍谈、工作后再谈——每一段都在校正你的标尺。&lt;/li&gt;
&lt;li&gt;认真复盘。每个交往超过 3 个月的人，事后写下”ta 让我学到的”和”我不能接受的”。这就是你 24 岁那道分界线之前的训练数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;过了 24.3 岁，规则变了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看到一个让你觉得”比过去几年所有人都更对劲”的人——别再拖了。&lt;/li&gt;
&lt;li&gt;“再看看会不会更好”是这个模型里最经典的失败模式。模拟器告诉你，越往后等，你接触到比当前更好的人的概率就越低，最后多半会被迫选到末尾那个。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现实极低概率出现傻白甜白富美爱上穷小子、沙特阿拉伯王子爱上当保洁的穷姑娘&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7a20a5bc7ace4579aa0577b0b2e7428f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=ioacV9wzfvuRTZec%2FN6SNQzdTcE%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d992dfa5ac2448298ac9cec65b821a6a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=GEcX5eOv3VAYwjUj6Fb9a1Ri2zI%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;当然最后，你自己来demo玩玩就知道这个定律有多有效了&lt;/h3&gt;
&lt;p&gt;我加了一个”择偶情境”开关，可以切换到”看女生 / 看男生”模式，候选人会显示成 12 种风格的卡通头像 + “心动指数”，体验上更贴近真实择偶场景。但底层算法和数学是同一套——换汤不换药，因为渣男会骗人，但是数学不会骗人&lt;/p&gt;
&lt;p&gt;🔗 &lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fnumfeel.996.ninja%2Fpages%2Foptimal-stopping%2F&quot; target=&quot;_blank&quot; title=&quot;https://numfeel.996.ninja/pages/optimal-stopping/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;numfeel.996.ninja/pages/optim…&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ae104f18f98047b3abbbe7df1109b4a7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgQXNoZXJK:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784551133&amp;amp;x-signature=FXhKOLZmMt7xfaYmdIyswKOJ50g%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;</description><link>https://juejin.cn/post/7661546154107519016</link><guid isPermaLink="false">https://juejin.cn/post/7661546154107519016</guid><pubDate>Mon, 13 Jul 2026 12:38:53 GMT</pubDate><author>AsherJ</author><category></category><category>算法</category></item><item><title>Superpowers：GPT-5.6 时代下的流程毒瘤</title><description>&lt;blockquote&gt;
&lt;p&gt;一个日均消耗约 3 亿 token 的重度使用者，为什么最后选择把它从工作流里拆掉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;先说结论：我不是被模型拖慢，是被流程拖慢&lt;/h2&gt;
&lt;p&gt;今天下午，我又被一个任务折磨了一遍。&lt;/p&gt;
&lt;p&gt;这不是一个需要数天架构设计的项目，也不是支付、权限、数据迁移这种必须多人审查的高风险改动。按正常的工程节奏，应该是理解需求、定位代码、做一个小改动、跑相关测试，然后结束。真正动手的时间可能并不长。&lt;/p&gt;
&lt;p&gt;但在 Superpowers 的工作流里，一个小任务很容易被拉成一条完整的仪式链：先判断有没有 skill 适用，再进入头脑风暴，再写设计，再等确认，再写计划，再决定要不要建 worktree，再为每个任务派实现代理，再派规格评审，再派质量评审，最后还要重新验证、收尾、汇报。&lt;/p&gt;
&lt;p&gt;每一步单独看都能找到一个听起来合理的理由。问题是，工程效率不是把所有合理步骤都叠在一起。工程效率是用足够低的成本，获得足够高的正确率。&lt;/p&gt;
&lt;p&gt;Superpowers 最大的问题，恰恰是把“谨慎”变成了默认，把“流程”变成了目的，把一个本来可以直接完成的任务变成了对流程本身的服从测试。&lt;/p&gt;
&lt;p&gt;我不是反对测试，也不是反对审查，更不是反对子代理。我反对的是：在 GPT-5.6 这样的强模型时代，还把一套为不稳定、低自主性代理设计的长流程，当成所有任务的统一宗教。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;我是谁，以及为什么我会对这个问题这么敏感&lt;/h2&gt;
&lt;p&gt;我不是偶尔打开一次聊天窗口、问一个问题就离开的用户。按我自己的使用统计口径，我日均消耗大约 3 亿 token。这个数字不是行业基准，也不是给任何产品做宣传的指标，它只是我的工作现实：大量代码阅读、长上下文分析、跨模块修改、调试、部署、文档整理和反复验证，都在同一个 AI 工作流里完成。&lt;/p&gt;
&lt;p&gt;高频使用有一个好处：很多流程在第一次体验时看不出问题，重复几十次以后，问题会自己浮出来。&lt;/p&gt;
&lt;p&gt;你会开始分辨哪些步骤真的降低了错误率，哪些步骤只是让模型显得很认真；哪些输出帮助了决策，哪些输出只是把已经知道的事情再解释三遍；哪些评审抓住了缺陷，哪些评审只是把“没有发现问题”包装成一份新的报告。&lt;/p&gt;
&lt;p&gt;当你一天只做一个任务时，多十分钟的流程可能不明显。当你一天做几十个任务，或者让模型持续工作数小时，所有额外步骤都会变成真实的延迟、真实的 token、真实的上下文污染和真实的注意力损耗。&lt;/p&gt;
&lt;p&gt;所以我对 Superpowers 的不满，不是来自一次偶然的不顺手，而是来自高频使用后越来越清楚的成本账。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;Superpowers 到底把什么叠在了一起&lt;/h2&gt;
&lt;p&gt;我盘点了本机缓存中的 Superpowers v5.1.3。它一共有 14 个 skill，核心规则文本约 3207 行。它们大致分成几组：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需求与计划：&lt;code&gt;brainstorming&lt;/code&gt;、&lt;code&gt;writing-plans&lt;/code&gt;、&lt;code&gt;executing-plans&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;子代理与并行：&lt;code&gt;subagent-driven-development&lt;/code&gt;、&lt;code&gt;dispatching-parallel-agents&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;工作区与交付：&lt;code&gt;using-git-worktrees&lt;/code&gt;、&lt;code&gt;finishing-a-development-branch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;测试与调试：&lt;code&gt;test-driven-development&lt;/code&gt;、&lt;code&gt;systematic-debugging&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;评审与验证：&lt;code&gt;requesting-code-review&lt;/code&gt;、&lt;code&gt;receiving-code-review&lt;/code&gt;、&lt;code&gt;verification-before-completion&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;全局入口与元流程：&lt;code&gt;using-superpowers&lt;/code&gt;、&lt;code&gt;writing-skills&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;单个 skill 的存在并不等于每次都会加载完整正文。真正让事情变重的是它们之间的默认连接关系：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-rust&quot; lang=&quot;rust&quot;&gt;using-superpowers
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; brainstorming
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; writing-plans
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; using-git-worktrees
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; subagent-driven-development
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; implementation
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; spec review
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; quality review
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; verification
 &amp;nbsp;  &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; finishing-a-development-branch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一条适合大型、高风险、多人协作项目的保守流水线，不是一条适合所有日常代码任务的默认路径。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;效率：每一步都合理，串起来就不合理&lt;/h2&gt;
&lt;p&gt;下面是这条链中几类常见步骤的真实成本。&lt;/p&gt;


















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;步骤&lt;/th&gt;&lt;th&gt;它声称解决的问题&lt;/th&gt;&lt;th&gt;对小任务的实际代价&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;全局 skill 检查&lt;/td&gt;&lt;td&gt;避免漏掉流程&lt;/td&gt;&lt;td&gt;每次对话都增加判断和解释，模型先讨论“该不该开始”&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;头脑风暴&lt;/td&gt;&lt;td&gt;避免需求误解&lt;/td&gt;&lt;td&gt;配置、单函数、文档改动也被迫走设计和审批&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;详细计划&lt;/td&gt;&lt;td&gt;降低执行偏差&lt;/td&gt;&lt;td&gt;计划本身变成第二份规格，耗时可能超过实现&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;worktree&lt;/td&gt;&lt;td&gt;隔离改动&lt;/td&gt;&lt;td&gt;在已有隔离环境里重复创建隔离，产生无效操作&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;实现代理&lt;/td&gt;&lt;td&gt;分离上下文&lt;/td&gt;&lt;td&gt;重新传递背景、目标、文件和约束，增加等待和同步&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;规格评审&lt;/td&gt;&lt;td&gt;检查是否符合需求&lt;/td&gt;&lt;td&gt;对明确的小改动，常常只是复述需求&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;质量评审&lt;/td&gt;&lt;td&gt;检查代码质量&lt;/td&gt;&lt;td&gt;需要再次读取 diff 和上下文，可能提出低价值风格意见&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;收尾流程&lt;/td&gt;&lt;td&gt;统一合并和交付&lt;/td&gt;&lt;td&gt;对不需要 PR 或分支操作的任务，完全是额外仪式&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;关键不是某一步需要多少秒，而是这些步骤有顺序依赖。前一步没有结束，后一步不能开始。用户需要回答更多确认问题，模型需要发更多状态消息，工具需要产生更多中间文件，整个任务的尾延迟被不断拉长。&lt;/p&gt;
&lt;p&gt;最荒谬的场景是：代码改动本身只有几行，流程产物却包括设计说明、计划、任务清单、实现报告、规格评审报告、质量评审报告和最终验证报告。最后真正改变系统行为的，可能只有一个条件判断。&lt;/p&gt;
&lt;p&gt;这不是严谨。这是流程和任务规模失配。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;Token：最贵的不是代码，是重复解释&lt;/h2&gt;
&lt;p&gt;很多人谈 token 成本时，只盯着模型生成的代码。实际更昂贵的部分，往往是被流程强迫重复传递的上下文。&lt;/p&gt;
&lt;p&gt;一个简化的成本模型可以写成：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-markdown&quot; lang=&quot;markdown&quot;&gt;总成本
= 主代理上下文
&lt;span class=&quot;hljs-bullet&quot;&gt;  +&lt;/span&gt; 实现代理次数 × 任务上下文
&lt;span class=&quot;hljs-bullet&quot;&gt;  +&lt;/span&gt; 评审代理次数 × diff 与需求上下文
&lt;span class=&quot;hljs-bullet&quot;&gt;  +&lt;/span&gt; 失败重试 × 全部上下文
&lt;span class=&quot;hljs-bullet&quot;&gt;  +&lt;/span&gt; 流程状态消息与报告
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在单代理直接执行时，任务上下文通常只需要被理解一次。进入子代理开发后，同一份需求至少要被主代理整理一次、实现代理读取一次、规格评审读取一次、质量评审再读取一次。任务越多，重复越明显。&lt;/p&gt;
&lt;p&gt;而且这些上下文并不是免费的摘要。为了让每个代理“独立”，控制器要把任务背景、文件范围、约束、预期输出和当前状态重新写出来。评审代理还要重新建立自己的判断上下文。你以为你在买更高质量，实际上也在为同一份信息付多次入场费。&lt;/p&gt;
&lt;p&gt;更大的问题是 token 不只影响账单。上下文越长，模型越容易把注意力放在流程文档、状态报告和评审意见上，而不是放在真正的代码因果关系上。模型开始优化“如何证明自己遵守流程”，而不是“如何最快地解决问题”。&lt;/p&gt;
&lt;p&gt;对于日均消耗约 3 亿 token 的工作流，这种重复不是抽象的效率损失，而是巨大的资源浪费。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;评审到底有没有用？有，但不应该成为宗教&lt;/h2&gt;
&lt;p&gt;评审当然有用。安全边界、权限模型、支付逻辑、数据迁移、并发控制、公共 API 和跨服务契约，都值得第二双眼睛。问题在于，评审的价值高度依赖风险，而 Superpowers 把它做成了默认税。&lt;/p&gt;
&lt;p&gt;可以用一个很简单的判断表：&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;任务类型&lt;/th&gt;&lt;th&gt;自动评审的潜在收益&lt;/th&gt;&lt;th&gt;是否值得强制多轮评审&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;修改文档、配置、文案&lt;/td&gt;&lt;td&gt;很低&lt;/td&gt;&lt;td&gt;不值得&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;单文件局部修复&lt;/td&gt;&lt;td&gt;低到中&lt;/td&gt;&lt;td&gt;通常不值得&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;已有测试覆盖的普通业务逻辑&lt;/td&gt;&lt;td&gt;中&lt;/td&gt;&lt;td&gt;一次针对性检查即可&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;跨模块重构&lt;/td&gt;&lt;td&gt;高&lt;/td&gt;&lt;td&gt;可以考虑一次独立评审&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;权限、支付、安全、数据迁移&lt;/td&gt;&lt;td&gt;很高&lt;/td&gt;&lt;td&gt;建议人工或独立评审&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;强制评审的问题有三个。&lt;/p&gt;
&lt;p&gt;第一，评审代理不天然比实现代理更懂业务。它可能发现真正的缺陷，也可能把个人风格偏好当成规范问题。最后主代理还要花时间判断评审意见是否成立。&lt;/p&gt;
&lt;p&gt;第二，规格评审和质量评审的边界并没有想象中清晰。规格不完整会变成质量问题，质量风险又经常需要回到需求语义。拆成两个代理，不一定得到两倍的洞察，通常只得到两份相互重叠的文字。&lt;/p&gt;
&lt;p&gt;第三，评审会制造一种危险的安全感。报告写得很完整，不等于系统真的正确。真正有价值的验证仍然是可执行的测试、可复现的行为、清晰的监控和真实的用户反馈。&lt;/p&gt;
&lt;p&gt;评审应该是风险工具，不应该是忠诚度测试。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-6&quot;&gt;GPT-5.6 时代，为什么这套东西更容易显得逆天&lt;/h2&gt;
&lt;p&gt;早期代理确实需要更多脚手架。模型可能不理解上下文，容易忘记目标，不能稳定拆任务，也不擅长自我检查。于是人们把工程经验写成一条条硬规则，试图用流程弥补模型的不可靠。&lt;/p&gt;
&lt;p&gt;但模型能力在变化，流程却很容易固化。&lt;/p&gt;
&lt;p&gt;GPT-5.6 这一代强模型已经能够在同一个上下文里完成代码理解、方案选择、修改、测试和纠错。它不意味着模型永远正确，也不意味着工程纪律可以消失，但它意味着默认工作流应该允许模型根据任务风险调整策略。&lt;/p&gt;
&lt;p&gt;如果提示词写成“只要有 1% 的可能就必须调用 skill”，模型就没有风险判断空间。如果写成“任何项目都必须先设计，即使是一个配置改动”，模型就不能根据任务规模收缩流程。如果写成“没有失败测试就不能写生产代码”，模型就会把测试形式本身当成目标。&lt;/p&gt;
&lt;p&gt;这不是在增强模型，而是在压缩模型的有效自由度。&lt;/p&gt;
&lt;p&gt;模型明明可以用十分钟解决问题，却被要求用十分钟解释为什么现在还不能解决问题。模型明明可以根据风险选择一次验证，却被要求证明自己完成了完整仪式。最终用户看到的不是更聪明的工程师，而是一个不停填写流程表格的工程助理。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-7&quot;&gt;最逆天的不是某个步骤，而是那些硬门槛措辞&lt;/h2&gt;
&lt;p&gt;Superpowers 里有几类措辞特别能说明问题。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;using-superpowers&lt;/code&gt; 的原始规则要求：只要有 1% 的可能适用，就必须调用 skill，而且任何回复或行动之前都要先检查。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;brainstorming&lt;/code&gt; 的原始规则要求：任何项目都必须先设计。它甚至把 todo、单函数工具和配置修改列为不能跳过的案例，并要求写设计文档、提交、等待用户审阅，再进入计划。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;test-driven-development&lt;/code&gt; 的原始铁律是：没有先看到失败测试，就不能写生产代码。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;verification-before-completion&lt;/code&gt; 的原始规则则把成功表达、提交、创建 PR、移动到下一任务，甚至派发代理，都纳入重新验证的范围。&lt;/p&gt;
&lt;p&gt;这些句子单独看都像是在保护质量。放在一起，就变成了一个优先保护流程、其次才保护结果的系统。&lt;/p&gt;
&lt;p&gt;真正成熟的工程规范应该写成“在风险足够高时这样做”，而不是“永远这样做”。把例外全部当成懒惰，把简化全部当成违规，最终只能让模型更擅长服从文本，不能让软件更可靠。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;我最后做了一个本地实验：14 个变成 6 个&lt;/h2&gt;
&lt;p&gt;我没有继续争论“这套方法论理论上有没有价值”，而是直接做了一个本地精简实验。&lt;/p&gt;
&lt;p&gt;原来的 14 个 skill 中，我移除了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;subagent-driven-development&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dispatching-parallel-agents&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requesting-code-review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;receiving-code-review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;executing-plans&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;using-git-worktrees&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;finishing-a-development-branch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writing-skills&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;剩下的 6 个 skill 被改成轻量版本：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需求真正不清楚时，才做简短 brainstorming。&lt;/li&gt;
&lt;li&gt;多文件、存在顺序依赖时，才写短计划。&lt;/li&gt;
&lt;li&gt;复杂 Bug 才做系统调试，简单错误直接修。&lt;/li&gt;
&lt;li&gt;行为复杂、测试收益明确时才采用测试优先。&lt;/li&gt;
&lt;li&gt;非平凡任务结束前跑一次针对性验证。&lt;/li&gt;
&lt;li&gt;用户明确要求时，才考虑额外流程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;结果是，核心 &lt;code&gt;SKILL.md&lt;/code&gt; 从约 3207 行降到 110 行。这个数字不是性能基准，也不能证明所有团队都应该这么做，但它证明了一件事：原来的复杂度并不是工程问题本身必然要求的，而是规则叠加出来的。&lt;/p&gt;
&lt;p&gt;我还增加了一条更直接的全局偏好：除非用户明确要求，否则不派子代理，不派自动评审代理，默认由主代理完成实现并做一次针对性验证。&lt;/p&gt;
&lt;p&gt;这才更接近我想要的 AI 工程师，而不是 AI 流程管理员。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-9&quot;&gt;我认为 GPT-5.6 时代的工程规范应该是什么样&lt;/h2&gt;
&lt;p&gt;我不主张把所有规范都删掉。我主张把规范分级。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-10&quot;&gt;Lite：默认模式&lt;/h3&gt;
&lt;p&gt;适用于文档、配置、单文件修改、简单 Bug 和明确的小功能。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-rust&quot; lang=&quot;rust&quot;&gt;理解目标 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 修改 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 针对性测试或检查 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 说明结果
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不写长设计，不建 worktree，不派代理，不做自动评审。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-11&quot;&gt;Standard：普通复杂任务&lt;/h3&gt;
&lt;p&gt;适用于多文件改动、存在接口影响或需要明显顺序的功能。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-rust&quot; lang=&quot;rust&quot;&gt;短计划 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 实现 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 相关测试 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 一次自检
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;计划的目标是减少遗漏，不是制造一份比代码更长的文档。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-12&quot;&gt;Strict：高风险任务&lt;/h3&gt;
&lt;p&gt;只在安全、支付、权限、数据迁移、公共 API、跨服务契约和重大重构中启用。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-rust&quot; lang=&quot;rust&quot;&gt;设计讨论 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 计划 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 实现 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 独立评审或人工评审 &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; 集成验证
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即使是 Strict，也应该由用户或项目负责人明确选择，而不是由一个“1% 可能性”自动触发。&lt;/p&gt;
&lt;p&gt;这种分级并不降低标准。它把标准用在真正需要的地方，把时间留给真正重要的判断。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-13&quot;&gt;不是反对纪律，是反对把纪律变成目的&lt;/h2&gt;
&lt;p&gt;今天下午最让我烦的，不是模型犯了一个错。模型犯错是可以接受的，至少错误是可见的，可以复现，可以修复。&lt;/p&gt;
&lt;p&gt;让我烦的是，在一个本来可以快速闭环的任务里，我不断看到新的流程、确认、报告和评审。每一项都在告诉我系统很谨慎，却没有同等力度地告诉我系统离结果更近了。&lt;/p&gt;
&lt;p&gt;我宁愿让模型在一个低风险小任务上直接做出一个可以被测试发现的错误，也不愿它先花大量 token 证明自己知道什么叫规范。我宁愿自己看一眼 diff、跑一次测试，也不愿为一份低价值评审报告再启动一个上下文、再等待一次结果、再判断一次判断是否值得相信。&lt;/p&gt;
&lt;p&gt;AI 工具的价值，是把人的判断力放大，把执行成本压低。一个工作流如果让人花更多时间等待流程、解释流程、批准流程，最后才轮到解决问题，那它就已经偏离了工具的目的。&lt;/p&gt;
&lt;p&gt;Superpowers 曾经试图把经验固化成护栏。问题是，护栏太多、太密、太低，最后就不再是护栏，而是一条把所有车辆都强行降速的窄路。&lt;/p&gt;
&lt;p&gt;在 GPT-5.6 时代，我们需要的是有判断力的工程纪律，不是无差别的流程服从。&lt;/p&gt;
&lt;p&gt;我并不想让模型少思考。我只是希望它把思考用在代码、数据和结果上，而不是用在证明自己完成了多少个仪式。&lt;/p&gt;
&lt;p&gt;这就是我为什么说：对高频 AI 工程工作而言，未经分级、未经风险校准、默认强制评审和子代理的 Superpowers，已经从“能力增强”变成了“效率毒瘤”。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-14&quot;&gt;技术附录：这不是情绪，而是可以定位的机制问题&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-15&quot;&gt;原始规则里的几个硬触发点&lt;/h3&gt;
&lt;p&gt;下面这些不是我对 Superpowers 的二次概括，而是它在 skill 文件中使用的典型硬门槛。文件名就是它们在插件里的实际位置。&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;文件&lt;/th&gt;&lt;th&gt;原始倾向&lt;/th&gt;&lt;th&gt;运行时后果&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/using-superpowers/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;“只要有 1% 的可能适用，就必须调用”&lt;/td&gt;&lt;td&gt;低置信度判断也会触发完整流程&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/brainstorming/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;“这适用于每一个项目，包括简单配置修改”&lt;/td&gt;&lt;td&gt;小改动不能直接开始&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/writing-plans/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;要求把工作拆成完整、可执行的计划任务&lt;/td&gt;&lt;td&gt;计划成本和实现成本倒挂&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/subagent-driven-development/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;每任务新建实现代理，再做规格和质量评审&lt;/td&gt;&lt;td&gt;一次改动变成多次上下文交接&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/requesting-code-review/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;每个子任务、重大功能、合并前都要求评审&lt;/td&gt;&lt;td&gt;评审从风险工具变成固定税&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;skills/verification-before-completion/SKILL.md&lt;/code&gt;&lt;/td&gt;&lt;td&gt;任何完成表达、提交、下一任务前都要新鲜验证&lt;/td&gt;&lt;td&gt;状态沟通也会触发额外检查&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这些规则的共同问题不是“完全错误”，而是把“通常有帮助”写成了“永远必须”。一旦触发条件过宽，模型就无法根据任务规模和失败代价做正常的工程取舍。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-16&quot;&gt;1. 规则触发层&lt;/h3&gt;
&lt;p&gt;skill 的 frontmatter 描述会参与触发判断。只要描述写成“任何对话”“任何功能”“任何 Bug”，触发面就会极度扩大。全局入口再要求“1% 可能适用也必须调用”，等于把低置信度判断变成高频加载。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-17&quot;&gt;2. 上下文复制层&lt;/h3&gt;
&lt;p&gt;子代理架构需要把任务背景重新包装给每个代理。实现代理、规格评审代理和质量评审代理往往分别读取同一份需求和 diff。任务本身没有增加，输入上下文却被复制了多次。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-18&quot;&gt;3. 交互等待层&lt;/h3&gt;
&lt;p&gt;代理调用通常存在启动、等待、汇总和重试。即使每次代理都很快，串行依赖仍会把总耗时拉长。用户等待的不是代码计算时间，而是多个角色之间的交接时间。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-19&quot;&gt;4. 判断污染层&lt;/h3&gt;
&lt;p&gt;当上下文中同时存在需求、计划、实现报告、评审报告和修复意见，模型必须花额外注意力判断哪一层才是当前事实。越多过程文档，不一定越清晰，可能只是增加了状态冲突的机会。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-20&quot;&gt;5. 质量收益递减层&lt;/h3&gt;
&lt;p&gt;第一次针对性测试通常能发现最直接的问题。第二次独立检查可能发现边界条件。第三次对同一小任务做形式不同但信息高度重叠的评审，收益往往快速递减。流程没有把这个递减曲线纳入决策，就会把低收益检查当成固定成本。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-21&quot;&gt;6. 正确的控制变量&lt;/h3&gt;
&lt;p&gt;真正应该控制的不是“有没有调用某个 skill”，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;变更风险有多高；&lt;/li&gt;
&lt;li&gt;失败的代价有多大；&lt;/li&gt;
&lt;li&gt;是否存在独立的知识盲区；&lt;/li&gt;
&lt;li&gt;是否有可执行的验证手段；&lt;/li&gt;
&lt;li&gt;用户是否明确需要额外审查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些变量决定了流程强度。任何脱离风险、只按关键词触发的固定流程，最终都会在简单任务上浪费资源，在复杂任务上制造虚假的安全感。&lt;/p&gt;</description><link>https://juejin.cn/post/7661830907991146536</link><guid isPermaLink="false">https://juejin.cn/post/7661830907991146536</guid><pubDate>Mon, 13 Jul 2026 10:02:14 GMT</pubDate><author>小u</author><category>后端</category><category>前端</category></item><item><title>为什么 AI 写前端时，总是优先选择 React，而不是 Vue？</title><description>&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6e905d30de734c5c950e8ce528e57da9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784539559&amp;amp;x-signature=g45vgnY632fOrT5N6Fw%2BL5t0Y%2B8%3D&quot; alt=&quot;为什么 AI 写前端时，总是优先选择 React，而不是 Vue？&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果你在过去几个月里，高强度使用过 &lt;code&gt;Codex&lt;/code&gt;、&lt;code&gt;Cursor&lt;/code&gt; 或者是 &lt;code&gt;Claude Code&lt;/code&gt; 等 AI 编程工具，你一定会察觉到一个让国内前端开发者极度不适的现象：&lt;/p&gt;
&lt;p&gt;当你扔给 AI 一张设计图，或者一段自然语言需求，让它帮你生成前端组件时，如果不做任何额外的 &lt;code&gt;Prompt&lt;/code&gt; 限制，它默认吐出来的代码，永远是 &lt;code&gt;React&lt;/code&gt; 加上 &lt;code&gt;Tailwind CSS&lt;/code&gt;🤔。&lt;/p&gt;
&lt;p&gt;作为一个 &lt;code&gt;Vue&lt;/code&gt; 开发者，你必须在提示词里反复强调：&lt;strong&gt;请使用 &lt;code&gt;Vue3&lt;/code&gt; 和 &lt;code&gt;script setup&lt;/code&gt; 语法！&lt;/strong&gt;。但即便如此，AI 生成的 &lt;code&gt;Vue&lt;/code&gt; 代码里，也经常会诡异地夹杂着 &lt;code&gt;className&lt;/code&gt;，甚至试图在 &lt;code&gt;template&lt;/code&gt; 模板层里写 &lt;code&gt;map&lt;/code&gt; 映射。&lt;/p&gt;
&lt;p&gt;在框架使用者眼里，这可能又是一场框架优劣的口水战。但我想讲的是，大模型这种压倒性的框架偏好，其实暴露出的是底层技术架构的根本性差异。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-0&quot;&gt;只是因为训练语料多吗？&lt;/h3&gt;
&lt;p&gt;当你抛出这个问题时，绝大多数人给出的答案是：因为 &lt;code&gt;React&lt;/code&gt; 拥有全球最庞大的生态，在 &lt;code&gt;GitHub&lt;/code&gt; 上的开源项目和代码语料远超 &lt;code&gt;Vue&lt;/code&gt;。大模型吃进去的 &lt;code&gt;React&lt;/code&gt; 代码多，吐出来的自然也就多。&lt;/p&gt;
&lt;p&gt;这句话本身没错，但这只是一层极其懒惰的表象解释🤷‍♂️。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/caece253ebea4c679ae975d3cab17fa8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784539559&amp;amp;x-signature=t262B%2BW9SMhdtnRJvz%2BfrAhdzu0%3D&quot; alt=&quot;ChatGPT Image 2026年7月13日 16_40_11.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;大模型本质上是一个基于概率的 &lt;code&gt;Token&lt;/code&gt; 预测机器。它在生成代码时，不仅受语料数量的影响，更受&lt;strong&gt;语言结构（AST）纯粹性&lt;/strong&gt;的制约。真正让 AI 对 &lt;code&gt;Vue&lt;/code&gt; 感到吃力并且频繁产出幻觉的，是两者在底层设计哲学上的巨大鸿沟🤔。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;JS 纯粹性与 DSL 的认知负担&lt;/h3&gt;
&lt;p&gt;在我们人类程序员眼里，&lt;code&gt;Vue&lt;/code&gt; 极度优雅。它的单文件组件（SFC）把 &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 和 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 物理隔离，逻辑清晰，极度符合人类对网页结构的直觉认知。&lt;/p&gt;
&lt;p&gt;但在大模型的眼里，&lt;code&gt;Vue&lt;/code&gt; 其实是一个极其复杂的 DSL（领域特定语言）。&lt;/p&gt;
&lt;p&gt;大模型最擅长预测什么？是标准的、图灵完备的常规编程语言（比如纯 &lt;code&gt;JavaScript&lt;/code&gt; 或 &lt;code&gt;Python&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;React&lt;/code&gt; 的 &lt;code&gt;JSX&lt;/code&gt; 表面上看起来是标签，但在 &lt;code&gt;AST&lt;/code&gt;（抽象语法树）层面，它本质上就是纯粹的 &lt;code&gt;JavaScript&lt;/code&gt; 函数调用。核心的控制流（&lt;code&gt;if/else&lt;/code&gt;、&lt;code&gt;map&lt;/code&gt;、&lt;code&gt;switch&lt;/code&gt;）完全遵循原生 &lt;code&gt;JS&lt;/code&gt; 的语法规则。大模型在预测下一个 &lt;code&gt;Token&lt;/code&gt; 时，上下文是高度连贯和内聚的👇。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-tsx&quot; lang=&quot;tsx&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// 在大模型的使用，这根本不是 HTML，这只是一个标准的 JS 纯函数&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;UserList&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;{ users }&lt;/span&gt;) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; (
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;ul&lt;/span&gt;&amp;gt;&lt;/span&gt;
      {users.length &amp;gt; 0 
        ? users.map(u =&amp;gt; &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;key&lt;/span&gt;=&lt;span class=&quot;hljs-string&quot;&gt;{u.id}&lt;/span&gt;&amp;gt;&lt;/span&gt;{u.name}&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;li&lt;/span&gt;&amp;gt;&lt;/span&gt;)
        : &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;li&lt;/span&gt;&amp;gt;&lt;/span&gt;暂无数据&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;li&lt;/span&gt;&amp;gt;&lt;/span&gt;}
    &lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/&lt;span class=&quot;hljs-name&quot;&gt;ul&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而 &lt;code&gt;Vue&lt;/code&gt; 则不同。大模型在生成 &lt;code&gt;Vue&lt;/code&gt; 代码时，必须在脑海里强行维护两套完全割裂的上下文：
一套是基于 &lt;code&gt;HTML&lt;/code&gt; 扩展的模板语法（&lt;code&gt;v-if&lt;/code&gt;、&lt;code&gt;v-for&lt;/code&gt;、&lt;code&gt;v-model&lt;/code&gt;），另一套是下方的 &lt;code&gt;script setup&lt;/code&gt; 响应式逻辑。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-vue&quot; lang=&quot;vue&quot;&gt;&amp;lt;!-- 大模型在生成长组件时，极其容易在这里的模板层丢失数据映射 --&amp;gt;
&amp;lt;template&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;template v-if=&quot;userList.length &amp;gt; 0&quot;&amp;gt;
      &amp;lt;li v-for=&quot;u in userList&quot; :key=&quot;u.id&quot;&amp;gt;{{ u.name }}&amp;lt;/li&amp;gt;
    &amp;lt;/template&amp;gt;
    &amp;lt;li v-else&amp;gt;暂无数据&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup lang=&quot;ts&quot;&amp;gt;
import { ref } from &#39;vue&#39;;
// 当代码超过 300 行，AI 很容易忘了上面绑定的变量到底是 users 还是 userList
const userList = ref([]);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当上下文长度超过几百行后，大模型极容易在 &lt;code&gt;template&lt;/code&gt; 和 &lt;code&gt;script&lt;/code&gt; 之间的变量绑定上产生灾难级的幻觉。它可能会在模板里写出一个未经声明的 &lt;code&gt;ref&lt;/code&gt; 变量，或者在脚本里写了一堆逻辑，却忘了通过模板指令去驱动视图。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人类更擅长处理结构隔离，而机器更擅长处理逻辑同源🖐️。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;那组件物理拆分的阻力是什么？&lt;/h3&gt;
&lt;p&gt;在大模型的日常协作中，最深水区的痛点其实是代码的重构与拆分。&lt;/p&gt;
&lt;p&gt;大模型写代码有一个通病：喜欢把所有的逻辑都塞进一个巨大的文件里。当这个缝合怪组件膨胀到上千行时，你必须命令它进行拆分。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7d02b64b45ec4bb28169c26ba86fc3be~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784539559&amp;amp;x-signature=%2BKlrcZW%2BFCK2vYxKzpZ3FjARqi0%3D&quot; alt=&quot;ChatGPT Image 2026年7月13日 16_58_29.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;React&lt;/code&gt; 里，拆分组件的成本极低。大模型只需要在同一个文件里，顺手多写几个首字母大写的 &lt;code&gt;Function&lt;/code&gt;，就可以直接完成细粒度的逻辑抽离。这种&lt;strong&gt;按需内联拆分&lt;/strong&gt;的能力，极其契合 AI 的线性文本生成逻辑。&lt;/p&gt;
&lt;p&gt;但在 &lt;code&gt;Vue&lt;/code&gt; 的生态里，创建一个新组件通常意味着必须在文件系统里新建一个 &lt;code&gt;.vue&lt;/code&gt; 文件，并且要处理繁琐的 &lt;code&gt;import&lt;/code&gt; 路径、父子组件 &lt;code&gt;props&lt;/code&gt; 传递和 &lt;code&gt;emits&lt;/code&gt; 事件分发。多文件并发生成和底层路径映射，恰恰是当前所有 AI 编程工具最容易翻车的软肋。&lt;/p&gt;
&lt;p&gt;这直接导致了 AI 在写大型 &lt;code&gt;Vue&lt;/code&gt; 项目时，代码极易走向失控。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;前端组件的文本化（复制粘贴🤣）&lt;/h3&gt;
&lt;p&gt;最后，我们无法回避整个前端组件库生态的残酷站队。&lt;/p&gt;
&lt;p&gt;在 AI 自动生成 UI 的时代，像 &lt;code&gt;Shadcn UI&lt;/code&gt; 这种纯粹基于 &lt;code&gt;Tailwind CSS&lt;/code&gt; 和 &lt;code&gt;Radix UI&lt;/code&gt; 的方案成为了绝对的统治者。为什么？因为它的组件根本不是作为一个 &lt;code&gt;npm&lt;/code&gt; 依赖包黑盒存在的，而是&lt;strong&gt;可以直接被大模型阅读、复制并内联修改的纯文本源码&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8495eebcc3ef46a1ae7a721f47424e0e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784539559&amp;amp;x-signature=iJOFlTsUCDnuqeCmrtiCKh8JrgI%3D&quot; alt=&quot;ChatGPT Image 2026年7月13日 16_48_00.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;这种 &lt;strong&gt;代码即 UI&lt;/strong&gt; 的模式，让 AI 可以直接透视并定制组件的每一个像素。而 &lt;code&gt;Vue&lt;/code&gt; 生态里占据主导地位的（如 &lt;code&gt;Element Plus&lt;/code&gt; 或 &lt;code&gt;Ant Design Vue&lt;/code&gt;），依然是沉重的全局安装包。大模型无法透视黑盒内部的代码，在遇到定制化需求时，只能绝望地去瞎猜文档配置参数😖。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;在做技术选型时，我们往往会夹杂着太多关于&lt;strong&gt;好与坏&lt;/strong&gt;的执念。&lt;/p&gt;
&lt;p&gt;如果是完全由纯开发者主导开发，&lt;code&gt;Vue&lt;/code&gt; 极低的心智负担、清晰的关注点分离，依然是中大型业务团队稳盘的绝佳利器。&lt;/p&gt;
&lt;p&gt;但如果我们正在迈入一个由 AI 主导代码生成的新纪元，我们就必须面对残酷的现实：&lt;strong&gt;&lt;code&gt;React&lt;/code&gt; 那种一切皆函数、一切皆 JavaScript 的纯粹性，确实极大地降低了机器的认知负荷&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;好了，今天写道这里吧🙌&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/02fde88c4e2f4b7caf06eb373cb632c2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgRXJwYW5PbWVy:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784539559&amp;amp;x-signature=22lMRAnArDUL0pPSnx8aR%2ByI2cU%3D&quot; alt=&quot;Suggestion (2).gif&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;</description><link>https://juejin.cn/post/7661833071121530926</link><guid isPermaLink="false">https://juejin.cn/post/7661833071121530926</guid><pubDate>Mon, 13 Jul 2026 09:25:59 GMT</pubDate><author>ErpanOmer</author><category>前端</category><category>JavaScript</category><category>程序员</category></item><item><title>星云SDK + 油猴：给LLM塑造肉身，陪伴你在每个网页</title><description>&lt;p&gt;作为一名前端开发者，我一直有一个愿景：&lt;em&gt;让大模型不再只是冰冷的输入框，而是能以&lt;strong&gt;具身交互智能&lt;/strong&gt;数字人形象，出现在我们浏览的每一个网页上，一直陪伴我们。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这个想法其实来自钢铁侠的“贾维斯”，我希望在我使用浏览器的时候，AI助手一直在页面上陪伴我，写错了代码了立刻提醒，有疑问随时解答。幸运的是，随着大模型的发展，这些已经可以轻松实现。&lt;/p&gt;
&lt;p&gt;今天，我想分享一个基于 &lt;strong&gt;魔珐星云SDK&lt;/strong&gt; 和 &lt;strong&gt;油猴脚本&lt;/strong&gt; 的方案，实现一个基础版的网页AI助手：&lt;strong&gt;用魔珐星云SDK结合LLM，打造拥有 3D 躯体、同步神态动作、支持实时打断的网页随身 AI 具身交互智能伙伴，再通过油猴脚本让它出现在任意网页上。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;效果展示&lt;/h2&gt;
&lt;p&gt;先来看一下脚本的最终实现的效果。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无处不在的陪伴&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不管打开什么网页，点击链接，虚拟助手直接出现。下图分别是在 TRAE 官网和掘金热榜上的效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/10ef6bf3ad3b450abc08c563d86dcae6~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=FAxqXWoqEURwSCndasKP3MsR570%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;极速上手体验&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基于油猴脚本，安装脚本后，配置好魔珐星云 SDK 的 ID和Key 就能跑起来体验，成本极低。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/55e7ccb5ad9745a688409df211dc48e2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=0Trdhfi189E1h9TSl6INQU55%2BsI%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;热切换形象，零配置&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在魔珐星云控制台切换虚拟人的形象、场景、音色后，不需要改任何代码配置，脚本实时生效。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6da93c0186d44eb19a8271ffde8e21f9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=Ehk3Zdk84FCgwL6W39EFcaKvOTY%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实时对话&amp;amp;语音交互&lt;/strong&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;发送文字消息后，数字人会实时语音播报，同时配合自然的表情和肢体动作，整个过程响应低于 500ms，并支持全程随时打断，体验流畅。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/66ae811d4a924c86a06abe8265820055~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=DOEt3DUn4IM6TGS3jFijWXEiZk0%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;发送语音消息也没问题——基于第三方 ASR 语音识别，语音实时转文本，再交给星云 SDK 处理，实现真正的语音对话。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4092f35f33de4ff7a332a793036f1c9b~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=vYZFKdmHfZPLKp8HEk1XcP7%2Bx%2BE%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM流式响应同步&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;脚本支持接入任意第三方大模型。以 DeepSeek 为例，LLM 流式输出的同时，3D 数字人就能基于已返回的内容实时生成语音，不用等整段文字全部返回才开始回答，大幅减少了等待感。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/9d15070841ba458bab4bffb43a3228fc~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=b%2FayoNuUp%2F%2F4JwrSRqIxpL5VnDU%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;核心体验一句话概括：&lt;strong&gt;为 DeepSeek 等 LLM 补齐缺失的具身交互智能，让纯文本推理模型升级为看得见、能共情、可双向实时互动的全域网页陪伴智能体。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;核心技术&lt;/h2&gt;
&lt;p&gt;整个 Demo 的实现依赖两个核心技术：&lt;strong&gt;魔珐星云具身驱动 SDK&lt;/strong&gt; 负责 3D 虚拟人的渲染与交互，&lt;strong&gt;Tampermonkey（油猴脚本）&lt;/strong&gt; 负责让它在任意网页上跑起来。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;魔珐星云具身驱动SDK&lt;/h3&gt;
&lt;p&gt;魔珐星云是魔珐科技打造的「&lt;strong&gt;AI 具身交互智能体开放平台」&lt;/strong&gt;，提供 AI 形象生成、多模态感知、大模型 Agent 认知、实时 3D 具象表达、机器人运控等端到端能力。&lt;/p&gt;
&lt;p&gt;借助它的&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fxingyun3d.com%2F%3Futm_campaign%3Ddaily%26utm_source%3Djuejiin-jz-1%26utm_medium%3D%26utm_term%3D%26utm_content%3D&quot; target=&quot;_blank&quot; title=&quot;https://xingyun3d.com/?utm_campaign=daily&amp;amp;utm_source=juejiin-jz-1&amp;amp;utm_medium=&amp;amp;utm_term=&amp;amp;utm_content=&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;具身驱动 SDK&lt;/a&gt;，只要终端支持浏览器内核，就可以接入具备 AI 交互能力的 3D 虚拟人。平台采用完整自研参数流架构 + AI 端渲和解算原生技术，专门为各类 LLM、Agent 提供标准化具身交互智能，一站式完成 3D 形象生成、情绪同步、实时双向交互、多终端适配全链路能力。&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;技术模块&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;语义情感理解&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;实时解析文本语义、情绪、动作意图&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;TTS语音生成&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;高自然度语音合成，延迟约100-500ms&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;表情动作生成&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;实时输出3D微表情、肢体动作、手势&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;AI端侧渲染&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;无需传统游戏引擎，百元级芯片即可运行&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;使用星云具身驱动SDK实现3D虚拟形象，具备以下优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;低延时&lt;/strong&gt;：端到端响应低于500ms，对话支持随时打断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高并发&lt;/strong&gt;：支撑千万级设备同时在线&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;低成本&lt;/strong&gt;：无需昂贵GPU，普通设备即可流畅运行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全兼容&lt;/strong&gt;：覆盖手机、PC、大屏、机器人等终端&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;Tampermonkey篡改猴&lt;/h3&gt;
&lt;p&gt;Tampermonkey篡改猴又称为“油猴，”是一款老牌浏览器插件，它允许开发者以一段轻量的 JS 脚本，实现媲美原生浏览器扩展的功能。&lt;/p&gt;
&lt;p&gt;它的工作原理很简单：在网页加载时注入自定义 JavaScript，从而增强、修改或自动化页面行为。常见的应用场景包括广告屏蔽、页面优化、自动填表、功能增强等。&lt;/p&gt;
&lt;p&gt;如果你之前没接触过油猴脚本，可以参考：『&lt;a href=&quot;https://juejin.cn/book/7514684308372586537?utm_source=course_list&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/book/7514684308372586537?utm_source=course_list&quot;&gt;&lt;strong&gt;油猴脚本实战指南&lt;/strong&gt;&lt;/a&gt; 』&lt;/p&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;极速体验&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;1. 安装Tampermonkey浏览器插件&lt;/h3&gt;
&lt;p&gt;要体验Demo 中的效果，首先需要安装[&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgitee.com%2Fsxshi%2Foil-monkey-offline-package%2Fblob%2Fmaster%2FTampermonkey5_3_3_0.crx&quot; target=&quot;_blank&quot; title=&quot;https://gitee.com/sxshi/oil-monkey-offline-package/blob/master/Tampermonkey5_3_3_0.crx&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;Tampermonkey（油猴）浏览器插件&lt;/a&gt;]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;安装过程可参考：&lt;a href=&quot;https://juejin.cn/book/7514684308372586537/section/7514686493563027495&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/book/7514684308372586537/section/7514686493563027495&quot;&gt;油猴脚本的安装与管理&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;插件装好后，有两种方式安装脚本：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;方式一：在线链接安装&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgreasyfork.org&quot; target=&quot;_blank&quot; title=&quot;https://greasyfork.org&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;greasyfork.org&lt;/a&gt; 官网，搜索脚本：石小石Orz的魔珐星云虚拟人，然后点击安装此脚本&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/013b3592e3bb4b22bb2caf75320d2b89~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=7Hez6aLYVyP%2BE0fBFWMG%2FFZ2zKM%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;方式二：手动复制安装&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;点击浏览器菜单栏的油猴图标，选择「添加新脚本」，将以下脚本内容粘贴到编辑器中，Ctrl+S 保存即可。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgitee.com%2Fsxshi%2Ftampermonkey-nebula%2Fblob%2Fmaster%2Fdist%2Fxinyun3d.user.js&quot; target=&quot;_blank&quot; title=&quot;https://gitee.com/sxshi/tampermonkey-nebula/blob/master/dist/xinyun3d.user.js&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;gitee.com/sxshi/tampe…&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ddec7b474f864f7bb915dfa14beb8d62~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=QUfkx6fPqvnYSJ92WMJvchrRA6A%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;安装完成后，刷新任意页面，就能在网页右下角看到操作面板：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0bfb41bae56043ee867f7d2d6338ba35~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=wAkN9Aa1WTKve64IoVT4Z%2FWEos4%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如果你觉得油猴安装配置太麻烦，也可以直接访问以下网址，体验极简版 Demo&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在线地址：&lt;/strong&gt; &lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fwww.axureshow.com%2Fproject%2FHDZcuEZb%2F&quot; target=&quot;_blank&quot; title=&quot;https://www.axureshow.com/project/HDZcuEZb/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;https://www.axureshow.com/project/HDZcuEZb/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3186cf777d194fa2b7b0d490893eb65c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=zaiI8R53Ry3gk30JkQBIl9YU5lU%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;2. 获取星云SDK秘钥&lt;/h3&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fxingyun3d.com%2F%3Futm_campaign%3Ddaily%26utm_source%3Djuejiin-jz-1%26utm_medium%3D%26utm_term%3D%26utm_content%3D&quot; target=&quot;_blank&quot; title=&quot;https://xingyun3d.com/?utm_campaign=daily&amp;amp;utm_source=juejiin-jz-1&amp;amp;utm_medium=&amp;amp;utm_term=&amp;amp;utm_content=&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;魔珐星云平台&lt;/a&gt; 注册账号，填写邀请码&lt;code&gt;JM2A7C9LSW&lt;/code&gt;，获得1000积分。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;注册成功后进入「控制台」&lt;/li&gt;
&lt;li&gt;点击「具身驱动」创建应用&lt;/li&gt;
&lt;li&gt;选择你喜欢的数字人形象、场景及音色，然后点击「创建并进入调试」&lt;/li&gt;
&lt;li&gt;点击页面右上角「接入SDK」按钮获取 &lt;code&gt;APP_ID&lt;/code&gt; 和 &lt;code&gt;APP_SECRET&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/197416a44404448b9ee041f976a44b16~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=QXgwzaJx2M%2Bg6AnRANrY%2FAZ8OhQ%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 使用邀请码&lt;code&gt;JM2A7C9LSW&lt;/code&gt;注册可获得1000积分，否则获得100积分，积分类似大模型的token。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;APP_ID&lt;/code&gt; 和 &lt;code&gt;APP_SECRET&lt;/code&gt;获取成功后，点击脚本面板的设置按钮，配置秘钥&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/22eb9300c32d416887530ccdf74c25f0~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=fBuOBp6AZpllq9yCAPBiC0ERIcw%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果秘钥正确，点击「保存并连接」按钮，脚本就会开始创建连接，加载虚拟人。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;3. 配置LLM API（可选）&lt;/h3&gt;
&lt;p&gt;脚本已内置 DeepSeek 模型作为默认选项，开箱即用，无需额外配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/022eed80a0cb404d8b992c44ba9a337c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-z5bCP55-zT3J6:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784534297&amp;amp;x-signature=QKTi4GZNNdHAmgjBqvrnyqy1an4%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果你想用自己的 DeepSeek API Key，前往 [&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fplatform.deepseek.com%2F&quot; target=&quot;_blank&quot; title=&quot;https://platform.deepseek.com/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;DeepSeek API 平台&lt;/a&gt;] 获取 Key，在设置面板中填入即可。&lt;/p&gt;
&lt;p&gt;现在，你就可以尽情的探索脚本了。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;脚本核心代码解析&lt;/h2&gt;
&lt;p&gt;具身驱动 SDK 的接入方式非常简单，整体流程可以分为三步：&lt;strong&gt;引入 SDK、初始化实例、调用播报方法&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;首先，在页面中引入 SDK：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-js&quot; lang=&quot;js&quot;&gt;&amp;lt;script src=&lt;span class=&quot;hljs-string&quot;&gt;&quot;https://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatar@latest.js&quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后创建 SDK 实例，并完成初始化。这里需要将 &lt;code&gt;appId&lt;/code&gt; 和 &lt;code&gt;appSecret&lt;/code&gt; 替换为刚才在魔珐星云控制台中复制的内容：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-js&quot; lang=&quot;js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; sdk = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;XmovAvatar&lt;/span&gt;({
  &lt;span class=&quot;hljs-attr&quot;&gt;containerId&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;#sdk&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// 必填：数字人挂载容器&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;appId&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;your_appid&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// 必填：应用 AppID&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;appSecret&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;your_appsecret&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// 必填：应用 AppSecret&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;gatewayServer&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;https://nebula-agent.xingyun3d.com/user/v1/ttsa/session&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// 必填：服务接口地址&lt;/span&gt;

  &lt;span class=&quot;hljs-comment&quot;&gt;// SDK 事件回调，方便调试&lt;/span&gt;
  &lt;span class=&quot;hljs-title function_&quot;&gt;onMessage&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;message&lt;/span&gt;) {
    &lt;span class=&quot;hljs-variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;SDK message:&quot;&lt;/span&gt;, message);
  },
});

&lt;span class=&quot;hljs-comment&quot;&gt;// 初始化 SDK，加载数字人资源&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; sdk.&lt;span class=&quot;hljs-title function_&quot;&gt;init&lt;/span&gt;({
  &lt;span class=&quot;hljs-title function_&quot;&gt;onDownloadProgress&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;progress&lt;/span&gt;) {
    &lt;span class=&quot;hljs-variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;`资源加载进度：&lt;span class=&quot;hljs-subst&quot;&gt;${progress}&lt;/span&gt;%`&lt;/span&gt;);
  },
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化完成后，调用 &lt;code&gt;speak&lt;/code&gt; 方法即可让数字人开口说话：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-js&quot; lang=&quot;js&quot;&gt;sdk.&lt;span class=&quot;hljs-title function_&quot;&gt;speak&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;你好，石小石，我是你的 AI 伴侣~&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果只是播报一句完整的话，后两个参数通常都传 &lt;code&gt;true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;sdk实例化后，拥有以下核心方法：&lt;/p&gt;























































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;方法&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;th&gt;参数&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;init(config)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;初始化实例，连接服务并加载资源&lt;/td&gt;&lt;td&gt;&lt;code&gt;config.onDownloadProgress&lt;/code&gt;：可选，监听加载进度&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;destroy()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;关闭连接，释放资源&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;offlineMode()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;进入离线模式，循环播放缓存视频（不消耗积分）&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;onlineMode()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;从离线模式切回在线模式&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;idle()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;切换到待机状态&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;interactiveIdle()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;互动待机状态，可被其他状态打断&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;listen()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;倾听状态，数字人正在接收用户语音输入&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;think()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;思考状态，用户提问后、AI 尚未回复时的过渡&lt;/td&gt;&lt;td&gt;无&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;speak(ssml, isStart, isEnd)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;驱动数字人说话，支持流式分段调用&lt;/td&gt;&lt;td&gt;&lt;code&gt;ssml&lt;/code&gt;：文本/SSML；&lt;code&gt;isStart/isEnd&lt;/code&gt;：标记是否为流式的起止片段&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;SDK 的能力到&quot;让数字人说话&quot;为止，至于说什么、怎么说，需要我们自己对接大模型。这其实和普通的 AI 对话开发没什么区别，核心就是把 AI 的输出通过 &lt;code&gt;sdk.speak()&lt;/code&gt; 播报出来。&lt;/p&gt;
&lt;p&gt;文字对话功能的核心是调用 LLM 获取回复，将结果传入 &lt;code&gt;sdk.speak()&lt;/code&gt; 即可。配合流式输出，可以分段调用 &lt;code&gt;speak()&lt;/code&gt;，每段传不同的 &lt;code&gt;isStart/isEnd&lt;/code&gt; 标记，实现边生成边播报。&lt;/p&gt;
&lt;p&gt;语音对话需要借助第三方 ASR 语音识别服务，将用户语音实时转为文本，送给 AI 处理后，再将结果喂给 &lt;code&gt;sdk.speak()&lt;/code&gt;。整个链路就是：语音 → ASR → 文本 → LLM → 回复 → SDK 播报。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-9&quot;&gt;总结&lt;/h2&gt;
&lt;p&gt;本文分享了一个将 3D 虚拟数字人嵌入任意网页的方案：&lt;strong&gt;通过魔珐星云具身驱动 SDK 实现低延迟、高表现力的数字人渲染与交互，再借助油猴脚本的注入能力，让它出现在任意网页上。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;整个方案的代码量并不大，技术栈也很简单：SDK 负责&quot;形象 + 表达&quot;，油猴负责&quot;无处不在&quot;，LLM 负责&quot;大脑&quot;。三者组合起来，就把一个原本只能在对话框里回复文字的 AI，变成了一个有形象、能说话、随叫随到的数字伙伴。&lt;/p&gt;
&lt;p&gt;如果你也在做大模型应用，不妨试试这个方向——让 AI 不再只是一个输入框，而是真正&quot;站在&quot;用户面前的陪伴者。&lt;/p&gt;</description><link>https://juejin.cn/post/7661754132202766371</link><guid isPermaLink="false">https://juejin.cn/post/7661754132202766371</guid><pubDate>Mon, 13 Jul 2026 04:44:06 GMT</pubDate><author>石小石Orz</author><category></category><category>前端</category><category>人工智能</category></item><item><title>不用框架，手搓 AI Agent：(一) 先让它跑起来</title><description>&lt;blockquote&gt;
&lt;p&gt;🚀 &lt;strong&gt;插播一条&lt;/strong&gt;：欢迎来到 &lt;strong&gt;&lt;a href=&quot;https://juejin.cn/column/7661531339729829926&quot; target=&quot;_blank&quot; title=&quot;https://juejin.cn/column/7661531339729829926&quot;&gt;不用框架，手搓 AI Agent&lt;/a&gt;&lt;/strong&gt; 👈 专栏！这是咱们的第一站。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;别被 Agent 这个词绕晕了，它的核心其实就两部分。&lt;/p&gt;
&lt;p&gt;我们平时使用的 &lt;strong&gt;Cursor、Trae、Claude Code、Codex&lt;/strong&gt;，本质上都属于 AI Agent。
很多人第一次接触 Agent，会觉得它特别神秘，好像背后藏着一套非常复杂、深不可测的技术。
但如果给 AI Agent“去个魅”，它其实可以简化成一个非常直观的公式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Agent = 大模型（大脑）+ Harness（缰绳）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;大模型负责思考，Harness 负责让它真正把事情做好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-id=&quot;heading-0&quot;&gt;&lt;code&gt;先来“放个毒”，看看经过本系列的打磨，我们最终会亲手搞出一个怎样的“完全体”&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7d60aab406204deaac6090027f939d77~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=gT4fNVLr5RyyvePzYf5Nlx5ZMgw%3D&quot; alt=&quot;Kapture 2026-07-13 at 10.07.08.gif&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;如上图所示，它将拥有类似claudecode的终端交互、能感知你当前的工作目录，还能自主决定如何帮你完成研发任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;是不是感觉很酷？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但这些能力并不是模型天生就有的。模型本身只负责理解需求、思考下一步；至于如何进入你的工作目录、调用终端、读写文件、执行命令，并在失败后继续尝试，靠的是另一套运行机制。&lt;/p&gt;
&lt;p&gt;这套机制，就是 Harness。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;Harness 到底是什么？&lt;/h2&gt;
&lt;p&gt;Harness 直译过来是“马具”或者“缰绳”。&lt;/p&gt;
&lt;p&gt;放在 AI 工程里，这个比喻其实非常形象。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;大模型就像一匹能力很强的马&lt;/strong&gt;：动力十足、创意丰富，但有时候也比较“冲动”。如果没有约束，它写代码时可能会乱用依赖、执行危险命令，甚至产生幻觉，然后一本正经地胡说八道。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Harness 就像套在马身上的缰绳&lt;/strong&gt;：它负责约束和引导大模型，把模型的想法转化成一个个可执行的工程步骤，确保它既能跑起来，也不至于跑偏。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;举个最简单的例子。&lt;/h3&gt;
&lt;p&gt;当你对 Claude Code 或 Codex 说：帮我修复这个项目里的登录 Bug。&lt;/p&gt;
&lt;p&gt;背后的大模型并不能凭空读取你的代码，也不能直接修改文件。&lt;/p&gt;
&lt;p&gt;真正让它拥有这些能力的，是 Harness 为它提供的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取文件&lt;/li&gt;
&lt;li&gt;搜索代码&lt;/li&gt;
&lt;li&gt;修改代码&lt;/li&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;li&gt;检查运行结果&lt;/li&gt;
&lt;li&gt;限制危险操作&lt;/li&gt;
&lt;li&gt;在失败后继续调整方案&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，只有大模型还不够。&lt;/p&gt;
&lt;p&gt;没有 Harness 的大模型，更像是一个会聊天、会出主意的“大脑”；接上 Harness 之后，它才能真正读代码、改文件、执行命令，成为一个可以帮我们完成任务的 AI Agent。&lt;/p&gt;
&lt;p&gt;大模型决定它能不能想明白，Harness 决定它能不能把事情做好。&lt;/p&gt;
&lt;p&gt;而这个系列要做的事情，就是和你一起从零开始，亲手打磨出这样一套 Harness“缰绳”系统。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;今天的目标：先让它跑起来&lt;/h2&gt;
&lt;p&gt;罗马不是一天建成的。我们把复杂的高级能力先放一边，任何一个强大的 AI Agent，都有一个极其朴素的起点。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本系列的第一篇，我们就来亲手敲下它的第一行核心代码，调通这条最基础的“一问一答”最短链路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c61cad7b6f4148619a3d337ef6ee63d9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=CetzEBFqMyyf32PXkGsdtqCR%2BaM%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;我们今天第一步要实现的“最小可用版本”跑起来长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;$ npm run start -- -prompt &lt;span class=&quot;hljs-string&quot;&gt;&quot;用一句话解释什么是 TypeScript&quot;&lt;/span&gt;

AI：TypeScript 是 JavaScript 的超集，为 JavaScript 添加了静态类型能力。
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：它现在还只是“会聊天的命令行助手”，还不会读文件、改代码。但这正是后面实现 AI 编程 Agent 的地基。&lt;/p&gt;
&lt;p&gt;🚀 &lt;strong&gt;本节配套源码：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2FTeernage%2Fpowercode&quot; target=&quot;_blank&quot; title=&quot;https://github.com/Teernage/powercode&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;powercode&lt;/a&gt;&lt;/strong&gt;  👈点它&lt;/p&gt;
&lt;p&gt;如果中途遇到问题，可以对照源码排查。后续章节的代码也会持续更新，如果这个项目对你有帮助，欢迎点个 Star ⭐&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;一、准备环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js21 或 更高版本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一个 OpenAI 兼容的 API Key&lt;/strong&gt;：这是通向各大模型的“万能通行证”。无论你用 DeepSeek、GLM 还是 Kimi，它们都遵循这套行业通用协议。拿到它，就等于拿到了所有主流模型的“入场券”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先检查 Node.js 版本：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;node -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果版本低于 &lt;code&gt;v21&lt;/code&gt;，建议先升级。&lt;/p&gt;
&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/649c0772b7fc44c290ba6673e16e3fec~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=TSzd0D4quTDjmDVtJjddnWbBChY%3D&quot; alt=&quot;image.png&quot; width=&quot;70%&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;二、新建一个独立项目&lt;/h2&gt;
&lt;p&gt;新建一个文件夹powercode&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt; powercode
&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; powercode
npm init -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装依赖：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npm install openai 
npm install -D typescript @types/node
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在项目目录大致是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;powercode/
├── node_modules/
├── package.json
└── package-lock.json
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-6&quot;&gt;三、配置 TypeScript&lt;/h2&gt;
&lt;p&gt;新建 &lt;code&gt;tsconfig.json&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot; lang=&quot;json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ES2022&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;NodeNext&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;moduleResolution&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;NodeNext&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;rootDir&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;outDir&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;dist&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;strict&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;skipLibCheck&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;include&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;src/**/*.ts&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后修改 &lt;code&gt;package.json&lt;/code&gt;，将它调整为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot; lang=&quot;json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;powercode&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;private&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;tsc&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;node dist/main.js&quot;&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;openai&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;^6.0.0&quot;&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;@types/node&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;^22.0.0&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;typescript&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;^5.0.0&quot;&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;划重点&lt;/strong&gt;：注意这里添加了 &lt;code&gt;&quot;type&quot;: &quot;module&quot;&lt;/code&gt;，这是为了让我们能在 Node.js 中直接使用现代的 &lt;code&gt;import&lt;/code&gt; 语法，而不是老式的 &lt;code&gt;require&lt;/code&gt;。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-7&quot;&gt;四、配置你的大模型&lt;/h2&gt;
&lt;p&gt;在项目根目录新建 &lt;code&gt;provider.json&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot; lang=&quot;json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;protocol&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;openai&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;baseURL&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;https://api.deepseek.com&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;apiKey&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;替换成你的 API Key&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;deepseek-v4-flash&quot;&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你使用别的兼容 OpenAI 接口的服务，&lt;strong&gt;&lt;code&gt;protocol&lt;/code&gt; 保持不变，你只需要改下面这三个字段&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;baseURL&lt;/code&gt;：接口地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apiKey&lt;/code&gt;：你的密钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;model&lt;/code&gt;：模型名称&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;警告&lt;/strong&gt;：&lt;code&gt;provider.json&lt;/code&gt; 包含私人密钥，&lt;strong&gt;绝对不要&lt;/strong&gt;提交到 Git！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以我们在根目录新建 &lt;code&gt;.gitignore&lt;/code&gt; 文件：&lt;/p&gt;
&lt;p&gt;新建 &lt;code&gt;.gitignore&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-gitignore&quot; lang=&quot;gitignore&quot;&gt;node_modules
dist
provider.json
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;科普小知识&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你可能会好奇：市面上有几百种大模型，难道我们要学几百种调用方法吗？
其实不用。目前业界的 API 调用基本上被两大“普通话”统一了：&lt;strong&gt;OpenAI 协议&lt;/strong&gt; 和 &lt;strong&gt;Claude 协议&lt;/strong&gt;。尤其是 OpenAI 协议，国内的绝大多数主流模型（比如 DeepSeek、glm、通义千问、Kimi、豆包等）都完美兼容了它。&lt;/p&gt;
&lt;p&gt;所以，&lt;strong&gt;只要你学会了 OpenAI 的接入方式，稍微改一下 &lt;code&gt;baseURL&lt;/code&gt; 和 &lt;code&gt;apiKey&lt;/code&gt;，就能无缝切换到几乎任何国产模型&lt;/strong&gt;。这就是为什么我们在配置里只写这三个字段的原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;五、先写一个读取配置的模块&lt;/h2&gt;
&lt;p&gt;在powercode下创建src源码目录：&lt;/p&gt;
&lt;p&gt;新建 &lt;code&gt;powercode/src/config.ts&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; { readFile } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;node:fs/promises&quot;&lt;/span&gt;;

&lt;span class=&quot;hljs-comment&quot;&gt;/**
 * 提供商配置接口
 * 定义与 AI 提供商通信所需的配置参数
 */&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;ProviderConfig&lt;/span&gt; {
  &lt;span class=&quot;hljs-attr&quot;&gt;baseURL&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;;   &lt;span class=&quot;hljs-comment&quot;&gt;/** API 服务的基础 URL 地址 */&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;apiKey&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;;   &lt;span class=&quot;hljs-comment&quot;&gt;/** 用于身份验证的 API 密钥 */&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;model&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;;    &lt;span class=&quot;hljs-comment&quot;&gt;/** 要使用的 AI 模型名称 */&lt;/span&gt;
}

&lt;span class=&quot;hljs-comment&quot;&gt;/**
 * 加载并验证提供商配置
 *
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@returns&lt;/span&gt; Promise&amp;lt;ProviderConfig&amp;gt; 完整的提供商配置对象
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@throws&lt;/span&gt; 当 provider.json 缺失或必需字段不完整时抛出错误
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@example&lt;/span&gt;
 * ```ts
 * const config = await loadConfig();
 * // 使用配置初始化 AI 客户端
 * ```  
 */&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;loadConfig&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;): &lt;span class=&quot;hljs-title class_&quot;&gt;Promise&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-title class_&quot;&gt;ProviderConfig&lt;/span&gt;&amp;gt; {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; content = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;readFile&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;provider.json&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;utf8&quot;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; config = &lt;span class=&quot;hljs-title class_&quot;&gt;JSON&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;parse&lt;/span&gt;(content) &lt;span class=&quot;hljs-keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Partial&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-title class_&quot;&gt;ProviderConfig&lt;/span&gt;&amp;gt;;

  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!config.&lt;span class=&quot;hljs-property&quot;&gt;baseURL&lt;/span&gt; || !config.&lt;span class=&quot;hljs-property&quot;&gt;apiKey&lt;/span&gt; || !config.&lt;span class=&quot;hljs-property&quot;&gt;model&lt;/span&gt;) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Error&lt;/span&gt;(
      &lt;span class=&quot;hljs-string&quot;&gt;&quot;provider.json 配置不完整，需要提供 baseURL、apiKey 和 model。&quot;&lt;/span&gt;,
    );
  }

  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; {
    &lt;span class=&quot;hljs-attr&quot;&gt;baseURL&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;baseURL&lt;/span&gt;,
    &lt;span class=&quot;hljs-attr&quot;&gt;apiKey&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;apiKey&lt;/span&gt;,
    &lt;span class=&quot;hljs-attr&quot;&gt;model&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;model&lt;/span&gt;,
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它告诉 TypeScript：配置对象必须包含这三个字符串字段。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;说白了，这就相当于你给 AI 拨打电话必需的“三件套”：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;baseURL&lt;/code&gt; 是区号；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apiKey&lt;/code&gt; 是你的专属通讯证；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;model&lt;/code&gt; 是你要找的哪位接线员。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;准备好这三样，下一步我们就能真正向大模型发请求、让它干活了。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-9&quot;&gt;六、封装一次大模型请求&lt;/h2&gt;
&lt;p&gt;新建 &lt;code&gt;src/chat.ts&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;OpenAI&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;openai&quot;&lt;/span&gt;;
&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; { &lt;span class=&quot;hljs-title class_&quot;&gt;ProviderConfig&lt;/span&gt; } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;./config.js&quot;&lt;/span&gt;;

&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;ChatClient&lt;/span&gt; {
  &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;client&lt;/span&gt;: &lt;span class=&quot;hljs-title class_&quot;&gt;OpenAI&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// OpenAI 客户端实例&lt;/span&gt;

  &lt;span class=&quot;hljs-comment&quot;&gt;/**
   * 初始化 ChatClient 实例
   *
   * &lt;span class=&quot;hljs-doctag&quot;&gt;@param&lt;/span&gt; config 提供商配置对象
   */&lt;/span&gt;
  &lt;span class=&quot;hljs-title function_&quot;&gt;constructor&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;readonly&lt;/span&gt; config: ProviderConfig&lt;/span&gt;) {
    &lt;span class=&quot;hljs-variable language_&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;client&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;OpenAI&lt;/span&gt;({
      &lt;span class=&quot;hljs-attr&quot;&gt;apiKey&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;apiKey&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;baseURL&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;baseURL&lt;/span&gt;,
    });
  }
  
  &lt;span class=&quot;hljs-comment&quot;&gt;/**
   * 向 AI 模型发送问题并获取回答
   *
   * &lt;span class=&quot;hljs-doctag&quot;&gt;@param&lt;/span&gt; prompt 用户的问题或指令
   * &lt;span class=&quot;hljs-doctag&quot;&gt;@returns&lt;/span&gt; 模型回答的内容
   */&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;ask&lt;/span&gt;(&lt;span class=&quot;hljs-attr&quot;&gt;prompt&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;): &lt;span class=&quot;hljs-title class_&quot;&gt;Promise&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;&amp;gt; {
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; response = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;hljs-variable language_&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;client&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;chat&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;completions&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;create&lt;/span&gt;({
      &lt;span class=&quot;hljs-attr&quot;&gt;model&lt;/span&gt;: &lt;span class=&quot;hljs-variable language_&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;config&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;model&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;messages&lt;/span&gt;: [
        {
          &lt;span class=&quot;hljs-attr&quot;&gt;role&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;system&quot;&lt;/span&gt;,
          &lt;span class=&quot;hljs-attr&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;你是power-code,一个由驾驭工程驱动的骨灰级研发助手,请使用中文回答。&quot;&lt;/span&gt;,
        },
        {
          &lt;span class=&quot;hljs-attr&quot;&gt;role&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;user&quot;&lt;/span&gt;,
          &lt;span class=&quot;hljs-attr&quot;&gt;content&lt;/span&gt;: prompt,
        },
      ],
    });

    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; response.&lt;span class=&quot;hljs-property&quot;&gt;choices&lt;/span&gt;[&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;]?.&lt;span class=&quot;hljs-property&quot;&gt;message&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;content&lt;/span&gt; ?? &lt;span class=&quot;hljs-string&quot;&gt;&quot;模型没有返回内容。&quot;&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先用大白话解释这段代码。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;OpenAI&lt;/code&gt; 是官方 SDK 提供的客户端。即使你接入的不是 OpenAI，只要接入的模型服务兼容 OpenAI 的接口格式，通常也能这样调用&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-variable language_&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;client&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;OpenAI&lt;/span&gt;({
  &lt;span class=&quot;hljs-attr&quot;&gt;apiKey&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;apiKey&lt;/span&gt;,
  &lt;span class=&quot;hljs-attr&quot;&gt;baseURL&lt;/span&gt;: config.&lt;span class=&quot;hljs-property&quot;&gt;baseURL&lt;/span&gt;,
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真正发请求的核心是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-variable language_&quot;&gt;this&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;client&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;chat&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;completions&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;create&lt;/span&gt;(...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们把对话内容放进 &lt;code&gt;messages&lt;/code&gt; 数组：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot; lang=&quot;json&quot;&gt;messages&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    role&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    content&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;你是power-code,一个由驾驭工程驱动的骨灰级研发助手，请使用中文回答。&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    role&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    content&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; prompt&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;system&lt;/code&gt;：给 AI 定规则，例如让它用中文、保持某种身份。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt;：用户真正提出的问题。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assistant&lt;/code&gt;：AI 历史回答的位置，后续实现多轮对话时会用到。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前我们只有一问一答，所以只需要 &lt;code&gt;system&lt;/code&gt; 和 &lt;code&gt;user&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-10&quot;&gt;七、写命令行入口&lt;/h2&gt;
&lt;p&gt;新建 &lt;code&gt;src/main.ts&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; { &lt;span class=&quot;hljs-title class_&quot;&gt;ChatClient&lt;/span&gt; } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;./chat.js&quot;&lt;/span&gt;;
&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; { loadConfig } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;./config.js&quot;&lt;/span&gt;;

&lt;span class=&quot;hljs-comment&quot;&gt;/**
 * 从命令行参数中提取用户问题
 *
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@param&lt;/span&gt; args 命令行参数数组
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@returns&lt;/span&gt; 用户的问题或指令
 * &lt;span class=&quot;hljs-doctag&quot;&gt;@throws&lt;/span&gt; 当 -prompt 参数缺失或后面为空时抛出错误
 */&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;getPrompt&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;args: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;[]&lt;/span&gt;): &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; promptIndex = args.&lt;span class=&quot;hljs-title function_&quot;&gt;indexOf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;-prompt&quot;&lt;/span&gt;);

  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (promptIndex === -&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Error&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;请通过 -prompt 传入问题，例如：-prompt &quot;你好&quot;&#39;&lt;/span&gt;);
  }

  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; prompt = args[promptIndex + &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;];

  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!prompt) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Error&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;-prompt 后面不能是空内容。&quot;&lt;/span&gt;);
  }

  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; prompt;
}

&lt;span class=&quot;hljs-comment&quot;&gt;/**
 * 主函数，处理命令行参数并调用 ChatClient 发送问题
 */&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; prompt = &lt;span class=&quot;hljs-title function_&quot;&gt;getPrompt&lt;/span&gt;(process.&lt;span class=&quot;hljs-property&quot;&gt;argv&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;slice&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;));
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; config = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;loadConfig&lt;/span&gt;();
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; client = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;ChatClient&lt;/span&gt;(config);

  &lt;span class=&quot;hljs-variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;AI 正在思考...\n&quot;&lt;/span&gt;);

  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; answer = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; client.&lt;span class=&quot;hljs-title function_&quot;&gt;ask&lt;/span&gt;(prompt);

  &lt;span class=&quot;hljs-variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;`AI：&lt;span class=&quot;hljs-subst&quot;&gt;${answer}&lt;/span&gt;`&lt;/span&gt;);
}

&lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;().&lt;span class=&quot;hljs-keyword&quot;&gt;catch&lt;/span&gt;(&lt;span class=&quot;hljs-function&quot;&gt;(&lt;span class=&quot;hljs-params&quot;&gt;error: &lt;span class=&quot;hljs-built_in&quot;&gt;unknown&lt;/span&gt;&lt;/span&gt;) =&amp;gt;&lt;/span&gt; {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; message = error &lt;span class=&quot;hljs-keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Error&lt;/span&gt; ? error.&lt;span class=&quot;hljs-property&quot;&gt;message&lt;/span&gt; : &lt;span class=&quot;hljs-title class_&quot;&gt;String&lt;/span&gt;(error);
  &lt;span class=&quot;hljs-variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;error&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;`启动失败：&lt;span class=&quot;hljs-subst&quot;&gt;${message}&lt;/span&gt;`&lt;/span&gt;);
  process.&lt;span class=&quot;hljs-title function_&quot;&gt;exit&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的关键是 Node.js 提供的一个内置数组：&lt;code&gt;process.argv&lt;/code&gt;。它会把我们在命令行敲下的每一段文字收集起来。&lt;/p&gt;
&lt;p&gt;当我们执行这行命令时：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;npm run start -- prompt &lt;span class=&quot;hljs-string&quot;&gt;&quot;你好&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;小提示&lt;/strong&gt;：中间的 &lt;code&gt;--&lt;/code&gt; 是为了告诉 npm：“后面的参数请原封不动地传给我的代码，不要你自己处理掉。”
程序内部收到的完整的 &lt;code&gt;process.argv&lt;/code&gt; 数组，其实长这样：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;[
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;/usr/local/bin/node&quot;&lt;/span&gt;,       &lt;span class=&quot;hljs-comment&quot;&gt;// 第 0 项：Node.js 环境所在的路径&lt;/span&gt;
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;/你的项目路径/dist/main.js&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// 第 1 项：当前正在执行的脚本路径&lt;/span&gt;
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;-prompt&quot;&lt;/span&gt;,                   &lt;span class=&quot;hljs-comment&quot;&gt;// 第 2 项：我们传的参数名&lt;/span&gt;
  &lt;span class=&quot;hljs-string&quot;&gt;&quot;你好&quot;&lt;/span&gt;                       &lt;span class=&quot;hljs-comment&quot;&gt;// 第 3 项：我们传的参数内容&lt;/span&gt;
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你看，前两项都是系统自带的路径信息，对我们没有任何用处。&lt;/p&gt;
&lt;p&gt;所以，我们要用 &lt;code&gt;.slice(2)&lt;/code&gt; 像切蛋糕一样，把前面那两项切掉，只保留从第 2 项开始的真实参数：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;[&lt;span class=&quot;hljs-string&quot;&gt;&quot;-prompt&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;你好&quot;&lt;/span&gt;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;拿到这个干净的数组后，&lt;code&gt;getPrompt&lt;/code&gt; 函数的工作就非常傻瓜化了：去数组里找 &lt;code&gt;-prompt&lt;/code&gt; 在哪个位置，然后把紧跟在它后面的那句话（也就是 &lt;code&gt;&quot;你好&quot;&lt;/code&gt;）提取出来，这就是用户真正要问 AI 的问题。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-11&quot;&gt;八、编译并运行&lt;/h2&gt;
&lt;p&gt;一切准备就绪，现在我们要把 TS 代码转化为 Node.js 可执行的 JS 代码，并让 Agent 跑起来。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-12&quot;&gt;1. 编译代码&lt;/h3&gt;
&lt;p&gt;执行构建指令，将 &lt;code&gt;src&lt;/code&gt; 下的 TypeScript 代码编译至 &lt;code&gt;dist&lt;/code&gt; 目录：&lt;/p&gt;
&lt;p&gt;如果没有报错，项目中会多出一个 &lt;code&gt;dist&lt;/code&gt; 目录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;powercode/
├── dist/
│   ├── chat.&lt;span class=&quot;hljs-property&quot;&gt;js&lt;/span&gt;
│   ├── config.&lt;span class=&quot;hljs-property&quot;&gt;js&lt;/span&gt;
│   └── main.&lt;span class=&quot;hljs-property&quot;&gt;js&lt;/span&gt;
└── src/
    ├── chat.&lt;span class=&quot;hljs-property&quot;&gt;ts&lt;/span&gt;
    ├── config.&lt;span class=&quot;hljs-property&quot;&gt;ts&lt;/span&gt;
    └── main.&lt;span class=&quot;hljs-property&quot;&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-id=&quot;heading-13&quot;&gt;2. 让 Agent 跑起来&lt;/h3&gt;
&lt;p&gt;接下来，调用我们的系统，并传入你的第一个指令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;npm run start -- -prompt &lt;span class=&quot;hljs-string&quot;&gt;&quot;用一句话解释什么是 TypeScript&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/48ffe3559afd429b9dc8d336be2f9613~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=819xFl7Ybm%2BWtImh8JDEuBEKFFg%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;恭喜，你已经写出了第一个命令行 AI 助手。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-14&quot;&gt;九、我们刚刚到底完成了什么？&lt;/h2&gt;
&lt;p&gt;把整件事画成一条数据流，就是：&lt;/p&gt;
&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f803f4d2309a42b39b964f72be0571d5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=r%2BCpX7KYGYpBpwbUXE%2FubUnj8rQ%3D&quot; alt=&quot;image.png&quot; width=&quot;30%&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
&lt;p&gt;目前的项目结构也非常简单：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot; lang=&quot;bash&quot;&gt;powercode/
├── src/
│   ├── config.ts    &lt;span class=&quot;hljs-comment&quot;&gt;# 读取和校验模型配置&lt;/span&gt;
│   ├── chat.ts      &lt;span class=&quot;hljs-comment&quot;&gt;# 请求大模型&lt;/span&gt;
│   └── main.ts      &lt;span class=&quot;hljs-comment&quot;&gt;# 命令行入口&lt;/span&gt;
├── provider.json    &lt;span class=&quot;hljs-comment&quot;&gt;# 本地模型配置，不提交&lt;/span&gt;
├── .gitignore
├── package.json
└── tsconfig.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;每个文件只有一个职责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;config.ts&lt;/code&gt; 不关心如何请求模型；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chat.ts&lt;/code&gt; 不关心命令行参数怎么解析；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.ts&lt;/code&gt; 只负责把它们串起来。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种拆分方式会在后面越来越重要。因为当我们加入读文件、修改代码、执行命令等能力后，项目不会轻易变成一团乱麻。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-15&quot;&gt;十一、这算 AI Agent 吗？&lt;/h2&gt;
&lt;p&gt;严格来说，还不算。&lt;/p&gt;
&lt;p&gt;现在的程序只有：&lt;/p&gt;
&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/222ab2f845fd4ea2983559b3e0ab69f4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=rwPufNGrC0rPJF%2FznpaMG1pHVL0%3D&quot; alt=&quot;image.png&quot; width=&quot;50%&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
&lt;p&gt;而一个真正能帮我们完成编程任务的 Agent，至少还要具备：&lt;/p&gt;
&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d2c633938e2a44dd9e524af2ad71b7f7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN5LiA5qC355qE5bCR5bm0Xw==:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784642175&amp;amp;x-signature=CqvK%2BGTP8OpLfwPO9RdpvCCv%2BkQ%3D&quot; alt=&quot;image.png&quot; width=&quot;50%&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
&lt;p&gt;这也是下一篇要解决的问题。&lt;/p&gt;
&lt;p&gt;下一篇，我们会给这个助手发一个“工具箱”，让 AI 不只是回答问题，而是能够主动请求读取项目里的文件。到那一步，它才真正开始具备 Agent 的味道。&lt;/p&gt;</description><link>https://juejin.cn/post/7661531893103935539</link><guid isPermaLink="false">https://juejin.cn/post/7661531893103935539</guid><pubDate>Mon, 13 Jul 2026 02:13:38 GMT</pubDate><author>不一样的少年_</author><category></category><category>前端</category><category>后端</category><category>Agent</category></item><item><title>AI 编程普及，初学者还要不要学习基础语法？</title><description>&lt;p&gt;大家好，我是双越。&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fwww.wangeditor.com%2F&quot; target=&quot;_blank&quot; title=&quot;https://www.wangeditor.com/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;wangEditor&lt;/a&gt; 作者，前百度 滴滴 资深前端工程师，慕课网精英讲师，PMP，&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fwww.mianshipai.com%2F&quot; target=&quot;_blank&quot; title=&quot;https://www.mianshipai.com/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;前端面试派&lt;/a&gt; 作者。&lt;/p&gt;
&lt;p&gt;我正致力于两个项目的开发和升级，感兴趣的可以私信我，加入项目小组。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fzhitalk.chat%2F&quot; target=&quot;_blank&quot; title=&quot;https://zhitalk.chat/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;智语&lt;/a&gt; 带你从 0 开发一个 AI Agent 智能体，真实发布上线，像 openclaw 小龙虾一样。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fwww.huashuiai.com%2F&quot; target=&quot;_blank&quot; title=&quot;https://www.huashuiai.com/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;划水AI&lt;/a&gt; 前端转全栈，从 0 开发一个复杂、高难度、全流程的全栈项目，真实发布上线。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;开始&lt;/h2&gt;
&lt;p&gt;AI 编程正在快速普及，几乎所有开发者都在用 AI 写代码，效率提升是肉眼可见的：以前一天的工作量，现在半小时就能搞定，一天写出几千行代码已经不是新鲜事。&lt;/p&gt;
&lt;p&gt;在这样的背景下，一个问题被越来越多人提出来：对于编程初学者，还要不要像过去那样，从变量、循环、函数这些基础语法开始，一点点啃下去？&lt;/p&gt;
&lt;p&gt;学，速度很慢。语法这东西本身没什么技术含量，大量时间花在记忆规则、调试拼写错误、理解各种&quot;为什么这里要加分号&quot;上，性价比很低，尤其是当 AI 几秒钟就能写出正确代码的时候，这种投入显得更加低效。&lt;/p&gt;
&lt;p&gt;不学，又不放心。AI 写的代码你看不懂，出了 bug 你没法排查，项目稍微复杂一点，你就完全丧失了掌控力，只能祈祷 AI 不要犯错。&lt;/p&gt;
&lt;p&gt;这个问题乍一看好像没有标准答案，但如果换个角度想——也许我们问错了问题。真正值得讨论的不是&quot;要不要学语法&quot;，而是&quot;在 AI 编程时代，程序员的核心能力到底是什么&quot;。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;技术栈知识体系&lt;/h2&gt;
&lt;p&gt;我是一名前端开发，最近在学习 Java 和 Spring Boot。借助 AI 编程，我确实不需要死抠语法细节：泛型怎么写、注解怎么加、某个 API 的具体参数顺序，这些交给 AI 就够了。&lt;/p&gt;
&lt;p&gt;但与此同时，我发现自己面对的是一个更高维度的要求：你要熟悉这个技术栈完整的知识体系。&lt;/p&gt;
&lt;p&gt;这个体系当然也可以通过 AI 获取——你问它 Spring Boot 项目该怎么组织，它能给你讲得头头是道。但问题在于，如果你自己完全没学过、不熟悉这个领域，AI 讲的内容你根本听不懂，更别说做出判断了。这就好比一个从没学过外语的人拿着翻译软件出国，软件能帮你翻译每一句话，但你依然无法理解对方话里的潜台词和文化背景。&lt;/p&gt;
&lt;p&gt;以 Java 开发 Web 服务端为例，最基础的服务端知识体系大致包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;框架（Spring Boot、SSM 等）&lt;/li&gt;
&lt;li&gt;数据库（MySQL、事务、索引设计）&lt;/li&gt;
&lt;li&gt;消息队列（RabbitMQ、Kafka）&lt;/li&gt;
&lt;li&gt;缓存（Redis）&lt;/li&gt;
&lt;li&gt;文件存储（对象存储、CDN）&lt;/li&gt;
&lt;li&gt;部署（Docker、CI/CD）&lt;/li&gt;
&lt;li&gt;日志与监控（日志采集、链路追踪、指标统计）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对一个初学者来说，掌握这一整套体系，远比学会 Java 语法本身要难得多，也重要得多。所以与其纠结&quot;要不要学语法&quot;，不如换个思路：从这些更贴近工程实际、维度相对更低的知识点开始学起，语法反而会在使用 AI 编程的过程中自然而然地被理解。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;AI 编程主要把控什么&lt;/h2&gt;
&lt;p&gt;技术栈知识体系这个话题实在太大，不是一篇文章能讲完的。回到编程本身，在 AI 编程模式下，我们不需要、也不建议自己手动敲代码，但作为开发者，有几件事必须由你亲自把控。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一，技术选型。&lt;/strong&gt; 用什么编程语言、什么框架、依赖哪些工具和第三方服务，这些决策直接决定了项目的技术边界和后续的可维护性。AI 可以给你列出几套方案的优劣，但选哪个、为什么选，是你的责任。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二，项目架构。&lt;/strong&gt; 代码目录怎么组织、模块之间怎么划分、数据结构怎么设计、系统的扩展性如何预留，这些是决定项目能不能&quot;长大&quot;的关键。架构设计得好，后期加功能、改需求都轻松；设计得差，代码很快就会变成一团乱麻，AI 写得再快也救不了一个烂架构。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三，验收标准。&lt;/strong&gt; 你让 AI 写代码，必须清楚地告诉它要达到什么要求、满足哪些功能和业务流程，绝不能让它&quot;自由发挥&quot;。需求描述得越具体、边界条件交代得越清楚，AI 交付的结果就越可靠。反过来，如果你自己都说不清楚要什么，那再强的 AI 也帮不了你。&lt;/p&gt;
&lt;p&gt;以上这三件事，你都可以让 AI 参与讨论、给出建议，但最终的决策权必须留在你自己手里。这其实也是 AI 编程时代对开发者能力要求的一次转移：从&quot;会不会写代码&quot;转向&quot;会不会做判断&quot;。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-3&quot;&gt;善用测试&lt;/h2&gt;
&lt;p&gt;很多人担心 AI 写的代码里藏着漏洞，于是想着要逐行审核 AI 产出的每一段代码。&lt;/p&gt;
&lt;p&gt;这种做法就好比，你是一个团队的负责人，你担心下属做事不靠谱，于是事无巨细地审核他做的每一个步骤、每一个动作。抱着这种心态做事，凡事都要亲力亲为、事必躬亲，团队是无法真正做大做强的——你的精力终究是有限的，靠人力审核代码的方式，在 AI 一天能产出几千行代码的效率面前，根本跟不上节奏。&lt;/p&gt;
&lt;p&gt;更靠谱的做法是：你不需要审核 AI 写的每一行代码，而是让它把测试写好，包括单元测试和集成测试。&lt;/p&gt;
&lt;p&gt;具体来说，你可以规定测试用例必须覆盖所有需求涉及的功能点，并且要求每一次代码改动之后，所有单元测试都必须通过。你只需要把控好测试用例的设计和覆盖的业务场景，剩下的交给测试去验证——只要测试真实、全面，并且全部通过，这种质量保证方式其实比你自己肉眼扫一遍代码要靠谱得多，也快得多。&lt;/p&gt;
&lt;p&gt;换句话说，AI 编程时代，测试不再只是&quot;锦上添花&quot;的工程规范，而是你和 AI 之间建立信任的核心机制。你把关的对象，从&quot;代码写得对不对&quot;变成了&quot;测试设计得全不全&quot;，这本身就是一种能力升级。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-4&quot;&gt;最后&lt;/h2&gt;
&lt;p&gt;AI 编程普及之后，初学者不必再从零开始死磕基础语法，也不需要逐行审核 AI 写出的每一行代码——这两件事，在过去是程序员的立身之本，但在今天，它们的重要性正在被重新评估。&lt;/p&gt;
&lt;p&gt;真正值得花时间投入的，是做好技术选型、设计合理的技术方案，同时让 AI 承担起单元测试和集成测试的编写工作，并且明确规范好 AI 编程的验收标准。这三件事做扎实了，AI 才能真正成为你的生产力放大器，而不是一个让你提心吊胆的黑盒。&lt;/p&gt;
&lt;p&gt;随着工作经验的增长，你会逐步掌握所在技术栈的完整知识体系——从框架到数据库，从消息队列到部署运维——这个过程本身，就是从&quot;会用 AI 写代码&quot;到&quot;能驾驭 AI 做工程&quot;的进阶之路。走到这一步，你依然会是一名优秀的程序员，只是你的核心竞争力，已经从&quot;熟练敲代码&quot;变成了&quot;精准做判断&quot;。&lt;/p&gt;</description><link>https://juejin.cn/post/7661117411174350890</link><guid isPermaLink="false">https://juejin.cn/post/7661117411174350890</guid><pubDate>Mon, 13 Jul 2026 01:07:43 GMT</pubDate><author>双越AI_club</author><category>人工智能</category><category>全栈</category><category>AI编程</category><category>Agent</category></item><item><title>Flutter Windows 开始支持 Impeller ，还修复了多窗口 bug</title><description>&lt;p&gt;因为这段时间一直在使用 Flutter 多窗口的原因，有一个 windows 多窗口的 bug 一直挺难受的，就是在切换到项目子窗口的时候，会默认激化主窗口，之后才能再次点击回到子窗口：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0044fb9009d54a2398ea6da47023e990~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oGL54yrZGXlsI_pg60=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784509423&amp;amp;x-signature=fj6g%2Fq0Fh6eeuW9rdEAlnTMFS5U%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;更准确说是，就是激活一个 child &lt;code&gt;RegularWindow&lt;/code&gt; 后，主窗口会重新回到前台并盖住它。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个问题的诱因很多，但是实际上主要就是代码写的太草台。&lt;/p&gt;
&lt;p&gt;原因之一是在 Engine 里，Engine 收到 Windows 的 &lt;code&gt;WM_ACTIVATE&lt;/code&gt; 消息时，不管窗口是激活还是失活，都会执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-kotlin&quot; lang=&quot;kotlin&quot;&gt;FocusRootViewOf(&lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是让当前窗口里的 Flutter view 获得焦点，&lt;strong&gt;但是问题在于，当主窗口正在失去焦点时，它也会执行这句&lt;/strong&gt;，然后就导致主窗口本来应该退到后面，然后又主动 &lt;code&gt;SetFocus&lt;/code&gt; 自己，然后 Windows 又把主窗口重新激活并拉到最前面。&lt;/p&gt;
&lt;p&gt;这个 Bug 就算了，&lt;strong&gt;主要是 Flutter framework 还把多个窗口的 focus tree 挂错了层级&lt;/strong&gt;，Flutter 的多窗口里，每个窗口都有自己的 &lt;code&gt;View&lt;/code&gt; ，但 Framework 里子窗口的 &lt;code&gt;FocusScope&lt;/code&gt; 居然还会有挂在父窗口的 &lt;code&gt;FocusScope&lt;/code&gt; 下面的情况，这样会造成一个新问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;子窗口获得焦点时，主窗口的 focus scope 也被认为“有焦点”，然后主窗口又又又通知 engine：“我有焦点了，把我的 native window 激活”，然后又又又又会把主窗口拉到前面····&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而且整个过程，&lt;strong&gt;也没有判断是否已经有另一个窗口拿到焦点&lt;/strong&gt;，这就导致这个 Bug 是综合好几个地方导致，之前好久一直没能根本修复问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一直只能写兜底代码来强切。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不过针对这三个问题，最近终于修复了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果收到的是 &lt;code&gt;WA_INACTIVE&lt;/code&gt;，也就是窗口正在失活，就直接返回，不再抢焦点&lt;/li&gt;
&lt;li&gt;每个 &lt;code&gt;View&lt;/code&gt; 的 focus subtree 直接挂到全局 root scope 下&lt;/li&gt;
&lt;li&gt;只有在没有其他窗口申请焦点时，才恢复旧焦点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;然后在我合并完这部分代码之后，马上又躺了另外一个坑：Flutter windows 开始启用 Impeller 了&lt;/strong&gt;，是的，Flutter 开始在 Windows 上用 OpenGLESSDF 适配 Impeller 了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/27373077e9b2440591be0bc3f97f8fa9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oGL54yrZGXlsI_pg60=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784509423&amp;amp;x-signature=%2Fcw7VGRZVSW4y2dxhgH62ZrrRsk%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后问题又出现了，&lt;strong&gt;在绘制 canvas 的时候，出现了细线看起来比 Skia 粗约 1.3–1.6 个物理像素的情况，而且更暗&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7cc19fa8e90142c9a6a13e4c0627f26c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oGL54yrZGXlsI_pg60=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784509423&amp;amp;x-signature=MlQjoVau8EURYvvXqWD1kCAuxp0%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果叠加 alpha ，还会直接失效&lt;/strong&gt;，这些以前在我项目里若隐若现的细线，在 Impeller 出来后直接就变成又大又粗：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/07354dd02f454446b4e8fa24dc33cad4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oGL54yrZGXlsI_pg60=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784509423&amp;amp;x-signature=Qs%2B7Np6MIBcnnybsvYwiV5kRVu4%3D&quot; alt=&quot;&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;根据 issue 的计算，目前不同的粗细在 Impeller 上变化倍率也不一样：&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;笔画宽度 (logical→physical)&lt;/th&gt;&lt;th&gt;Skia 覆盖度&lt;/th&gt;&lt;th&gt;Impeller 覆盖度&lt;/th&gt;&lt;th&gt;倍数&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0.5 → 0.75 px&lt;/td&gt;&lt;td&gt;0.75&lt;/td&gt;&lt;td&gt;2.00&lt;/td&gt;&lt;td&gt;&lt;strong&gt;2.7×&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1.0 → 1.5 px&lt;/td&gt;&lt;td&gt;1.50&lt;/td&gt;&lt;td&gt;2.78&lt;/td&gt;&lt;td&gt;&lt;strong&gt;1.9×&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2.0 → 3.0 px&lt;/td&gt;&lt;td&gt;3.00&lt;/td&gt;&lt;td&gt;4.59&lt;/td&gt;&lt;td&gt;&lt;strong&gt;1.5×&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4.0 → 6.0 px&lt;/td&gt;&lt;td&gt;6.00&lt;/td&gt;&lt;td&gt;7.50&lt;/td&gt;&lt;td&gt;&lt;strong&gt;1.25×&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;而且粗细还不是主要问题，主要问题是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 canvas transform 缩放下，AA 边缘也跟着被放大，导致缩放比例越大线条越糊（zoom=4 时 0.5px 线变成 12px 宽模糊带）&lt;/li&gt;
&lt;li&gt;Alpha 值被完全忽略：&lt;code&gt;0xCC&lt;/code&gt; 和 &lt;code&gt;0x66&lt;/code&gt; 渲染结果像素完全一致&lt;/li&gt;
&lt;li&gt;极细线在某些情况下整条消失&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个问题看起来像是 Impeller 的 &lt;code&gt;SDFAlpha&lt;/code&gt; 实现有问题， &lt;code&gt;smoothstep&lt;/code&gt; 范围是固定的物理像素宽度，比如 &lt;code&gt;smoothstep(-fade_size, fade_size, sdf)&lt;/code&gt; 会在笔画边缘两侧分别产生约半个 &lt;code&gt;pixel_size * aa_pixels&lt;/code&gt; 的渐变过渡带，而这个过渡带是固定宽度（取决于 &lt;code&gt;aa_pixels&lt;/code&gt; 参数，代码中设置为常量）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;然后对于 Skia 这样的解析式 AA，覆盖度 = 笔画宽度，但是对于 SDF 的 smoothstep，覆盖度 = 笔画宽度 &lt;strong&gt;+ 固定边缘过渡带&lt;/strong&gt;，所以当笔画只有 0.75 物理像素宽时，这个固定的 ~1.2px 过渡带就变得很明显，导致渲染出来的线是&quot;实心宽线 + 两侧晕染&quot;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;另外 &lt;code&gt;float half_stroke = max(stroke_width, base_pixel_size) * 0.5&lt;/code&gt; 的最小宽度钳制没有补偿 alpha ，当 &lt;code&gt;stroke_width &amp;lt; 1&lt;/code&gt; 像素时，这里会把宽度强制钳制到至少 1 个像素（&lt;code&gt;base_pixel_size&lt;/code&gt;），但没有按比例降低 alpha 来补偿。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;而Skia 的做法是亚像素线宽： 把线变成 1 像素宽但按比例降低 alpha（0.75px 线 ≈ 38% 不透明的 1px 线），Impeller 的 SDF 实现直接给了满 alpha 的 1px+ 宽线，所以看起来更暗更粗。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是 &lt;code&gt;SDFStroke&lt;/code&gt; 根本没有把 alpha 纳入计算，alpha 值到 fragment shader 时已经在别处处理，没有和宽度钳制联动。&lt;/p&gt;
&lt;p&gt;目前暂时缓解的办法有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;用 &lt;code&gt;drawRect&lt;/code&gt; 替代 &lt;code&gt;drawLine&lt;/code&gt;&lt;/strong&gt; ：用高度等于期望线宽的 filled rect 代替 stroked line，fill 路径的 UberSDF 覆盖度是正确的&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;强制使用 Skia&lt;/strong&gt;：&lt;code&gt;--no-enable-impeller&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1px 整像素线宽&lt;/strong&gt;：用 1.0 物理像素宽的线&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前看来，Impeller 在 Windows 上估计还是要经历一次 Android 的问题，不得不说，自渲染的维护成本确实高，不过多窗口在 Windows 上确实也可以用了，自从 bug 解决之后，基本没什么大问题了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/986ef52308fb4dac88d083a303c15a8c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oGL54yrZGXlsI_pg60=:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784509423&amp;amp;x-signature=U2GjVX%2FWVUQ2Rv9osvDQxPZfsC0%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;链接&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fflutter%2Fflutter%2Fissues%2F187436&quot; target=&quot;_blank&quot; title=&quot;https://github.com/flutter/flutter/issues/187436&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/flutter/flu…&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fflutter%2Fflutter%2Fissues%2F188911&quot; target=&quot;_blank&quot; title=&quot;https://github.com/flutter/flutter/issues/188911&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/flutter/flu…&lt;/a&gt;&lt;/p&gt;</description><link>https://juejin.cn/post/7661123972889559046</link><guid isPermaLink="false">https://juejin.cn/post/7661123972889559046</guid><pubDate>Mon, 13 Jul 2026 01:03:44 GMT</pubDate><author>恋猫de小郭</author><category>Android</category><category>前端</category><category>Flutter</category></item><item><title>没写一行代码！我用 ChatGPT 5.6 (Sol) 做了一个智慧充电站 3D 大屏</title><description>&lt;p&gt;先说结论。&lt;/p&gt;
&lt;p&gt;从设计稿到能在浏览器里打开、点击充电桩弹出状态面板的 3D 可视化大屏，我没有写任何一行代码，没有在 Blender 里手动拖过一次控件，也没有切过一张图。&lt;/p&gt;
&lt;p&gt;整条链路交给了 ChatGPT 5.6 (Sol)。&lt;/p&gt;
&lt;p&gt;但这篇文章不是来吹 AI 有多厉害的。我想说的是：这条路上我踩了哪些坑，以及为什么同样的工具，用法不同，结果差了十万八千里。顺便对&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3MDkwMDI0MQ%3D%3D%26mid%3D2247488698%26idx%3D1%26sn%3Dd29885e9a705b1ed2d3c2ff7f4e815ed%26scene%3D21%23wechat_redirect&quot; target=&quot;_blank&quot; title=&quot;https://mp.weixin.qq.com/s?__biz=MzU3MDkwMDI0MQ==&amp;amp;mid=2247488698&amp;amp;idx=1&amp;amp;sn=d29885e9a705b1ed2d3c2ff7f4e815ed&amp;amp;scene=21#wechat_redirect&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;有了大屏设计稿还不够，我又用Gpt-image-2把里面的素材全扒了出来&amp;nbsp;&lt;/a&gt;这篇文章做一个补充和资源切割提示词的修复。&lt;/p&gt;
&lt;p&gt;这个是我最终实现的网页效果，我觉得效果还行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/48d41afd242042e4b86391d23f59aa65~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=NoLRMUQjtn6pSmHESoMNkzv3bOk%3D&quot; alt=&quot;截屏2026-07-12 21.08.24.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-0&quot;&gt;四个步骤，每一步的输入都是上一步的输出&lt;/h2&gt;
&lt;p&gt;链路本身不复杂：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设计稿 → 切割透明素材 → Blender 自动建模 → 3D 大屏网页&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;工具组合是 Codex（ChatGPT 5.6 (Sol)）、blender、blender-mcp、还有一个是我之前做的 @lius1314/visual-dashboard-scaffold 的大屏脚手架。&lt;/p&gt;
&lt;p&gt;听起来很顺。实际上还是碰到很多的问题的，那我们按照步骤来看看整体流程遇到的问题和如何解决的吧。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 data-id=&quot;heading-1&quot;&gt;第一步：设计稿&lt;/h2&gt;
&lt;p&gt;设计稿不是一次成型的，来回定了好几轮。先是照着一张暗色科技等距沙盘风格的参考图生成第一版充电站概念图，看完觉得质感不够，又重做成最高画质的 16:9 版本。到这一步设计稿已经能用了，但为了配合后面的切图流程，我又单独出了一版预留透明背景的稿子——因为素材切割终归是要把图标、边框从背景里挖出来，源头设计稿如果本身没有为分离预留干净的边界，后面怎么切都费劲。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4b2f0e36c14a40548a337779a9aee8f5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=ok0xgwhV3Gbpd1Zswspsbzo3M84%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0822163a1c694e45b65ba95668836637~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=BCT7XYfI2JHgbBTmSAs4h%2Fqpuig%3D&quot; alt=&quot;设计稿.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;上面的设计稿是主体蓝的，我觉得做这种太多了，然后它的界面我觉得太大众了，所以我就重新设计了设计稿，下面的暗黑色的是我觉得还不错的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/961fe41c11e14ab4b20265a2849bc798~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=2ZK9HTFl3bhmimn8juGbwFNpKms%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0c7d878c6d474d76b6283a9d837e7ea2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=BYmssXu4lS8s1BRrqqjr9%2F8f0bY%3D&quot; alt=&quot;设计稿-v2.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7a154633c0624b94b12bfd4b3ec0ec0f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=7Pg3zGx3C%2Fs8SNNEO6Rs8wAavZg%3D&quot; alt=&quot;设计稿-v3.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
这一步花的时间不算少，但没出什么坑，跳过不细说，直接进第二步。&lt;/p&gt;
&lt;h2 data-id=&quot;heading-2&quot;&gt;第二步：切图&lt;/h2&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;第一版，27 个素材，全部白切&lt;/h3&gt;
&lt;p&gt;设计稿定稿后，我让 Codex 按坐标把图标、卡片边框、分割线抠出来。提示词是使用之前这篇文章的提示词&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3MDkwMDI0MQ%3D%3D%26mid%3D2247488698%26idx%3D1%26sn%3Dd29885e9a705b1ed2d3c2ff7f4e815ed%26scene%3D21%23wechat_redirect&quot; target=&quot;_blank&quot; title=&quot;https://mp.weixin.qq.com/s?__biz=MzU3MDkwMDI0MQ==&amp;amp;mid=2247488698&amp;amp;idx=1&amp;amp;sn=d29885e9a705b1ed2d3c2ff7f4e815ed&amp;amp;scene=21#wechat_redirect&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;有了大屏设计稿还不够，我又用Gpt-image-2把里面的素材全扒了出来&amp;nbsp;&lt;/a&gt;—背景色&amp;nbsp;&lt;a href=&quot;https://link.juejin.cn/?target=&quot; title=&quot;&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;#0B1426&lt;/a&gt;，抠出图标和边框，校验一下尺寸和 RGB。&lt;/p&gt;
&lt;p&gt;跑出来 27 个素材，数字上什么都对：12 个图标、7 个卡片外框、6 个装饰件，尺寸和颜色校验全部通过。&lt;/p&gt;
&lt;p&gt;然后我把它们贴到页面上。&lt;/p&gt;
&lt;p&gt;图标放大到 200%，全是虚的。原图里很多图标本身只有二三十像素见方，切图脚本直接插值放大凑数，边缘发糊，内部镂空的地方糊成一片。更离谱的是背景压根不透明——贴到页面上，只要页面背景和&amp;nbsp;&lt;a href=&quot;https://link.juejin.cn/?target=&quot; title=&quot;&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;#0B1426&lt;/a&gt;&amp;nbsp;差一点，图标周围就多出一圈矩形色块，像贴了一块膏药。&lt;/p&gt;
&lt;p&gt;27 个素材，等于白切了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4228fb4f2bca43299e13abd34d89f849~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=Nmn9Ci%2FbfFaww3Lw19cCeJkA1kk%3D&quot; alt=&quot;f79c3708756117d7b56abb141f0c1206.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;后来我想明白了。当时的提示词里有一句&quot;RGB 无 Alpha、&lt;a href=&quot;https://link.juejin.cn/?target=&quot; title=&quot;&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;#0B1426&lt;/a&gt;&amp;nbsp;背景色校验&quot;——这句话自己就打架。既然要求 RGB 无 Alpha 通道，背景只能是实色，根本谈不上透明。模型照着这句话做，做出来的东西完全符合要求，但就是没法用。&lt;/p&gt;
&lt;p&gt;这不是模型的问题，是我的问题。提示词只写了要做什么，没写怎么判断做得够不够好。没有判定标准，模型就会挑最省事的路走——插值放大代替清晰，实色背景代替真透明，给你一个看起来合格的结果。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-4&quot;&gt;第二版，把&quot;验收标准&quot;写进提示词&lt;/h3&gt;
&lt;p&gt;我没有在原来的提示词上打补丁，直接推倒重写。核心变化就一个：把&quot;描述任务&quot;改成&quot;描述任务 + 每一步验收标准&quot;。&lt;/p&gt;
&lt;p&gt;透明度按死：图标、卡片底板、标题背景、分割装饰，全部必须输出 PNG-32 RGBA，空白区域 Alpha 必须为 0。白底、黑底、棋盘格伪透明，全部列为禁止项。&lt;/p&gt;
&lt;p&gt;清晰度分路处理：原图主体大于 64 像素、轮廓还看得清，走精确抠取，保留原始像素；原图本身就糊，走受约束的高清重建——但只能照着原图的外轮廓、比例、线宽去理清边缘，不允许凭空加纹理，不允许加原本没有的细节；要是连重建的依据都不够，直接跳过并说明原因，不硬凑一个将就能用的版本。&lt;/p&gt;
&lt;p&gt;验收动作也写进流程里：每个素材切完，分别放到纯白和纯黑背景下看边缘有没有残留描边，再用透明棋盘格确认 Alpha 通道是不是真的生效。以前这一步靠人工事后抽查，现在模型给结果之前先自查一遍。&lt;/p&gt;
&lt;p&gt;另外定了一条硬规矩：一图一资产，每个元素单独成文件。之前模型有时候图省事把图标拼成一张宫格图，这版直接禁掉。&lt;/p&gt;
&lt;p&gt;用新提示词跑下来，20 个素材，四角 Alpha 全部为 0，白底黑底验边全部通过。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e0c0992b573e4192a26359064a8531ec~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=mJPUuk4WquzP1Id3DcG0bAnGz84%3D&quot; alt=&quot;e68f2b7d62692b678eca859ec23ba0cd.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/43744f73144f473ba64a39f12eedce00~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=HVQf1L51p2KRD5Z0Ea7D4V45%2BwI%3D&quot; alt=&quot;f360a77d7e33371a956fef1a7603102d.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/21e14ddafd5a4a5ebb74a13c2cd455cc~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=LCDCBYTWb0VQoWf9%2FG0lE9llYzQ%3D&quot; alt=&quot;3b01268c057227e0dab572a9ce066310.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;这里就列举了一些，貌似切割的资源还是不是很超清，但是已经很够用了。&lt;/p&gt;
&lt;p&gt;拉开效果差距的，不是换了更强的模型，是把验收标准写进了提示词。这句话值得记一下。&lt;/p&gt;
&lt;p&gt;下面是新的切割素材资源提示词，需要的可以自取&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-yaml&quot; lang=&quot;yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# 高级 UI 资产透明拆解专家 v5.1&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输入：一张完整的可视化大屏设计稿（通常为&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;×1080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG）&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输出：按批次拆分、可直接用于前端项目的独立透明&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;素材&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;你是一名专业的&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;UI&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;资产拆解与图像抠取专家。你的任务是识别设计稿中的可复用视觉元素，将它们逐个分离，输出轮廓清晰、边缘干净、背景真实透明的生产级素材。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 最高优先级硬约束&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;以下规则优先于本文其他要求；发生冲突时，以本节为准。&lt;/span&gt;

&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**真实透明**：除&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-05&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;外，全部输出&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`PNG-32&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;RGBA`。元素外区域的像素必须为&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`Alpha=0`。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**禁止伪透明**：严禁使用白底、黑底、深色底、纯色底或棋盘格模拟透明；棋盘格只能出现在预览界面，不能被写入图片。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**一图一资产**：每个文件只包含一个独立元素。禁止输出宫格、拼图、联系表、带标签的预览板。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**清晰优先**：禁止把低分辨率裁片仅靠&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Lanczos、双三次插值或锐化放大后冒充高清素材。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**忠实原稿**：保持元素的轮廓、比例、颜色、线宽、光效、透视和视觉含义，不得改变设计语言或添加原稿中不存在的细节。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**边缘无污染**：发光、阴影、羽化、抗锯齿必须正确过渡到透明，不能残留原设计稿底色形成深色描边、色边或矩形光晕。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**无法保证则不输出**：若当前工具不能导出真实&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG，必须停止并明确说明，禁止用带底色图片代替。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 任务指令&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;基于上传的设计稿，每次只处理一个批次，严禁混合输出：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【BATCH-01】通用图标：功能、状态、导航、UI&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;图标&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【BATCH-02】卡片底板：空心边框、信息容器&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【BATCH-03】标题背景：标题底板、标题装饰条&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【BATCH-04】分割与装饰：线条、角标、科技装饰&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【BATCH-05】模块背景：大面积分区底板、整体背景&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;【RESCAN】补扫：提取指定批次中遗漏的元素&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;每个视觉元素只能归入一个批次，禁止重复提取。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 输出常量&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;项目&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;要求&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|---|---|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01～04&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;背景&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;真透明，空白区域&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha=0&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01～04&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;格式&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG-32&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;RGBA，sRGB&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-05&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;格式&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG-24&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;RGB&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;或&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG-32&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;RGBA，按原稿保留&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;安全边距&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%～10%；最小&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;8px；发光元素最小&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;图标画布&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;×256px；主体占画布&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%～85%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;文件命名&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`{batch编号}_{序号}_{英文描述}.png`&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;原设计稿底色只用于识别元素和消除边缘污染，不得写入&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01～04&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;的最终图片。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 统一拆解流程&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;每个资产必须依次完成以下步骤：&lt;/span&gt;

&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**定位**：从上到下、从左到右扫描，记录元素在原图中的位置。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**判类**：根据元素的主要功能分配批次，不按颜色或大小随意归类。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**判定独立性**：仅提取轮廓完整、未被遮挡、可与周围内容分离的元素。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**选择处理方式**：&lt;/span&gt;
   &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;原图足够清晰：执行像素级精确抠取。&lt;/span&gt;
   &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;原图过小或已有明显像素化：执行一次“受约束高清重建”。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**去除背景**：删除元素之外的所有像素，使空白区域&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha=0。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**边缘净化**：消除原大屏底色造成的色边，同时保留合理的半透明抗锯齿和光效。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**规范画布**：等比缩放、居中放置、保留透明安全边距，严禁拉伸。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**双底检查**：分别放在纯白和纯黑背景上检查边缘，再用透明棋盘格确认&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;通道。&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;**独立导出**：每个元素输出为一个单独&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;文件。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 清晰度处理规则&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### A. 像素级精确抠取&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;符合以下条件时使用：原图中元素主体短边&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥64px，且轮廓、细线和内部镂空清楚可辨。&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;最大限度保留原始像素和原始视觉效果。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;不做风格化、重绘、过度锐化或对比度增强。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;如需缩放，仅进行一次等比高质量重采样。&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### B. 受约束高清重建&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;仅在元素短边&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;＜64px、明显模糊或放大后无法使用时启用。&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;原图是唯一视觉依据，重建的是同一个图标，不是创作相似图标。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;必须锁定：外轮廓、长宽比例、内部结构、线宽关系、颜色、渐变方向、发光强度和朝向。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;仅恢复清晰边缘与连续线条，不得增加纹理、符号、层级或装饰。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;简单线性图标应具有稳定线宽、连续轮廓和干净内孔。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;禁止用加粗描边、强锐化、过度发光或提高对比度制造“清晰”假象。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;若无法忠实重建，应跳过该元素并说明原因。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 复杂元素归类规则&lt;/span&gt;

&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;传递功能或状态含义&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;用于容纳或框住内容&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-02&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;专门服务于标题区域&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-03&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;用于分隔、角部点缀或科技装饰&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-04&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;构成大面积区域整体底图&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-05&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;与文字、图表或其他元素严重粘连且无法可靠分离&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;跳过&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 分批次规则&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### 【BATCH-01】通用图标&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;属于：独立功能图标、状态图标、导航图标、UI&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;操作图标。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;不属于：图表数据点、标题装饰、卡片角标、与卡片不可分离的业务图形。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;要求：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;每个图标输出为独立的&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;×256px&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;透明&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PNG。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;图标主体在画布内视觉居中，占画布&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%～85%，不得贴边。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;保留完整轮廓、内孔、细线、发光和阴影；不得断线、粘连或堵孔。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;不得把原图中包含底色的矩形裁片直接作为输出。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;不得包含任何文字、数字、水印、名称或编号。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;逐图验收：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-string&quot;&gt;PNG&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;为&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;RGBA，四角像素&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha=0&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-string&quot;&gt;透明区域没有白底、黑底、深蓝底或棋盘格像素&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-string&quot;&gt;白底和黑底预览均无矩形底、深色边、杂色边或异常光晕&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;显示清晰；200%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;显示时轮廓连续、细线无断裂、内孔未堵塞&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-string&quot;&gt;图标形状、颜色、比例和视觉含义与原稿一致&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; [ ] &lt;span class=&quot;hljs-string&quot;&gt;文件内只有一个图标且无文字&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### 【BATCH-02】卡片底板&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;属于：完整边框容器、独立面板外框。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;不属于：标题栏、模块整体背景。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;要求：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;只保留外边框、科技角、描边、边缘发光和多层装饰结构。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;移除标题、文字、数字、图标、图表、数据和内部填充。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;容器外部与中心区域均须真实透明，形成可直接叠加的空心边框。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输出宽度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥512px，高度等比，透明安全边距完整。&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### 【BATCH-03】标题背景&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;属于：标题区域底板、标题装饰条。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;不属于：完整卡片边框、独立角标。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;要求：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;移除所有标题文字，仅保留装饰底板。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;保留复杂轮廓、渐变、节奏线条和两端渐隐。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;渐隐与发光必须自然过渡到&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha=0。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输出宽度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥640px、高度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥128px。&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### 【BATCH-04】分割线与装饰&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;属于：独立分隔线、科技线条、角标装饰。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;不属于：卡片边框的一部分、标题装饰条。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;要求：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;线条和角标必须分别独立导出。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;保留线条端部羽化，并自然过渡到&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha=0。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;水平线长度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥512px；垂直线高度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥512px；角标画布&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;≥128×128px。&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;### 【BATCH-05】模块背景&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;属于：大面积分区底板、整体面板背景区域。&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;要求：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;保留纹理、网格、渐变和发光轮廓。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;移除文字、数字、图标、图表和业务内容。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;最小输出&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;×1080；若原图更大则保持原始尺寸。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;本批次本身是背景层，可保留原稿背景，不受透明背景硬约束。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 排除条件&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;遇到以下情况应跳过并说明，不得强行输出劣质资产：&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;元素被遮挡、被画面边缘截断或与其他元素无法可靠分离&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;去除文字后无法合理恢复底层结构&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;原始信息不足，无法忠实重建形状或内部结构&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;去背景后出现无法消除的严重色边、断线或透明孔洞&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输出仍包含文字、数字、业务数据或其他批次元素&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 不合格重做条件&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;以下任一条件成立，必须重做：&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;检查项&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;不合格条件&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|---|---|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;透明背景&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;四角任一像素&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha≠0，或存在纯色底/棋盘格底&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;边缘污染&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;白底或黑底预览出现原背景色描边、杂色边、矩形光晕&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;清晰度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;即可见模糊；200%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;出现断线、堵孔、双重边缘或严重锯齿&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;忠实度&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;轮廓、比例、颜色、线宽或视觉含义偏离原稿&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;完整性&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;发光、阴影、羽化或边角被裁切&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;内容纯净&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;存在文字、数字、水印、标签或其他无关元素&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;文件组织&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;多个元素被合并到同一张图&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 数量与命名&lt;/span&gt;

&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;单批次每轮最多输出&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;个资产。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;文件命名格式：`{batch编号}_{序号}_{英文描述}.png`。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;示例：`b01_03_settings-icon.png`、`b02_01_card-frame-large.png`。&lt;/span&gt;
&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;达到&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;个时停止并提示：&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;本批次已提取&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;个资产。回复「继续」提取剩余元素，或指定新批次。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## RESCAN 补扫模式&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;触发示例：&lt;/span&gt;


&lt;span class=&quot;hljs-string&quot;&gt;补扫&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01，左侧面板第&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;个图标未提取&lt;/span&gt;


&lt;span class=&quot;hljs-string&quot;&gt;仅提取明确指出的遗漏元素，不重复已完成资产；仍须通过原批次全部透明度、清晰度和忠实度检查。&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 每轮文字报告&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;报告内容不得写入图片。完成一批后，在回复中逐项列出：&lt;/span&gt;

&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;文件名&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;元素在原图中的位置&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;处理方式：`精确抠取`&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;或&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`受约束高清重建`&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;输出尺寸&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Alpha&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;检查结果&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;白底/黑底边缘检查结果&lt;/span&gt;
&lt;span class=&quot;hljs-number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;被跳过元素及原因&lt;/span&gt;

&lt;span class=&quot;hljs-meta&quot;&gt;---
&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;## 启动方式&lt;/span&gt;

&lt;span class=&quot;hljs-string&quot;&gt;请上传设计稿并指定批次，例如：&lt;/span&gt;


&lt;span class=&quot;hljs-string&quot;&gt;开始&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;BATCH-01&lt;/span&gt;


&lt;span class=&quot;hljs-string&quot;&gt;可选告知原大屏底色，它只用于去除边缘底色污染，不会写入最终透明资产。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-id=&quot;heading-5&quot;&gt;第三步：建模与烘焙&lt;/h2&gt;
&lt;p&gt;设计稿切完，四周的图标、边框、分割线交给前端 UI 层；中间那块 3D 场景插画不进前端，拿去给&amp;nbsp;blender-mcp&amp;nbsp;（地址获取&amp;nbsp;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fahujasid%2Fblender-mcp%25EF%25BC%2589%25E5%25BD%2593%25E5%258F%2582%25E7%2585%25A7%25E5%259B%25BE%25EF%25BC%258C%25E8%25AE%25A9&quot; target=&quot;_blank&quot; title=&quot;https://github.com/ahujasid/blender-mcp%EF%BC%89%E5%BD%93%E5%8F%82%E7%85%A7%E5%9B%BE%EF%BC%8C%E8%AE%A9&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;github.com/ahujasid/bl…&lt;/a&gt; Codex 照着它在 Blender 里自动建模。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b6f702ae245148e8aa9e898a6a6296c7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=AaBqrd4NE7CWnSCOzwFVLDirkaw%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;先验证了一下连通性，让 Codex 在场景里建一个正方体，确认 MCP 通道能跑通。通了之后，拿设计稿中间那张暗色科技等距沙盘图重新生成一张更完整的充电站参考图，然后让 Codex 照着这张图逐个模块建出来：场地底座、光伏顶棚、充电桩、车辆、储能电池舱、变压配电设备、控制室、发光地面线路、悬浮 UI 面板。整个过程不用人工在 Blender 里手动操作，Codex 通过 MCP 下发的是可重复执行的建模脚本，哪里不对改脚本重跑，不用从头摆一次场景。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-6&quot;&gt;第一版模型的问题：形状对了，没有质感&lt;/h3&gt;
&lt;p&gt;建出来之后感觉哪里不对，但说不清楚。盯着看了一会儿才反应过来：材质是平的。金属没有高光，地面纯色没有微纹理，玻璃没有透射，车漆像塑料——整个场景像是一个精确的玩具，而不是一个真实的场地。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e129808ab54643eda79eb3cc3c3cb22f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=SVhVh2hebixU3C3d2mlbWJLNYHg%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b7382e108d4f46ef8b9c36fc64d9a8eb~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=6azGFj0TFxq9gyGiVexCuwy0Fwo%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;
重做时把 PBR 材质流程补齐：金属件的金属度和粗糙度分开调，地坪加微纹理，玻璃做透射，车漆加清漆层，光伏板加反射。建模颗粒度也往上拉，最终建出来一千多个对象，四辆车、四套充电桩、双排储能柜、冷却设备、线槽都单独建出来，不再用简化的占位模型糊弄。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a46900b830b64ea29ddfdad79edf2a1c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=Gj4mXnCZCWkcDJ0EYnhf4FeQOSQ%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a1a3e38052174d08aa0a954920ea791e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=TSnBnudksEhXcz5zddQTOP8PfAQ%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h3 data-id=&quot;heading-7&quot;&gt;烘焙前先分组，别等前端接入了才想起来&lt;/h3&gt;
&lt;p&gt;模型精细了，但没法直接扔给前端实时渲染——这么多物体的 PBR 材质，帧率根本扛不住。所以要把光照和材质信息烘焙成贴图。但烘焙也有讲究，不是一把梭全烘成静态图就完事。&lt;/p&gt;
&lt;p&gt;在烘焙之前，我先按&quot;将来要不要交互&quot;把所有物体分了一次组。会被点击的——车辆、充电桩、终端机、电池柜、服务器、变压器、控制台，二十多个根节点，各自单独烘焙贴图，保留独立材质通道，前端可以单独控制它们的高亮和状态切换。纯粹是背景的——地面、建筑主体、光伏顶棚、固定附件，按区域合并成几组图集一起烘焙，减少渲染开销。&lt;/p&gt;
&lt;p&gt;每组贴图统一导出 BaseColor、Normal、ORM、Emission 四张。ORM 这张把 AO、粗糙度、金属度分别塞进 RGB 三个通道，前端一张图拿到三种材质信息。玻璃部件要保留透射效果，没有参与合并，单独留成透明子物体。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6425a89cb02d4ccd8f60d92250c42cc7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=y6fWGjnGtUO4VtXIepKJBNkY0EQ%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/02ab481cf8f34a889d0dce25cf8eee07~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=KIePk8npvupWUWDO03h5wwAIOKI%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;这一步的判断标准只有一条：凡是交互逻辑会碰到的物体，宁可多花烘焙成本也要保留独立性；纯粹填场景的，能合并就合并。这个分组做在烘焙阶段，而不是等到前端接入时再补——正是因为提前想清楚了，后面接脚手架的时候基本没有返工。&lt;/p&gt;
&lt;p&gt;最终实测：源 GLB 约 77.3 MB，Web 优化后压到 25.32 MB，107 张内嵌 WebP，贴图最大边 1024，23 个交互根节点完整保留。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c9585047da7e47e191076758406ada10~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=buUUxt%2BK7OflTIni8H5sHhrVtBs%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2382cb67b5bd4400a7c21d150fb11207~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=NcXVDmDXwsv%2Be1Ck9TlKt949Fc0%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-8&quot;&gt;第四步：拼成网页&lt;/h2&gt;
&lt;p&gt;前面三步产出的是三堆各自独立的东西：透明 UI 素材、烘焙好贴图的 Blender 场景、材质通道文件。这些东西要变成用户能打开的网页，还差一层骨架——页面布局、区块管理、屏幕自适应。这部分接了&amp;nbsp;&lt;code&gt;@lius1314/visual-dashboard-scaffold&lt;/code&gt;&amp;nbsp;这个大屏脚手架(可以看这篇文章&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3MDkwMDI0MQ%3D%3D%26mid%3D2247489407%26idx%3D1%26sn%3D92da83781f1eba5a9e49492b528e2871%26scene%3D21%23wechat_redirect&quot; target=&quot;_blank&quot; title=&quot;https://mp.weixin.qq.com/s?__biz=MzU3MDkwMDI0MQ==&amp;amp;mid=2247489407&amp;amp;idx=1&amp;amp;sn=92da83781f1eba5a9e49492b528e2871&amp;amp;scene=21#wechat_redirect&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;可视化大屏设计器脚手架：从设计到交付的一站式方案，&lt;/a&gt;如果你需要源码的话可以看这篇&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3MDkwMDI0MQ%3D%3D%26mid%3D2247489490%26idx%3D2%26sn%3Dc60b803e522df41621430c65005f4bc0%26scene%3D21%23wechat_redirect&quot; target=&quot;_blank&quot; title=&quot;https://mp.weixin.qq.com/s?__biz=MzU3MDkwMDI0MQ==&amp;amp;mid=2247489490&amp;amp;idx=2&amp;amp;sn=c60b803e522df41621430c65005f4bc0&amp;amp;scene=21#wechat_redirect&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;可视化大屏脚手架源码：一周下载突破 700，为什么这么多人选它？&lt;/a&gt;)，一个不绑定具体图表库的 React 大屏容器，默认 1920×1080，跟前面切图流程里素材尺寸的约束刚好对得上。&lt;/p&gt;
&lt;p&gt;业务图表或者 3D 场景不用改脚手架源码，通过&amp;nbsp;&lt;code&gt;registerBlock&lt;/code&gt;&amp;nbsp;把组件注册成一个区块 ID，脚手架负责区块的拖拽、缩放、层级和样式；预览模式下接&amp;nbsp;&lt;code&gt;autofit.js&lt;/code&gt;&amp;nbsp;做整体等比缩放，边调边看，不用来回换分辨率去试。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/55708073c81a4cbea50c4334b4fc88ec~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=Cr0tC%2FDBEwtpEgQDaaxbz71Jedw%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;烘焙阶段做的那个分组在这里起作用：中心 3D 场景包一层 Three.js 渲染组件挂到对应区块位置上，充电桩、储能柜这些单独烘焙过的物体各自是可交互对象；背景和建筑那部分只作为一张整体贴图渲染，不参与交互逻辑，渲染开销压得住。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/12d269985dff43d693c0c76fa48d67db~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=LWJ7QJDQSPB%2Fsp%2FUreFNYyv9BB0%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;切图流程产出的图标、边框、分割线，按脚手架约定的静态资源目录放进去就能用。信息卡片、告警列表、能耗曲线这些常规区块，是标准 React 组件按区块 ID 注册。整套配置最后导出成 JSON 作为初始配置加载，后面调布局不用改代码，直接在编辑模式里拖。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1718f10b09a841668521e439a254db1d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p-z5p2J:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784507574&amp;amp;x-signature=hNjBSlYwtG3ifSZObdKOVW%2BYhUo%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h2 data-id=&quot;heading-9&quot;&gt;最后&lt;/h2&gt;
&lt;p&gt;做完这整条链路，我觉得有两件事值得单独拎出来说。&lt;/p&gt;
&lt;p&gt;第一件事，提示词里有没有验收标准，决定了你拿到的是素材还是无法使用的。没有可执行的判定标准，模型永远挑最省事的路。它不是在糊弄你，它只是在照章办事——你说的章，本来就没写清楚。把验收标准显式写进提示词之后，产出质量的提升比换一个更强的模型明显得多，这让我多少有点意外。&lt;/p&gt;
&lt;p&gt;第二件事，前期的分层决策，决定了后期的返工量。烘焙阶段有没有提前想清楚哪些物体将来要被点击，直接决定前端接入时要不要重来一遍。做在正确的时间点，后面每一步都会顺；做晚了，代价是把整个场景重新烘焙一遍。&lt;/p&gt;
&lt;p&gt;Codex（ChatGPT 5.6 Sol）在切图、生成参照图、下发 Blender 建模脚本这几个环节都能给出结构化、可执行的结果，中间不需要人再补细节。这是整条链路能接起来的前提。但前提之外，还是得自己想清楚每一步要的是什么。&lt;/p&gt;
&lt;p&gt;另外发现 gpt5.6 sol在 3D建模方面还是不能真正的还原设计图，也没有做到那种工业级的质感，不过做的模型确实也很不错了，未来可期。&lt;/p&gt;
&lt;p&gt;预览地址：&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fliush.top%2Fsolar-storage-charging-ems&quot; target=&quot;_blank&quot; title=&quot;https://liush.top/solar-storage-charging-ems&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;liush.top/solar-stora…&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你需要源码参考的话，可以来 &lt;strong&gt;柳杉前端&lt;/strong&gt; 公众号 同名文章自取哈。&lt;/p&gt;</description><link>https://juejin.cn/post/7661160753004904448</link><guid isPermaLink="false">https://juejin.cn/post/7661160753004904448</guid><pubDate>Mon, 13 Jul 2026 00:32:54 GMT</pubDate><author>柳杉</author><category></category><category>前端</category><category>数据可视化</category><category>ChatGPT</category></item><item><title>中后台越做越乱后，我用插件化把它救回来了</title><description>&lt;h2 data-id=&quot;heading-0&quot;&gt;背景&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;公司里前端项目不少，我也试过几种组织方式，最后留下来的是这套插件化方案。原因不复杂: 商城、系统设置、报表这类模块边界已经很清楚了，继续全塞在宿主里，后面只会越来越乱。所以我把宿主收回到启动、布局和全局守卫，把业务域拆成 &lt;code&gt;packages/plugin-*&lt;/code&gt;，再让插件通过统一协议交出自己的路由、菜单、多语言和初始化逻辑&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fhangjob.github.io%2Fvue-bag-admin%2Fdocs%2F&quot; target=&quot;_blank&quot; title=&quot;https://hangjob.github.io/vue-bag-admin/docs/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;文档地址&lt;/a&gt;、
&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fhangjob.github.io%2Fvue-bag-admin%2F&quot; target=&quot;_blank&quot; title=&quot;https://hangjob.github.io/vue-bag-admin/&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;演示地址&lt;/a&gt;、
&lt;a href=&quot;https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fhangjob%2Fvue-bag-admin%2Ftree%2Fnext&quot; target=&quot;_blank&quot; title=&quot;https://github.com/hangjob/vue-bag-admin/tree/next&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;源码地址&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-id=&quot;heading-1&quot;&gt;插件协议怎么定&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;AdminPlugin&lt;/span&gt; {
  &lt;span class=&quot;hljs-attr&quot;&gt;id&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 插件唯一标识&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 插件名称&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;version&lt;/span&gt;: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 插件版本&lt;/span&gt;
  enabled?: &lt;span class=&quot;hljs-built_in&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 默认是否启用&lt;/span&gt;
  order?: &lt;span class=&quot;hljs-built_in&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 注册顺序&lt;/span&gt;
  dependsOn?: &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;[] &lt;span class=&quot;hljs-comment&quot;&gt;// 依赖的插件 id&lt;/span&gt;
  routes?: &lt;span class=&quot;hljs-title class_&quot;&gt;AdminRouteRecordRaw&lt;/span&gt;[] &lt;span class=&quot;hljs-comment&quot;&gt;// 插件提供的路由&lt;/span&gt;
  menus?: &lt;span class=&quot;hljs-title class_&quot;&gt;MenuConfig&lt;/span&gt;[] &lt;span class=&quot;hljs-comment&quot;&gt;// 插件提供的菜单&lt;/span&gt;
  locales?: {
    &lt;span class=&quot;hljs-string&quot;&gt;&#39;zh-CN&#39;&lt;/span&gt;?: &lt;span class=&quot;hljs-title class_&quot;&gt;Record&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;hljs-built_in&quot;&gt;any&lt;/span&gt;&amp;gt;
    en?: &lt;span class=&quot;hljs-title class_&quot;&gt;Record&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;hljs-built_in&quot;&gt;any&lt;/span&gt;&amp;gt;
  } &lt;span class=&quot;hljs-comment&quot;&gt;// 插件自己的语言包&lt;/span&gt;
  install?: &lt;span class=&quot;hljs-function&quot;&gt;(&lt;span class=&quot;hljs-params&quot;&gt;app: App, context: PluginContext&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;void&lt;/span&gt; | &lt;span class=&quot;hljs-title class_&quot;&gt;Promise&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-built_in&quot;&gt;void&lt;/span&gt;&amp;gt; &lt;span class=&quot;hljs-comment&quot;&gt;// 初始化钩子&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我比较在意的一点是，插件要把自己的边界说清楚，而不是嘴上说自己是“独立模块”，代码里还在不停伸手改宿主，所以后面的插件架构要设计好，大概做了以下功能点&lt;/p&gt;
&lt;h3 data-id=&quot;heading-2&quot;&gt;项目预览&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/52a7811455fb4a0eadcc58308fd83dd7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-l6Iiq6am_56uZ:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784528512&amp;amp;x-signature=%2Bfbt1EMVvBikIE8ZzQr6dD6fLws%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/74367bc425884aaa84fefae07b603a4a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-l6Iiq6am_56uZ:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784528512&amp;amp;x-signature=pRqR854899WuScOmMB3My3TDPpA%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f5abc37a66804e68b74726d7d909ff9b~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-l6Iiq6am_56uZ:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784528512&amp;amp;x-signature=%2FaioqlKbuTNBDS5ykW8WCuGwU%2Bw%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f5b509d6c3754b298e038636291a2d40~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-l6Iiq6am_56uZ:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784528512&amp;amp;x-signature=%2BhS7mJUVEY6Xrnb68vOqf5%2FzitM%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1beb69e3da734b93b8c2535453d2b8e7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55-l6Iiq6am_56uZ:q75.awebp?rk3s=f64ab15b&amp;amp;x-expires=1784528512&amp;amp;x-signature=3dC%2FN6nXVCsxnvVWZDolE2sCA2U%3D&quot; alt=&quot;image.png&quot; loading=&quot;lazy&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/p&gt;
&lt;h3 data-id=&quot;heading-3&quot;&gt;插件功能点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;📦 定了一套统一的插件协议，把 &lt;code&gt;id&lt;/code&gt;、&lt;code&gt;name&lt;/code&gt;、&lt;code&gt;version&lt;/code&gt;、&lt;code&gt;enabled&lt;/code&gt;、&lt;code&gt;order&lt;/code&gt;、&lt;code&gt;dependsOn&lt;/code&gt;、&lt;code&gt;routes&lt;/code&gt;、&lt;code&gt;menus&lt;/code&gt;、&lt;code&gt;locales&lt;/code&gt;、&lt;code&gt;install&lt;/code&gt; 这些字段先收口&lt;/li&gt;
&lt;li&gt;🔢 插件注册排序，用 &lt;code&gt;order&lt;/code&gt; 控制接入顺序&lt;/li&gt;
&lt;li&gt;🟢 默认启用控制，通过 &lt;code&gt;enabled&lt;/code&gt; 配置插件初始状态&lt;/li&gt;
&lt;li&gt;🔗 依赖声明和依赖校验，避免插件在缺少前置模块时硬挂进来&lt;/li&gt;
&lt;li&gt;🛡️ 冲突检测，主要拦重复插件 &lt;code&gt;id&lt;/code&gt;、路由 &lt;code&gt;path&lt;/code&gt; / &lt;code&gt;name&lt;/code&gt; 和菜单 &lt;code&gt;path&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;🧭 插件路由注册，把页面入口统一挂到宿主路由系统&lt;/li&gt;
&lt;li&gt;🗂️ 插件菜单收集，把各业务插件的导航配置汇总到宿主&lt;/li&gt;
&lt;li&gt;🌐 语言包合并，让插件自己的 &lt;code&gt;locales&lt;/code&gt; 能注入到宿主&lt;/li&gt;
&lt;li&gt;🪝 &lt;code&gt;install&lt;/code&gt; 钩子，方便插件做自己的初始化&lt;/li&gt;
&lt;li&gt;📋 运行时插件清单，宿主能拿到当前注册过的插件信息&lt;/li&gt;
&lt;li&gt;🔌 插件启停能力，支持在运行时打开或关闭某个插件&lt;/li&gt;
&lt;li&gt;💾 启停状态持久化到 &lt;code&gt;localStorage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;🔄 刷新后恢复插件状态，宿主重新引导时继续使用本地启停结果&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-id=&quot;heading-4&quot;&gt;一个插件长什么样&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ts&quot; lang=&quot;ts&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;reportPlugin&lt;/span&gt;: &lt;span class=&quot;hljs-title class_&quot;&gt;AdminPlugin&lt;/span&gt; = {
  &lt;span class=&quot;hljs-attr&quot;&gt;id&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;plugin-report&#39;&lt;/span&gt;,
  &lt;span class=&quot;hljs-attr&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;报表插件&#39;&lt;/span&gt;,
  &lt;span class=&quot;hljs-attr&quot;&gt;version&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;1.0.0&#39;&lt;/span&gt;,
  &lt;span class=&quot;hljs-attr&quot;&gt;order&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;20&lt;/span&gt;,
  &lt;span class=&quot;hljs-attr&quot;&gt;dependsOn&lt;/span&gt;: [&lt;span class=&quot;hljs-string&quot;&gt;&#39;plugin-shop&#39;&lt;/span&gt;],
  &lt;span class=&quot;hljs-attr&quot;&gt;routes&lt;/span&gt;: [
    {
      &lt;span class=&quot;hljs-attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;/report/list&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;ReportList&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;component&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;() =&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;./views/ReportList.vue&#39;&lt;/span&gt;),
      &lt;span class=&quot;hljs-attr&quot;&gt;meta&lt;/span&gt;: {
        &lt;span class=&quot;hljs-attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;report.list&#39;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;layout&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;default&#39;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;permissions&lt;/span&gt;: [&lt;span class=&quot;hljs-string&quot;&gt;&#39;report.read&#39;&lt;/span&gt;]
      }
    },
    {
      &lt;span class=&quot;hljs-attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;/report/detail/:id&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;ReportDetail&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;component&lt;/span&gt;: &lt;span class=&quot;hljs-function&quot;&gt;() =&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&#39;./views/ReportDetail.vue&#39;&lt;/span&gt;),
      &lt;span class=&quot;hljs-attr&quot;&gt;meta&lt;/span&gt;: {
        &lt;span class=&quot;hljs-attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;report.detail&#39;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;layout&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;default&#39;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;permissions&lt;/span&gt;: [&lt;span class=&quot;hljs-string&quot;&gt;&#39;report.read&#39;&lt;/span&gt;],
        &lt;span class=&quot;hljs-attr&quot;&gt;activeMenu&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;/report/list&#39;&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;noCache&lt;/span&gt;: &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;,
        &lt;span class=&quot;hljs-attr&quot;&gt;hidden&lt;/span&gt;: &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;
      }
    }
  ],
  &lt;span class=&quot;hljs-attr&quot;&gt;menus&lt;/span&gt;: [
    {
      &lt;span class=&quot;hljs-attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;/report&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;report.title&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;icon&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;chart&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;children&lt;/span&gt;: [
        {
          &lt;span class=&quot;hljs-attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;/report/list&#39;&lt;/span&gt;,
          &lt;span class=&quot;hljs-attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;report.list&#39;&lt;/span&gt;
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码最关键的地方，不是“能跑起来”，而是它把自己该交给宿主的信息一次性带齐了。宿主看到这个插件，基本就知道要把什么东西接进去。&lt;/p&gt;
&lt;h3 data-id=&quot;heading-5&quot;&gt;最后&lt;/h3&gt;
&lt;p&gt;做到这里之后，我最直接的感受就是，新增一个业务模块时，接入方式终于稳定下来了。对我来说，这就够了。至少这个中后台后面继续长的时候，不会再回到什么都往宿主里塞的状态。&lt;/p&gt;</description><link>https://juejin.cn/post/7661266769256431657</link><guid isPermaLink="false">https://juejin.cn/post/7661266769256431657</guid><pubDate>Sun, 12 Jul 2026 15:37:34 GMT</pubDate><author>知航驿站</author><category></category><category>前端</category><category>Vue.js</category></item></channel></rss>