升华工作室
Friend Timeline

朋友圈

见字如面,相逢在字里行间

聚合了友情链接中朋友们的最新文章与动态,感受网络邻居们的思考与生活。

G
grtsinry43

我是怎样使用 AI Agent 写代码的

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/posts/coding-with-ai-agent">https://blog.grtsinry43.com/posts/coding-with-ai-agent</a></p></blockquote><blockquote> <p>从 AI 辅助编码、Vibe Coding,到现在的混合开发工作流</p> </blockquote> <blockquote> <p>TL;DR?复制下面这段提示词给你的 Agent,让它结合全文帮你优化自己的 AI 编程工作流:</p> <pre><code class="language-md">这是一篇关于 AI Agent 编程工作流的经验总结: https://blog.grtsinry43.com/posts/coding-with-ai-agent 请先完整阅读文章,再结合我当前的项目和使用习惯,帮我检查并优化自己的 AI 编程工作流。 重点分析: 1. 我现在使用 Agent 的流程中,哪些步骤缺失、重复或不合理; 2. 怎样根据任务复杂度区分直接执行、简单规划和深度设计; 3. 我的 CLAUDE.md、AGENTS.md、Skills、MCP 和 Hooks 应该怎样组织; 4. 怎样管理上下文、Compact、Handoff、项目文档和长期记忆; 5. 怎样合理使用主 Agent、Subagent 和不同能力、不同成本的模型; 6. 怎样改进编码、Debug、测试、Review 和验收流程; 7. 怎样减少无效 Token 消耗、过度思考和无意义的工具调用; 8. 怎样控制权限、修改范围和第三方 Skill、MCP 带来的安全风险; 9. 哪些工作适合交给 AI,哪些工作应该由我亲自完成或主导; 10. 最终为我整理出一套可以实际执行的分级工作流。 不要直接套用文章中的方案。请先询问我的技术栈、常用工具、项目规模、预算、权限要求和当前痛点,再根据我的实际情况进行调整。 输出时请包含: - 当前工作流的问题; - 建议保留和删除的部分; - 优化后的完整流程; - 推荐的规则文件结构; - 推荐的 Skill、MCP 和模型分工; - 一份适合我直接放进项目中的协作规范草稿。 </code></pre> </blockquote> <h2>写在前面</h2> <p>都已经 2026 年了,我的网站里居然还没有几篇真正讲 AI 的文章,这件事多少有点抽象。</p> <p>别人早就开始 all in AI,用 AI 接手越来越多的工作,我到现在才认真写这个话题。其实我很早就想写一篇 AI 编程入门教程,在学校的时候便建好了草稿,只是一直没有时间完善。那篇文章现在还在路上,之后应该会单独发布。我可能还会再写一篇模型横评,专门讲国内外模型、Agent 工具和各种订阅的体验。</p> <p>这一篇,我想先讲自己的经验。文章里大概有两条线。</p> <p>一条比较具体,讲我现在怎样配置模型、管理上下文、使用 Skill、MCP、Subagent 和文档,以及怎样让 AI 编码、Debug、测试和 Review。</p> <p>另一条是我自己的变化。我从最初的 AI 辅助编码,逐渐进入大量 Vibe Coding,又慢慢形成了现在这种 AI 与手写并行的工作方式。</p> <p>因为白天还要上班,晚上真正能用来写东西的时间并不算多。最近我也在调整作息,不知道是天气还是病毒的原因,这几天身体稍微有些不舒服,所以大概只能晚上抽出两个小时来写。</p> <p>文章的大部分内容由我先口述,再让 GPT-5.6 帮我二次整理。我已经明确要求它尽可能保留我的口吻、主体思想和原本的表达方式。它主要负责修正口误、语音识别错误和不太通顺的句子。</p> <p>大概就是这样,真的精力有限,是我第一个开始用 AI 写的文章,忘本了555。</p> <hr> <h2>我是从什么时候开始使用 Agent 的</h2> <p>还是先从自己的经历讲起。</p> <p>我真正开始频繁使用 AI 编程工具,应该是在实习之后,也就是我受伤的那段时间。那时候我开始使用 Claude Code,不过走的是第三方渠道。现在回头看,我甚至无法完全确定当时接入的 Claude 到底是不是真的。</p> <p>我主要用它写自己的项目,包括一个 Android 项目,也做过一些其他尝试。大概从九月、十月开始,我便一直在用。到了十月、十一月接触 Codex 之后,后面的使用方式也慢慢延续下来。关于那段时间的经历和感受,我之前在另一篇文章里也讲过一些。</p> <p>::: link-card href=&quot;/posts/from-think-to-code-in-2025/&quot; title=&quot;从想法到实践:在无序的生活里,试图用代码敲出一点秩序&quot; desc=&quot;&quot; newtab=&quot;true&quot;</p> <p>:::</p> <p>至于我什么时候开始有意识地优化工作流,应该是在今年年初。</p> <p>当时我使用的是 Claude Code 官方订阅。用了一段时间之后,我发现 Token 消耗得实在太快,于是开始想方设法优化整个流程。后来也算阴差阳错,我看了很多教程,自己又做过一些 AI 方向的项目,慢慢积累下不少经验。</p> <p>从三四月份回到学校开始,我已经比较熟练地使用这些 Agent 编程工具了。之后的几个月里,我一直在高强度体验各种模型和产品。</p> <p>Claude Code 官方的 Pro 订阅我用过,也借朋友的 Max 订阅体验过;OpenAI 的 Plus 和 Business 用过;Cursor、OpenCode Go、MiniMax、MiMo、火山引擎 Coding Plan、Poe、OpenRouter 也都陆续试过。DeepSeek 更多按照 API 用量付费,之前通过教育认证拿到的 Gemini 学生订阅现在也还在。</p> <p>::: link-card href=&quot;/posts/token-addiction/&quot; title=&quot;我患上了 token 的瘾&quot; desc=&quot;作为第一批被“纯 Vibe”工作流彻底卷入的开发者,我感到了一种前所未有的失语。&quot; newtab=&quot;true&quot;</p> <p>:::</p> <p>有朋友形容我是:</p> <blockquote> <p>哪个 AI 都吃一口。</p> </blockquote> <p>这么说倒也没错,我确实基本都试了一遍。</p> <p>具体的模型体验和订阅选择,我会留到之后的入门文章和模型横评里。这一篇主要讲这些实践最后怎样变成了我的工作流。</p> <hr> <h2>我的主力工具</h2> <p>我目前使用最多的 Agentic Coding 工具还是 Claude Code。</p> <p>它是一款命令行形态的工具。在我看来,它目前依然属于 Agent 编码工具里非常成熟的一档。当然,它也有一个很明显的问题:太费 Token。</p> <p>Claude Code 的界面运行在终端里,模型输出速度特别快时,TUI 偶尔会暴露出一些性能问题。不过正常使用时,这不算什么大问题。</p> <p>真正重要的是,它的工作流程已经比较成熟,我自己也最熟悉这套交互方式。所以直到现在,Claude Code 仍然是我的主力工具。</p> <p>除了 Claude Code,我用得比较多的还有 Cursor。Cursor 里的一些模型给我的感觉是便宜、快,同时效果也不错,多少有点碰到了“不可能三角”。它们响应很快,能力又足够完成大多数日常任务,所以我也会经常使用。</p> <p>Codex 当然也在我的工作流里。之前我还尝试过把 GPT 系列模型接入 Claude Code。有人反馈,同一个模型放进 Claude Code 以后会比在其他 Agent 工具里更好用。我自己的体验没有那么明显,最终效果可能还是更取决于模型本身。</p> <p>不过,Agent 工具的设计当然也很重要。至少从我的使用感受来看,Claude Code 确实好用。</p> <p>国内外还有很多其他选择,比如 MiMo Code、OpenCode 等。我之前认真使用过一段时间 OpenCode,它的功能比较丰富,TUI 体验也不错,整体定位很明显,就是在对标 Claude Code。</p> <p><img src="/uploads/pictures/2026-07-15-16:43:46-00.png" alt="image.png"></p> <p>我的建议是,工具可以多试,但没有必要一直来回切换。找到一两个自己最习惯的主力工具,再围绕它们完善工作流,通常比不停追逐新产品更重要。</p> <hr> <h2>不要迷信上下文窗口</h2> <p>我使用这些工具时,最先关注的问题之一是上下文管理。</p> <p>无论一个模型宣传的 Context Window 有多大,实际使用时,我都不建议一直堆到接近上限。</p> <p><img src="/uploads/pictures/2026-07-15-16:44:38-94.png" alt="image.png"></p> <p>比如,一个模型拥有 1M 的上下文窗口,使用到 20%,其实就已经积累了大约 200k Tokens。按照我的经验,到这个阶段,上下文便可能开始涣散。模型仍然能够看到前面的内容,却不一定还能稳定抓住其中最重要的约束。</p> <p>如果一个模型本身只有 200k 上下文,那么积累到这个量级时,基本已经接近用满。GLM、DeepSeek 等模型也会遇到相似的问题,上下文增加到一定程度以后,效果会逐渐下降。</p> <p>所以,我通常会在使用到一定比例时(经验是 25% 到 35%)进行 Compact,必要时直接 Clear,重新开启会话。</p> <p>很多人会觉得,上下文越多,模型知道的东西越多,效果理应越好。实际使用中并非如此。旧日志、无关的工具输出、已经放弃的方案和重复讨论不断积累,一方面会增加成本,另一方面也会干扰模型判断。</p> <p>上下文不是仓库,不能什么都往里面塞。</p> <hr> <h2>让不同模型承担不同角色</h2> <p>另一个重要问题,是不同模型应该怎样配合。</p> <p>现在有不少模型可以直接担任主模型,但我通常不会让一个模型包办所有工作。Claude Code、Cursor 这些工具里都有类似 Subagent 的能力,我觉得应该充分利用。</p> <p>我一般会让多个 Subagent 分别阅读、搜索和分析代码,或者把一些已经明确的实现任务交给它们,最后由主模型统一检查和验收。</p> <p>能力更强的模型适合负责理解任务、判断架构、制定方案和最终验收;速度更快、价格更低的模型可以负责扫描代码、搜索文件,以及完成边界清晰的实现。</p> <p>如果预算比较充足,也可以一直使用强模型,只是在不同任务里调整 Reasoning Effort。国产模型同样可以按照类似方式组合。我有时会把它们统一接入 Claude Code,再根据能力和成本,映射到 Opus、Sonnet、Haiku 对应的角色上。</p> <p>具体哪个模型必须映射到哪个名字并不重要。真正重要的是形成分层:关键判断交给更可靠的模型,搜索和执行交给更快、更便宜的模型;简单任务不浪费昂贵模型,重要决策也不交给只适合快速执行的小模型。</p> <p>不过,模型能力越来越强以后,也不能无脑叠加复杂流程。</p> <p>像 Superpowers、OpenSpec 这类强调 Brainstorm、Spec 和完整规划的 Skill,本身当然有价值,我身边也有同事在用。但如果模型本身已经具备很强的推理能力(比如 Claude Fable 5,GPT 5.6 Sol),再把 Reasoning Effort 调到 High,同时套上一整套要求它不断质疑和反复确认的 Skill,很容易出现过度思考。</p> <p>模型会一直分析、一直反问、一直完善方案,就是迟迟不动手。最后未必得到明显更好的结果,时间和 Token 却消耗了很多。</p> <p>所以,我更习惯按照任务复杂度决定流程。简单任务直接完成,中等任务先做简短分析,真正涉及架构和大范围修改的任务,再进入完整的设计过程。</p> <p>困难任务当然需要深入思考。问题出现在一套流程被无差别地套到所有任务上。</p> <p>Skill 应该补充模型和任务的短板,而不是机械地增加步骤。</p> <hr> <h2>人和 AI 之间,需要一套固定的协作关系</h2> <p>现在有各种插件、Skills、Spec、Plan 和 Brainstorm 工具。这些东西都可以尝试,但最终有没有用,还是取决于它们是否符合自己的工作方式。</p> <p>我自己写过一个规范人与 AI 协作的 Skill,之前也开源过。它会按照任务复杂度,选择不同的执行流程。</p> <p><a href="https://github.com/grtsinry43/agent-skills/blob/main/skills/grt-collaborating/SKILL.md">https://github.com/grtsinry43/agent-skills/blob/main/skills/grt-collaborating/SKILL.md</a></p> <p>简单修改,比如调整样式、修改文本或者完成一个边界清楚的小功能,不需要大量前期规划,直接动手即可。</p> <p>涉及较大功能或架构变化时,我通常会先和 AI 讨论。先把需求、影响范围、实现方案和潜在问题理清楚,再进入编码。</p> <p>如果是大型项目或者关键设计,流程还会继续细分,包含需求梳理、代码探索、方案设计、任务拆分、实现、测试和验收。</p> <p>如果正好习惯这套方式,可以直接使用我的 Skill;如果不习惯,也可以复制里面的文本,再按照自己的习惯修改。</p> <p>这里真正重要的是,人和 AI 之间最好形成一套稳定的协作节奏。</p> <p>AI 默认的工作方式不一定符合我们的习惯。有时候,你只想先讨论一下,它却上来就开始改代码;有时候,你明确让它快速完成一个小改动,它又不停追问一些不需要确认的细节。这两种情况都很痛苦。</p> <p>所以,最好提前约定什么时候可以直接修改,什么时候必须先讨论,什么时候需要完整规划,写完以后怎样汇报,以及哪些地方必须由人确认。</p> <p>让 AI 知道应该怎样与你协作,比单独把某一次提示词写得特别长更重要。</p> <hr> <h2>Skill:让一个人“自愿蒸馏”自己</h2> <p>既然说到了 Skill,那就专门讲讲它。</p> <p>之前我在文章里写过一句话:</p> <blockquote> <p>Skill 可以让一个人自愿蒸馏自己。</p> </blockquote> <p>过去,当我们拿到一个项目或者一份文档时,通常只能看到最终的设计、代码,以及作者具体做过什么。至于他为什么这样设计、平时怎样思考、积累过哪些经验,往往没有被真正提炼出来。</p> <p>Skill 有些不同。</p> <p>它相当于一个人主动把自己的经验、想法和工作方式整理出来,写进一个 Markdown 文档。稍微夸张一点说,当你拿到这份 Markdown 时,就像拿到了这个人的一部分思想。</p> <p>这个说法确实有些夸张,但 Skill 的价值就在这里。它把原本只存在于个人经验里的东西,变成一套可以被 AI 读取、遵循和复用的工作方式。</p> <p>现在寻找 Skill 的地方也很多,比如相关的 Marketplace、skills.sh,以及各种可以通过命令快速安装 Skill 的工具。安装以后,还能把它们软链接到 Claude Code、Codex、OpenCode 等不同 Agent 工具中统一使用。</p> <p>我比较推荐的组合,是一个负责协作方式的主 Skill,再搭配若干领域 Skill。</p> <p>主 Skill 规定什么时候讨论、什么时候规划、什么时候编码,以及最后怎样验收。领域 Skill 则负责某个具体技术方向的知识和最佳实践。前端项目可以加载 Web Best Practices,React Router 项目可以加载对应的框架 Skill,后端项目则加载语言和框架相关规范。Debug 时也可以使用专门的排查 Skill。</p> <p>GitHub 上还有不少开发者公开了非常个人化的 Skill。比如,有些 Skill 会要求 AI 一直向你提问,直到真正把需求了解清楚以后才允许开始写代码。这些东西都挺有意思。</p> <p>你甚至可以在全局的 <code>CLAUDE.md</code>、<code>AGENTS.md</code> 或类似文件里规定:进入一个尚未初始化 Skill 的项目时,先分析各个目录使用了什么技术,再寻找并配置合适的 Best Practices Skill。</p> <p>这样,就相当于把别人已经总结好的经验,很方便地引入自己的项目。</p> <hr> <h2><code>CLAUDE.md</code>、<code>AGENTS.md</code> 和项目规则</h2> <p>除了 Skill,项目里最好还有一份稳定的规则文件。</p> <p>使用 Claude Code,可以写 <code>CLAUDE.md</code>;使用 Codex,可以写 <code>AGENTS.md</code>;其他工具也有类似文件。</p> <p>这些文件用来保存项目级规则和说明。在你和 AI 协作的过程中,它们通常比某次对话里临时提出的要求更稳定,也更容易成为 AI 长期遵循的约束。</p> <p>拿到一个新项目,准备让 AI 参与开发时,我非常推荐先写好这样一份文件。</p> <p>其中可以包括协作和编码规范,比如禁止 Placeholder 实现,使用陌生库之前必须先查文档,调用 API 前确认当前版本的真实用法,明确哪些情况可以直接修改,哪些情况必须先讨论,以及完成后需要执行哪些测试和检查。</p> <p>还可以介绍项目本身,包括它解决什么问题、整体架构怎样划分、各个目录承担什么职责,以及主要的数据流和模块边界。</p> <p>开发流程同样可以写进去,例如怎样创建分支、怎样提交、需要经过哪些检查、如何合并和发版。某些项目还会有自己的特殊规则,比如遇到特定报错时优先检查哪个模块,或者在某个目录工作时必须遵循哪些限制。</p> <p>不过,这类文件最好控制篇幅。</p> <p>上下文越来越长以后,模型对规则的注意力很容易下降。如果把大量不常使用、彼此重复,甚至互相冲突的内容全部塞进去,真正关键的规范反而可能失效。</p> <p>因此,这类文件应该尽量简短、明确,只放那些适用于大多数任务、确实需要长期遵守的规则。更具体的内容可以拆到单独文档中,再从主规则文件里引用。</p> <p>用我的来举个例子:</p> <pre><code class="language-md"># Repository Guidelines ## Project Structure &amp; Module Organization - `cmd/api`: application entry point (config load, dependency wiring, Fiber startup). - `internal/`: core packages (config, database, HTTP handlers/routers, services, domain models, persistence). - `configs/`: runtime configuration files (e.g., app and auth settings). - `migrations/`: Goose SQL migrations using `NNNN_description.sql` naming. - `docs/`: generated OpenAPI artifacts (`swagger.json`). - `storage/`: runtime data (logs, uploads, HTML snapshots, GeoIP databases). ## Build, Test, and Development Commands - `go mod tidy`: sync Go module dependencies. - `APP_PORT=8080 go run ./cmd/api`: run the API locally. - `make migrate-up|migrate-down|migrate-status|migrate-version`: manage database migrations via Goose. - `make migrate-create NAME=add_posts_table`: create a new SQL migration. - `make docs`: regenerate OpenAPI JSON from Swagger annotations. - Note: `swag` is sensitive to annotation order; keep `@BasePath /api/v2` in the main comment block (prefer near the end) to ensure it is emitted into `docs/swagger.json`. ## Coding Style &amp; Naming Conventions - Use standard Go formatting (`gofmt`) and idiomatic Go naming (PascalCase exports, camelCase locals). - Keep packages cohesive and aligned with the existing layout (e.g., `internal/app/*` for services, `internal/domain/*` for entities/repositories). - Migrations must follow `NNNN_description.sql` so Goose can order them. ## Additional Agent Requirements - 0. Guarantee high-quality code; forbid placeholder implementations, fake implementations, or problematic code. - 1. For major changes, list a modification plan first, including strategy, impacted files, technical approach, and choices with reasons. - 2. Act as an excellent Go engineer; adhere to Go and Fiber best practices, handle Go legacy issues with modern syntax, and avoid GORM pitfalls using experienced practices. - 3. Before using any library, check its latest version and documentation; leverage search and network access; do not guess or assume usage. ## Testing Guidelines - No dedicated test suite is present in this repo yet. When adding tests, place `_test.go` files alongside the code under `internal/` and run `go test ./...`. - Prefer table-driven tests for handler/service logic where possible. ## Commit &amp; Pull Request Guidelines - Follow the observed Conventional Commits style (e.g., `feat: ...`, `feat(server): ...`, `fix: ...`). - PRs should include a clear summary, rationale, and any required config or migration notes. - If you change API handlers or models, update `docs/swagger.json` via `make docs` and mention it in the PR. ## Database - The only supported database is **PostgreSQL 17+**. SQLite support was removed; do not write cross-dialect SQL workarounds. - Raw SQL may use PostgreSQL-specific syntax (e.g., `FILTER (WHERE ...)`, `jsonb` operators) when needed. - Prefer GORM model-based queries where possible; use raw SQL only for aggregations or features not expressible through GORM's query builder. ## Security &amp; Configuration Tips - Runtime behavior is controlled via env vars like `APP_PORT`, `DB_DRIVER`, `DB_DSN`, `AUTH_SECRET`, and `AUTH_DEFAULT_ROLES`. </code></pre> <hr> <h2>跨上下文:Agent 的记忆问题</h2> <p>很多人在使用 AI 编码时,都会遇到一个很大的限制:Agent 的 Context 太小了。</p> <p>第一次在完整上下文里开发时,模型效果可能非常好。但只要进行过一次压缩,它便可能忘记这个项目原本是什么样的。之后生成的代码不仅效果变差,还会和前面已经完成的设计无法对应。</p> <p>多个 Agent 协作时,这个问题更加明显。一个 Agent 已经完成一半工作,你想把任务交给另一个工具继续,却发现前面积累的上下文太长,根本带不过去。不同工具组织上下文的方式也不一样,很难直接完成交接。</p> <p>还有一种情况是,当前会话已经积累了大量内容。继续工作会越来越贵,尤其缓存过期以后,之前的 Tokens 可能需要重新发送。可一旦 Compact,又会损失不少细节。</p> <p>所以,Agent 的状态管理,尤其是记忆,一直很难彻底解决。</p> <p>我目前会把信息分成三个层次。</p> <p>长期稳定、所有 Agent 都必须遵守的内容,放进项目规则文件。某个需求的分析、设计、进度和交接信息,放进项目文档或者 Obsidian。开发过程中逐渐积累的经验、历史决策和踩坑记录,则交给 Agent Memory。</p> <p>我之前使用过一个 Agent Memory 项目。它可以部署在本地,通过 Hooks 捕获 Agent 的工具调用、代码读取和修改行为,再从中整理记忆;也可以通过 MCP 接入不同工具,让 Agent 主动搜索、增加、修改或者删除某条 Memory。</p> <p><a href="https://github.com/rohitg00/agentmemory">https://github.com/rohitg00/agentmemory</a></p> <p>不过,单纯依赖自动记忆还不够。</p> <p>对一个稍微复杂的项目来说,最好还是给 Agent 留下明确文档。我自己会使用 Obsidian。比如,当我要让 AI 完成一个新需求时,可以先为它建立单独的目录或文档。</p> <p>第一次接手任务的 Agent 阅读代码以后,需要把需求背景、当前结构、相关模块、已经确认的事实、仍然存在的问题、准备采用的方案、当前进度和下一步工作都整理进去。</p> <p>当它的上下文快要用完,或者需要换另一个工具继续时,就先进行一次 Handoff,把当前状态完整写入文档。下一个 Agent 不需要继承前面全部的聊天记录,只要读取这份交接文档和相关代码,就可以继续工作。</p> <p>还有一些开发中反复出现的提醒,比如某种实现以前失败过、某个模块不适合按照常规方式修改、遇到某类问题应该优先检查某个位置。这些内容不一定适合写成永久规则,但又值得以后重新想起,就可以保存到 Agent Memory。</p> <p>我现在的思路,是把会话里的状态逐渐转化成规则、文档和记忆,而不是一直试图搬运完整的历史对话。</p> <hr> <h2>一些我会安装的插件</h2> <p>插件方面,如果使用 Claude Code,我个人非常推荐 Claude HUD。</p> <p><img src="/uploads/pictures/2026-07-15-16:47:04-a0.png" alt="image.png"></p> <p>它可以直接显示当前的上下文占用、订阅额度、工具调用、Todo 状态、Token 消耗,以及模型输出速度。这些信息不会直接提高模型能力,却能让整个运行状态变得很直观。</p> <p>你可以随时知道上下文还剩多少,模型已经消耗了多少 Token,任务执行到了哪一步,以及是否应该 Compact 或者开启一个新会话。</p> <p>MCP 数量比较多,或者同时使用多个 Agent 工具时,也可以使用专门的管理和同步工具。现在已经有不少开源项目可以统一管理 Skills、MCP 和配置文件,按照自己的习惯选择即可。</p> <p>不过,插件、Skill 和 MCP 最终都只是工作流的辅助。真正重要的,还是你怎样面对一个实际项目。</p> <hr> <h2>以我的博客项目为例</h2> <p>当时我写博客项目的时候,其实已经赶上了这一轮 AI 快速发展的阶段。不过那时我使用 AI 还比较克制,并没有把大量工作直接交出去。</p> <p>以前端部分为例,拿到项目之后,我首先会确认项目规范,也就是前面提到的规则文件,然后再设计目录结构。</p> <p>代码结构一般讲究高内聚、低耦合。我的博客本身比较复杂,所以设计目录时,我大致借用了一些领域拆分的思路,把业务模块、公共能力和通用 UI 分开。</p> <p>当时写给 Agent 的规范,大概包括这些内容:</p> <pre><code class="language-markdown">页面只负责数据接入和模块编排,不堆积复杂业务逻辑。 业务能力按 feature 划分;跨功能能力收敛到 shared;通用组件放入 ui。 浏览器 API 必须封装,统一处理 cleanup、SSR 安全和重复绑定问题。 页面级数据优先通过 SvelteKit load 提供;跨层共享使用 Context 和 Store。 内容页面优先 SSR/SSG,评论、点赞和交互增强采用客户端 Islands。 禁止在 SSR 阶段访问浏览器对象,禁止随意引入全局状态,禁止修改构建产物和依赖目录。 只基于代码、日志和已知事实得出结论;证据不足时继续验证,不凭空猜测。 </code></pre> <p>规范确定以后,再决定先完成哪些模块。</p> <p>比如,首先要写文章模块。我会先和 AI 讨论这个模块应该怎样实现,包括数据查询、接口组织和整体结构。然后把自己的设计想法告诉它,让它按照项目规范给出实现方案、执行步骤,以及必要的代码片段。</p> <p>等方案确认以后,再让 AI 正式实现。实现完成后,我会进行第一次 Review,检查它有没有遵守规范,结构是否合理,代码是否符合预期。Review 基本通过后,再让它补充单元测试,最后进行实际验证。</p> <p>整个过程可以概括成:先确定模块,再讨论方案;对齐 API、技术栈和设计思路后开始实现;实现完成后由人 Review,再补测试和验证。</p> <p>如果要使用 AI 辅助开发,提示词至少应该写清楚一些。要告诉它具体完成哪个模块,使用哪些 API,采用什么技术栈,遵循什么设计,哪些地方不能修改,以及最终怎样验收。</p> <p>什么都不说清楚,只给一个模糊需求,AI 只能自行补全大量假设。最后很容易得到一套看起来完整,却和你的真实想法并不一致的实现。</p> <hr> <h2>一个更完整的项目流程</h2> <p>我之前给朋友写过一个 Android 项目。</p> <p>这类任务,我一般会先自己阅读文档,确认功能到底能不能实现。我会看 Android 官方文档,也会查 Jetpack Compose 等相关资料,先对准备使用的 API 和实现方式形成基本认识。</p> <p>确认功能可行以后,再让 AI 阅读已有代码。我会开启 Subagent,让它们分别探索项目和相关模块,再按照我的协作 Skill 进入完整流程。</p> <p>代码读完以后,让主 Agent 分析当前问题,并写出一份实践文档。文档里需要说明当前项目结构、与需求相关的代码、已经确认的事实、可选方案、方案之间的取舍,以及具体执行步骤。</p> <p>这些内容写进文档以后,当前上下文可能已经消耗了很多 Tokens。这个时候可以 Compact,也可以开启一个新模型,让它重新对照代码和文档,检查方案有没有问题。</p> <p>如果第二个模型认可,我自己也认可,就正式开始实现。</p> <p>实现完成后,我会先自己 Review,确认方向和结构没有明显问题,再让 AI 补充测试。测试写完以后,再做第二轮 Review 和实际运行验证。</p> <p>这就是我现在比较完整的一套工作流程。</p> <hr> <h2>怎样让 AI Debug</h2> <p>让 AI Debug 时,我比较重视三个原则。</p> <p>第一个原则是禁止推测。</p> <p>AI 应该根据日志、代码、运行现象和各种线索分析问题,解释这些现象为什么会出现。证据不足时,就继续补充日志、设计实验或者提出需要验证的问题,不能直接把一个听起来合理的猜测当成根因。</p> <p>第二个原则是控制修改面。</p> <p>修复问题时,修改范围应该尽可能小。不能为了处理一个局部 Bug,顺便重构整个架构,牵连大量无关代码。应该先找到最小修复点,再说明为什么只需要修改这里,以及这次修改可能影响哪些范围。</p> <p>第三个原则是寻找根因,不要只让报错消失。</p> <p>几乎所有 AI 在修 Bug 时,都有一个比较明显的倾向:这里抛出异常,就加一个 <code>catch</code>;这里出现错误状态,就补一个默认值;某一步失败,就增加一个兜底分支,把问题绕过去。</p> <p>报错可能暂时消失,原本的问题却仍然存在,只是变得更难发现。</p> <p>所以,必须提前规定,AI 的目标是找到问题最初出现在哪里。除非兜底本身就是设计的一部分,否则不能用兜底代替根因修复。</p> <hr> <h2>测试不能只为了覆盖率</h2> <p>让 AI 写测试时,也不能只是为了提高覆盖率,机械地生成大量测试代码。</p> <p>每个测试都应该有明确目的,比如验证正常路径、边界条件、历史 Bug 是否会再次出现、不同平台上的行为是否一致,以及模块之间的集成是否符合预期。</p> <p>测试也应该分层推进,从单元测试、集成测试,到多端测试、自动化实际运行测试,最后进入真实环境验证。</p> <p>尤其需要注意,AI 很容易为自己刚刚写出的实现,再写一个“必然通过”的测试。</p> <p>测试通过,不代表需求真的被满足。</p> <hr> <h2>怎样 Review AI 写的代码</h2> <p>Review 非常重要。</p> <p>我曾经有一段时间没有认真 Review AI 生成的代码,但现在基本都会检查。</p> <p>在我自己的协作 Skill 里,有一个任务完成后的汇报机制。AI 写完以后,不能只告诉我“任务已经完成”,还要先汇报这次修改。</p> <p>我会要求它自己判断,哪些内容最需要我关注。比如最重要的文件在哪里,核心功能怎样实现,做出了哪些设计选择,为什么选择这种方案,放弃了哪些方案,里面存在哪些取舍,以及哪些代码风险较高。</p> <p>我会先检查这些重要部分,再去扫剩下的修改。</p> <p>异常路径、资源生命周期和修改范围肯定也要看。尤其要确认 Diff 是否过大,有没有修改需求之外的代码,是否引入不必要的抽象,是否增加过多包装和参数,是否真的处理了根因,以及有没有资源没有释放或者状态流被破坏的问题。</p> <p>如果模型一次写出的内容太多,我会让它把汇报拆开,一部分一部分讲。</p> <p>修改量特别大时,还可以引入第二个模型进行交叉 Review,比如让 Codex 再检查一次其他模型写出的代码。</p> <hr> <h2>AI 是怎样毁掉一个项目的</h2> <p>早期的 AI 很喜欢直接覆盖 Existing Code。</p> <p>你让它修改一个地方,它可能一下子把原来的实现全部替换掉,甚至只留下一段注释,告诉你这里以后应该实现什么。</p> <p>现在的模型很少再犯这么明显的问题,但还是有很多其他方式可以把项目搞坏。</p> <p>它可能不搜索最新文档,直接按照训练数据里记住的内容猜测 API,最后生成大量不存在或者已经过时的接口。</p> <p>它也可能写出大量 TODO、Placeholder,以及只有注释、没有真实实现的代码。表面上结构已经搭好,实际上核心功能根本没有完成。</p> <p>还有过度防御性编程的问题。AI 有时很喜欢增加大量参数,在调用链之间一层又一层地包装,再加入各种没有必要的防御逻辑。最后看起来考虑得非常全面,真正的业务逻辑却被淹没了。</p> <p>另一个常见问题,是需求还没有理解完整,它便已经开始修改。修一个 Bug 时不断扩大范围,最后动到很多无关模块。</p> <p>面对复杂问题时,不同模型还可能给出完全相反的分析,最后变成一种左右脑互搏。</p> <p>所以,人必须始终抓住已经确认的事实,不能被一套又一套听起来合理的解释带着走。</p> <hr> <h2>让 AI 辅助设计和文档</h2> <p>AI 也可以参与设计工作。</p> <p>比如,可以先让它根据现有视觉风格生成一套原子化设计规范和 Design Tokens,再由人逐项 Review。确认 Token 以后,再按照它们实现组件。这样比让 AI 每次临时发挥,更容易保持视觉统一。</p> <p>技术文档也是一样。</p> <p>完成一次问题排查后,文档至少应该讲清楚最初出现了什么现象,收集了哪些证据,排除了哪些方向,最终根因是什么,做了哪些修改,怎样验证有效,以及还有哪些风险。</p> <p>任务完成以后,不同信息应该存到不同地方。</p> <p>可复用的经验写进 Agent Memory;对某个模块形成的新理解,更新到项目文档;这次具体做过哪些修改,写进任务记录或者 Handoff 文档。</p> <p>如果开发过程中发现原有文档已经不准确,也应该顺便更新,避免后面的 Agent 继续依据错误信息工作。</p> <hr> <h2>技术选型也可以考虑 AI</h2> <p>如果是公司项目,技术栈已经确定,那基本没有选择空间。这里主要讨论个人项目,或者自己能够参与技术选型的场景。</p> <p>当多个方案都能满足需求时,可以考虑哪些技术更方便 AI 编写,同时也方便人 Review。</p> <p>前端方面,TypeScript 和 React 应该是目前 AI 非常熟悉的一套组合。SWR、TanStack Query、React Scan、Jotai、shadcn/ui、Tailwind CSS、Vite、Next.js 等工具的文档、示例和开源项目都比较多,AI 对常见用法通常也更熟悉。</p> <p>这并不意味着所有项目都应该选择 React。只是当几个方案都合适时,选择资料丰富、社区规范成熟的技术,确实能降低和 AI 协作的成本。</p> <p>有些语言在 AI 时代反而变得更有优势。</p> <p>比如 Go。过去很多人会觉得 Go 表达能力有限,重复代码多,写起来比较累。有了 AI 以后,机械和重复的部分可以交出去,而 Go 清晰、直接、约束强的特点,让人更容易阅读和 Review AI 生成的代码。</p> <p>Rust 也有相似的变化。过去使用 Rust 的门槛比较高,所有权、生命周期和类型问题会消耗很多时间。AI 降低了这部分成本,一些以前不太敢写的模块,现在也可以尝试完成。</p> <p>不过,Rust 仍然不能完全交给 AI。自己至少需要具备一定基础,能够判断所有权、并发模型和错误处理是否合理。</p> <p>代码通过编译,不代表设计一定正确。</p> <hr> <h2>让合适的模型做合适的事情</h2> <p>不同模型的能力倾向并不完全一样,最好不要让一个模型包办所有任务。</p> <p>以前端为例,我通常会把视觉设计、UI 实现、业务逻辑和 Review 分开。</p> <p>前端视觉设计和原型,我更愿意交给 Gemini。具体的前端组件和页面实现,我会优先使用 Claude。业务逻辑和复杂代码更适合交给 Codex,代码 Review 也通常以 Codex 为主,Claude 可以作为补充。</p> <p>Gemini 在视觉方向、页面布局和原型探索方面比较合适。Claude 在样式、组件结构和前端代码上的综合表现比较稳定。Codex 更擅长业务逻辑、复杂重构和 Review。</p> <p>但如果直接让 Codex 从零设计一套 UI,我自己的体验并不算好。即使提供了 Design Tokens,最后的视觉效果有时还是比较普通。</p> <p>没有一个模型能在所有任务上保持最优。让合适的模型完成它更擅长的工作,通常比始终使用同一个最强模型更加舒服。</p> <hr> <h2>成本是无法绕过的问题</h2> <p>使用 Agent 编码,成本始终无法绕过。</p> <p>首先还是上下文。上下文越长,成本越高。要做好记忆、文档、Handoff 和任务接力,避免重复探索,也不要不断消耗没有价值的 Tokens。</p> <p>虽然前面推荐了很多 Skills 和 MCP,但数量也一定要控制。它们的定义、说明和工具信息同样会占用上下文。装得太多,不仅增加成本,也可能影响模型注意力。</p> <p>模型和 Reasoning Effort 也应该按照任务强度分配。简单任务不需要最昂贵的模型,也没有必要开启最高推理强度。真正复杂的任务,再使用更强的模型和更高的 Effort。</p> <p>至于订阅和 API,我自己的选择比较直接。Claude、Codex 这类价格较高、使用频率也高的工具,优先走订阅。国内模型如果提供合适的 Coding Plan 或 Token Plan,也优先购买套餐。</p> <p>像 DeepSeek 这种 API 本身非常便宜的模型,可以直接按量付费。其他价格较高、又没有合适套餐的模型,我通常不太推荐长期走 API。</p> <hr> <h2>权限和安全</h2> <p>安全问题也非常重要。</p> <p>我之前发过一条 QQ 动态,说自己开启 <code>--dangerously-skip-permissions</code> 以后,就像打开了潘多拉魔盒,再也回不去了。</p> <p>但实际上,不可能真的一直这样使用。这种权限实在太危险了。我真正长期完全跳过确认的时间并不多,最近也重新回到了需要手动确认的状态。</p> <p>很多 Agent 工具都提供 Sandbox 模式,平时应该尽量开启,限制 Agent 能读取和修改的范围。也可以使用 Bubblewrap 一类的隔离工具,限制进程只访问相关目录。容器化也是比较可靠的方案。</p> <p>对于危险命令,可以通过 Hooks 设定规则,要求必须由人确认,不能默认执行。</p> <p>第三方 MCP 和 Skills 在安装前同样需要 Review。它们可能包含命令、提示词和外部服务调用,不能因为开源就完全不检查。</p> <hr> <h2>并行开发</h2> <p>并行开发方面,我使用 <code>git worktree</code> 的次数其实不算多。</p> <p>大多数时候,我还是串行开发,先完成一个任务,再继续下一个。即使同时工作,也通常是多个项目并行,很少在同一个项目中同时开启大量 Agent 修改代码。</p> <p>如果多个任务之间会相互影响,我反而不太建议直接把它们完全隔离,让多个 Subagent 分别修改。这种情况下,可以考虑 Agent Team,让不同 Agent 之间互相发送消息、同步进度。</p> <p>如果只是让几个完全隔离的 Agent 同时写同一套代码,确实很容易产生冲突。</p> <p>并行并不是越多越好。任务之间真正能够拆分,而且边界足够清楚时,并行才有价值。</p> <hr> <h2>我为什么不再完全 Vibe Coding</h2> <p>我开始大量把代码交给 AI,应该是在今年三四月份,也就是刚回到学校的那段时间。</p> <p>当时我一直在尝试各种新模型,也开始采用比较纯粹的 Vibe Coding。它的效率确实非常高。只要提示词给得足够清楚,AI 生成的代码质量往往也不会太差。</p> <p>但这种方式最大的问题,是可维护性太差。</p> <p>一个项目只要大量使用 AI 编写,后面就可能变得很难维护。尤其是 AI 连续写了好几天,提交了一大堆 Diff,而你 Review 时只想看一眼,说一句:</p> <blockquote> <p>LGTM。</p> </blockquote> <p>这其实是非常痛苦的。</p> <p>项目仍然在快速推进,你对它的理解却可能已经逐渐跟不上。到最后,你甚至会发现,一个项目只要大量使用过 AI,自己便不太敢再手动维护它。</p> <p>所以,我现在会按照任务类型决定哪些工作可以直接交给 AI。</p> <p>如果一个功能的实现方式已经完全确定,我也知道它应该怎样写,只是需要真正实现出来,那可以完整交给 AI。</p> <p>如果我只有一个想法,还不知道具体怎样落地,或者里面涉及技术取舍,那就应该先讨论,不能直接动手。</p> <p>还有一些事情,比如编译器、渲染系统和整体架构设计,我不会完全交给 AI。AI 可以提供方案、参与讨论、帮助验证,最终设计仍然需要由我完成。</p> <p>我重新开始手写,也不意味着放弃 AI。不同类型的工作,本来就不应该采用同一种自动化程度。</p> <p>现在对我来说,手写的意义也不只是练习语法。</p> <p>手写会迫使我逐步回答:数据从哪里来,状态在哪里改变,这一段依赖什么假设,失败以后系统会处于什么状态,为什么这一层必须存在。</p> <p>真正需要自己建立完整模型的代码,我仍然会亲手写,或者至少全程参与。</p> <p>AI 负责扩大我的执行能力,我负责维护对系统的理解。</p> <hr> <h2>AI 与学习</h2> <p>AI 确实可以提高学习效率。</p> <p>过去接触一个新的库,可能需要先记住大量 API。现在很多时候,只要理解这个库解决什么问题、具备哪些能力、有哪些重要注意事项,就已经可以开始尝试。真正需要具体 API 时,再查文档或者让 AI 辅助。</p> <p>但基础知识不能完全跳过。</p> <p>AI 可以帮助学习,却无法替代思考。一定要分清楚,什么时候是自己真正理解了,什么时候只是 AI 帮你把东西做出来了。</p> <p>千万不要因为 AI 能够完成一个任务,就认为自己已经掌握了这个领域。</p> <p>我敢大量交给 AI 的内容,通常还是自己比较熟悉的技术栈。只有自己具备一定理解,才有能力判断它写出的东西是否正确。</p> <p>至少目前,我还没有到离开 AI 就完全不会写代码的程度。我仍然保留手写和 AI 并行的习惯。</p> <hr> <h2>AI 编程真正改变了什么</h2> <p>AI 编程首先改变的,可能是精力分配。</p> <p>有了 AI 以后,我们可以把一部分重复、机械的实现工作交出去,节省时间和精力,用来完成更多事情。</p> <p>但成本没有消失,只是发生了转移。</p> <p>过去主要面对学习成本、实现成本和时间成本。现在又增加了 Token 成本、Review 成本、验证成本、维护成本,以及理解 AI 生成代码的成本。</p> <p>而且,一个项目中由 AI 生成的代码越多,它的可读性和可维护性就越容易下降。这很难完全避免。</p> <p>所以,在 AI 时代,人的价值可能会更多体现在架构、取舍和判断上。至少在 AI 编程这个场景里,判断力和学习能力仍然非常重要。</p> <hr> <h2>Vibe Coding 和 AI 辅助编码是两种用法</h2> <p>Vibe Coding 和 AI 辅助编码其实是两个概念。</p> <p>个人做原型、小项目,或者验证一个想法时,可以使用更接近 Vibe Coding 的方式,快速把东西做出来。</p> <p>但面对大型、长期维护的项目,我不太建议完全采用这种方式。你当然可以使用 Agent 工具,但不能把整个项目全部交出去,自己不再参与理解和判断。</p> <p>而且,Agent 越强,反而意味着你越需要了解自己的项目。</p> <p>这件事看起来有些反直觉。很多人会觉得,模型能力越强,使用门槛就应该越低。</p> <p>但模型越强,它一次能够完成的修改越多,能够替你做出的决策也越复杂。这个时候,使用者反而更需要具备足够的能力,判断它的方向是否正确。</p> <p>你对项目理解得越深入,需求表达得越清楚,模型最终完成的效果才会越好。</p> <p>更强的 Agent 确实降低了部分实现门槛,同时也提高了对架构能力、判断能力和表达能力的要求。</p> <hr> <h2>怎样才算会使用 AI 编程</h2> <p>最后,怎样才算真正会使用 AI 编程?</p> <p>我觉得,AI 编程有点像把工作交给一个小团队。</p> <p>在传统开发中,你可能是一个组长。你需要理解需求、完成设计、拆分任务,再把不同工作交给不同成员。过程中还要跟进进度、Review 结果,并为最终交付负责。</p> <p>现在面对 AI,做的其实是类似的事情。</p> <p>你需要具备需求表达能力、架构设计能力、任务拆分能力、上下文组织能力、风险判断能力,以及 Review 和验收能力。</p> <p>把需求扔进去,等代码吐出来,还不能算真正会使用 AI。</p> <p>真正会使用 AI,意味着你能够判断哪些事情应该交给它,应该交给哪个模型,需要提供什么上下文,怎样验证结果,以及什么时候必须由自己接管。</p> <p>所以,“会使用 AI 编程”在我看来,其实已经是一个比较高的评价。</p> <p>如果一个人真的能够把 AI 编程这件事做好,那么至少在传统的软件开发环境里,他应该已经具备了带领一个小团队完成工作的部分能力。</p> <p>半年前,我还在尝试让 AI 多替我写一些代码。</p> <p>后来,我开始期待它替我完成整个项目。</p> <p>到现在,我更关心的是,怎样让它参与工作的同时,不让自己失去对工作的理解。</p> <p>我不再追求所有代码都由自己手写,也不再把“全部交给 AI”当成效率的终点。</p> <p>真正稳定的状态,是知道什么时候应该讨论,什么时候可以让它执行,什么时候需要 Review,以及什么时候应该停下来,自己亲手实现。</p> <hr> <p><del>语音输入太多,口干舌燥了,就先写到这里吧</del></p>

G
grtsinry43

从头开始的勇气

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/moments/2026/07/12/courage-to-start-over">https://blog.grtsinry43.com/moments/2026/07/12/courage-to-start-over</a></p></blockquote><blockquote> <p>谨以此文回忆记录我兵荒马乱的大三一年</p> </blockquote> <p>最近累死了,上周一在学校考深度学习,然后二三四依然上班,周五考自控和搬寝室,周日考信号与系统。考试之前还看到自己回广州的票停开了,只能换成高铁,半夜回来。还赶上没有地铁,只能坐公交;然后半夜还下暴雨了,一点多钟才到家。由此第二天又继续上班,开始了工作的一周。</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;考试前后&quot; <img src="/uploads/pictures/2026-07-12-11:40:23-9c.png" alt="image.png"> <img src="/uploads/pictures/2026-07-12-11:40:44-ad.png" alt="image.png"> <img src="/uploads/pictures/2026-07-12-11:40:53-cb.png" alt="image.png"> <img src="/uploads/pictures/2026-07-12-11:41:00-91.png" alt="image.png"> :::</p> <p>::: link-card href=&quot;/moments/2026/06/06/life-on-train/&quot; title=&quot;列车上的生活&quot; desc=&quot;早已经习惯这种生活了&quot; newtab=&quot;true&quot;</p> <p>:::</p> <p>回来第一周的周末,这一周只感觉累得很,本打算晚上去外面走走,散散步、散散心。结果朋友发来消息,说成绩出来了。看到自控过了,悬着的心终于落了下来,而且比我想象的还要高出一些。</p> <p><img src="/uploads/pictures/2026-07-12-11:46:51-ba.jpg" alt="fe585d32805f440126ea66a94440e89c.jpg"></p> <p>回想起这个学期,我和 24 级智能专业的同学上《信号与系统》,和 24 级自动化专业的同学上《自动控制原理》。(这里特别感谢 MciG 和 Navy 两位同学的陪伴,😭)</p> <p>整个学期基本上都是在提心吊胆中度过的。。一边要在公司和学校之间两头奔波、来回折腾;一边要硬着头皮复习这两门大课;一边还要重新锻炼,慢慢恢复体能;一边还要应付课内某些本身就比较恶心的学科。感觉过得真的很压抑、很痛苦,可以说是饱受折磨。</p> <p><img src="/uploads/pictures/2026-07-12-11:42:31-c5.png" alt="image.png"></p> <p>到现在,我才终于能够真正去正视去年的那场意外。坦白说,我感觉自己仿佛失去了一切。</p> <p>工作上,好不容易通过实习有了些探索和产出,也开始接触其他业务。</p> <p>生活上,大一的时候终于摆脱了“肥胖”这个标签,以至于后来每当陷入痛苦时,我都能用“至少我曾成功掌控过体重”来激励自己。大二下学期结束时,我的体重已经维持在 130 多斤,当时计算好体测也没什么问题了。骨折之后不得不从头再来。</p> <p>更沉重的是人际关系。那段时间麻烦了太多人。我知道朋友们都是真心想帮我,但越是这样,我越觉得自己欠下了很多,很怕有一天把这些珍贵的关系消耗掉。</p> <p>学业上,由于骨折无法好好复习,信号与系统补考挂了。后来为了养伤和实习两头折腾,直到十二月份才能勉强走路,期间自控也没能好好准备,同样挂了。学业就这么落下了两门大课。</p> <p>至于和家人的关系,当时也陷入了某种僵局。他们一心想陪着我,可处于极度痛苦中的我,根本不想连累他们,只想一个人承受。受伤之初我没向家里透露半个字,直到自己把一切勉强安顿好。可他们后来的执意到来,反而打乱了我所有的既定计划,让我感到无比难受。当时我唯一的想法就是独自留在广州,一个人拄着拐上下班,哪怕花钱雇人照顾,也不想打破这种独自承受的边界,哪怕气氛和关系僵化到了冰点。</p> <p>总之,那段时间经历了太多太多。我总觉得像是一场清算,剥夺了我的所有依靠。那些曾经让我相信“我好像也能把生活过好”的事情,突然都不算数了。</p> <p><img src="/uploads/pictures/2026-07-12-11:49:35-ba.png" alt="image.png"></p> <p>怎么说呢,我其实是个挺容易内耗的人。</p> <p>那时候,我感觉自己的世界是一片漆黑的。直到这个学期结束前,我都觉得自己身上背负了太多债。丢了那么多东西,曾经失去过的一切,都得慢慢找回来。于是,我试着重新站在操场上,重新开始跑步,重新去练心肺能力。</p> <p>当大口喘着粗气,感受到乳酸拖累自己的躯体,又开始抱怨,很多自己明明已经做过一次的事,现在又要从最低处重新做一遍。</p> <p>其实说实话,这段时间绝大多数的负面情绪,本质上都来自于落差感。</p> <p>如果我只是资质平平,或者工作、学习没有别人好,去接受一个平庸的自己,我觉得倒没什么,挺好接受的,我也体会过很多次了,我也承认自己就是那种比较笨、比较差的吧。毕竟跟别人比,你可以理智地把原因归结为天赋或环境,或是给自己一个过得去的理由,要么是认命,要么是看淡。</p> <p>我经历过很多落差,真正难以接受的可能就是这种和自己相比,从头再来的落差吧(笑)。</p> <p>因为对比的坐标系,是那个曾经存在过的状态。那些高光不是想象的空中楼阁,是自己流过汗、熬过夜,一步一步硬生生啃下来的阵地。所以当意外突然降临,抹平了曾经的一切,让你不得不站在一片废墟上“重头再来”的时候,最折磨人的不是眼前的困难有多大。。</p> <p>最难的从来不是能不能坚持下去,而是从头再来的勇气。</p> <p>不断地和过去那个更好的自己作对比,于是才体会到什么叫做无能为力。</p> <p><img src="/uploads/pictures/2026-07-12-11:44:44-60.jpg" alt="ce47a0906c8d0228e649e47f1a0064a3.jpg"></p> <p>说出来也不怕笑话了,可能这些也不是什么好遮遮掩掩的。我刚出生的时候很瘦,家里人怕我身体太差,养不活。于是就多给我吃,让我能健康长大。当然,这也变成了我生活中的一个负担,让我变得自卑和难受。 我大一入学时,体重足有 92 kg。经过近一年的咬牙坚持,硬生生瘦到了 140 斤左右,减掉了将近 44 斤。此后 我就正常生活,然后这个身体也就一直保持这个状态吧。我真以为自己成功了,成功摆脱这个标签,然后算是成功做下了一个了不起的事情。</p> <p>::: link-card href=&quot;/posts/summary-2024/&quot; title=&quot;2024 年终总结——于血泪中求索,于迷茫中坚守&quot; desc=&quot;第一次发生在24年 &quot; newtab=&quot;true&quot;</p> <p>:::</p> <p>然而骨折彻底打碎了这一切。从受伤到放假,因为完全没法运动加上代谢紊乱,我的体重一路失控,从 70 多公斤疯涨到了 95 kg。直到今年 1 月,我才勉强能够重新下地尝试快走;到了 2 月,终于能迈开腿慢跑了。那时候正值北方的隆冬,外面零下二十多度,滴水成冰。我就在那种极寒的夜里去外面慢跑、拉心肺,机械地为身体的恢复做铺垫。</p> <p>到了今年 5 月 6 号,体重秤上的数字再次定格在 92 kg,恰好是我大一入学的起点。今天是 7 月 12 号,两个月的时间,现在回到了81.9 kg。</p> <p>不仅是学业和身体,在工作上,现实也远没有旁人想象得那么轻松舒适。后来我拒绝了别的大厂看起来很吸引我的 offer,最终选择重新回到原来的组,是因为这里的业务和团队确实足够优秀、足够好。但在做决定时,我同样经历了巨大的动摇和犹豫。</p> <p>重新回来实习的日子,也并不好受。尽管同事和 mentor/leader 依然很照顾我,但我却深深地卡在了自己的瓶颈里。最近接手的几乎全是各种极其诡异、难以排查的 bug,一个问题查上一整天,最后可能只定位到一个很小的竞态或时序问题。事情不是没有进展,但每天都像把脑子榨干了。看着别人在推进新功能,而自己只能在日复一日的 debug 中焦头烂额,现在看到 bug 两个字都觉得头疼。</p> <p><img src="/uploads/pictures/2026-07-12-11:45:44-40.jpg" alt="c4173eccf80fa341e45b4c6eef8530dd.jpg"></p> <p>好在,这条路上并非全是晦暗,沿途还有那些在生命中极具意义的人。</p> <p>正好赶上刚刚过去的六月毕业季,看着校园里人来人往,我不禁回想起在我的经历里,有两位非常重要的学长。一位是 21 级的学长(应该是学姐,是她最初带我敲开了技术的大门,让我对这个领域产生了浓厚的兴趣;另一位是 22 级的学长,也就是刚刚在六月份毕业的这一届。当时他带着我做升华网的项目,后来他把任务交给了我,让我有了机会去学习。正是那段独自摸索、独立扛起一个项目的经历,逼着我实现了技术上的蜕变,并一步步发展到了今天。</p> <p>如今,看着这些曾对我有过重要指引意义的学长们一个个打包行李、告别校园,我的心里也有一种说不出的滋味。恍然间有些意识到,下一届,就要轮到我了。</p> <p>去年年底的时候,我曾在文章里写过,说自己开始懂得珍惜“学生”这个身份。但直到今天,走到了学长们的上一届,真正成为了一名“准毕业生”,我还不知道:以后的最后这一年里,我该如何作为一名学生,去最后体验这个校园?</p> <p>GPT 和我说:</p> <blockquote> <p>但我不觉得你失去了一切。相反,你最重要的东西似乎一直没有真正消失:你仍然会认真对待工作,会在意朋友,会想把生活重新过好,会对帮助过你的人心怀感激,也依然对未来有期待。只是过去一年里,它们都被疲惫、疼痛和自责压得很深。</p> <p>我真正希望你能慢慢放下的,不是过去本身,而是那种“我必须恢复到意外前,过去的努力才重新作数”的想法。</p> <p>过去做成的事情从来没有因为一次骨折而作废。现在重新做的这些,也不只是在偿还旧债。它们已经是你后来人生的一部分了。</p> </blockquote> <p>当然写这篇文章不可能为了炫耀自己先挂科,然后重修,这有什么可炫耀的,有这种经历后悔还来不及呢(哈哈。只是可能对我来说,这算是一种松了一口气吧。</p> <p>生活里的问题依然接踵而至。下学期开学,还有体育一千米的补考,好在最近一直在练,问题应该不大。主要还有大三上学期的体育重修,当时免测没申请下来,缓考时又不敢跑步,真是一波未平一波又起。</p> <p>其实去年刚受伤时,我就试图两头兼顾,但这绝不是什么值得炫耀的万全之策,这完全是在透支年轻、透支身体。只是在当时那种退无可退的情况下,我别无选择</p> <p>那时候我总觉得,去年落下的每一笔账都在今年同时到期。但没办法,人生毕竟不是游戏,没有存档读档,也没有重来的回溯机制。我们不能回到过去,但生活还必须继续。</p> <p>过往的这些,无论是过去的美好还是痛苦,我觉得都可以留作回忆,但是绝不能回头。因为身后已经没有路了,哪怕拖着步子,也希望能往前走出一片新的景色吧。</p>

G
grtsinry43

列车上的生活

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/moments/2026/06/06/life-on-train">https://blog.grtsinry43.com/moments/2026/06/06/life-on-train</a></p></blockquote><p>凌晨三点二十一分,火车不知道开到了哪里。</p> <p>车厢顶部的灯白晃晃的,凌晨三点,却亮得像白天。过道已经没有了(物理意义上的)。目光里一位穿黑短袖的男生大字型趴在过道中央,身后紧紧挨着另一个躺下的人。毛毯蒙头大睡的,下巴抵着行李箱歪着睡的。旁边一个姑娘的手机屏幕还亮着微光。</p> <p>凌晨三点还在刷手机,大概也是睡不着的人在打发时间吧。</p> <p>我试着站起来,腿麻了半边。车窗玻璃映出来的自己,头发有点油,眼神空空。</p> <p>第六趟了。也可能是第七趟。这种事记不清,说明已经太多次了。</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;每个周末,都是这种“盛况”&quot; <img src="/uploads/pictures/2026-06-06-07:03:39-14.jpg" alt="eaf3da9aa7287199f70006c72b692aec.jpg"> :::</p> <h2>序幕:北上</h2> <p>四月二十九号晚上九点多,广州北站。</p> <p>临近五一,西1检票口的人流密密麻麻。屏幕上滚动着红字,K6542,长沙方向。我背着包挤在队伍里,准备尝试硬座通勤,这样能节省白天的时间,顺便便宜些,还没意识到这会变成接下来一个多月的常态。</p> <p>凌晨三点五十一分,耒阳段。前面大哥盖着红格子毛毯趴在桌上睡熟。旁边是两个年龄差不多的年轻人,屏幕的微光映在他的脸上,他正咧开嘴,露出一口白牙,笑得极其灿烂,和旁边的人依偎在一起,感觉和死气沉沉的车厢形成了鲜明的对比。</p> <p>那一瞬间觉得,这趟车也没那么难熬。</p> <p>早上七点半,长沙站出站。熬了一整夜,步子有点飘。清晨阳光斜照过来,我顺着人流往外走。那时候想的是,五一过完,考完试就回去继续了。</p> <p>之后还有事情,一周一次回校吗?不可能的。</p> <p>然后一周一次甚至一周两次就开始了。</p> <p>你看,flag 这种东西,立了就是要倒的。</p> <h2>返程:深夜南下</h2> <p>五月七号晚上九点多,长沙站检票口。LED 屏上滚着「21:55 开点,准备检票」。收假人潮涌过闸机,我排在中间,心里知道八小时后天亮,天亮就到广州,到了就得上班。</p> <p>第二天早上六点零二分,广州白云站。天刚亮,新建的大厅空旷得有点不真实。顺着扶梯下楼换乘地铁十二号线。早上的步子软软的,感觉有点找不到北,<del>至少能找到广州北和机场北方向</del>,脑子已经在想今天的工作了,后来发现这只是开场。</p> <p>习惯了。说实话,这种无缝切换的能力,自己都有点佩服自己。</p> <h2>狂奔:体测前夜</h2> <p>五月十六号晚上九点,白云站。</p> <p>这次选择了卧铺。明天体测,今晚必须睡一觉。</p> <p>这次时间不是很充裕,下了地铁,我就开始一路狂奔。广州白云这里地铁出口和进站口是有很远的距离的,甚至有机场同款的电动步道。</p> <p>几分钟后,九点十六分。站台上绿皮车停在左侧,车窗透出暖黄光。排在队伍里,前面是拉着小黄鸭行李箱的姑娘,我喘着粗气,心还在撞。</p> <p>体测还没跑,心率先爆了。也算是一种热身吧。</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;&quot; <img src="/uploads/pictures/2026-06-06-07:08:03-44.jpg" alt="3334dffd93289c0e13639881ab4884f2.jpg"> :::</p> <p>上车摸到过道的椅子坐下,腿才真的软了。还好买了卧铺,明天还有一千,今晚再硬坐一晚的话,<del>大概要成为下一个张雪峰了</del>。</p> <h2>五月二十五日:一整夜</h2> <p>中间的不再赘述。</p> <p>而这次记了全程。为什么呢,当然是因为一整晚都没睡着呀(</p> <p>零点四十六分。腿部的空间逼仄到极致。我的手随意的放在腿上,对面的白洞洞鞋几乎顶到膝盖。左边人还在刷手机,感觉马上就要贴到我。就像...身体卡在一个固定形状里,动不了。</p> <p>凌晨一点零六分。日光灯惨白,车厢像手术室。行李架塞满大包小包。有人打盹,有人发呆。空气里是硬座长途的那种麻木。</p> <p>一点五十五分,衡南。旁边的年轻人换成了岁数相对比较大的大姐,光脚直接架到了对面座椅边沿,和对面的大叔一起相对释放生化武器。腿脚交错的缝里,就剩疲惫的身体互相凑合。</p> <p>五点三十二分,英德段。天还没亮。一个无座的兄弟戴着耳机,背靠座椅侧面,头埋进背包和膝盖之间,手垂在身侧。整个人陷在深度睡眠里。周围是别人的腿脚,地上塞着礼品纸袋和行李箱。</p> <p>过道里时不时有人来往,一次次跨过去,有点同情他。脚下踩的,是别人今晚的床。</p> <h2>插曲:一个周末,两座城</h2> <p>也有不苦的时候。</p> <p>五月三十号,周六傍晚。广州塔脚下,小蛮腰亮起彩虹渐变灯,广场暖黄树灯也亮了。路人慢悠悠散步,空气里是周末才有的松弛。我抬头看了会,觉得今天的自己,勉强算个人了。</p> <p>往前走几分钟,海心沙旁边镜面水池。远处建筑物金黄色的光,水面像是那光亮的镜子,倒映着台阶上密密麻麻坐着的人。吹晚风,看夜景。</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;&quot; <img src="/uploads/pictures/2026-06-06-07:09:07-50.jpg" alt="0ab44cb2ad1822d994c71b196f632de6.jpg"> <img src="/uploads/pictures/2026-06-06-07:09:04-7a.jpg" alt="d78daa28bec466f71bac2df272be3d42.jpg"> <img src="/uploads/pictures/2026-06-06-07:09:12-f4.jpg" alt="3ffb4e15fa663e4bc8b8193645ed4b2f.jpg"> :::</p> <p>晚上七点半,顺着商场 B1 往地铁走。头顶标牌写着「北中庭 / 广州塔剧场 / 3号线 / APM线」,前面是一对推婴儿车的年轻夫妇。灯光把人影拉得很长。广州的夜才开始,断断续续在这里待了快一年了,也是第一次来看。</p> <p>第二天清晨六点五十四分。地铁还是空荡荡的,我已经在路上了。</p> <p>去找了朋友,一起吃饭,一起去 hk 看看。</p> <p>傍晚快六点,维港。天边一点晚霞,港岛高楼在海风里立着。尖沙咀长廊上靠栏杆看白色游艇从波光上开过去。不虚此行了。</p> <p><img src="/uploads/pictures/2026-06-06-07:10:09-fe.jpg" alt="2828cec8373fe731c86abac1842cc5eb.jpg"></p> <p><del>休息两天算休息吗,算吧。</del></p> <h2>六月二日:用一下“Laptop”</h2> <p>然后第三天,六月二号。回公司上班。</p> <p>然后发现周三有个课设中期检查。</p> <p><del>😨</del></p> <p>课设这种东西,懂的都懂。前一天还没怎么动。所以六月二号这一整天,白天的休息时间也在搞,下班也在搞。晚上九点多,客村地铁站,等车的几分钟里单手端起笔电,趁着地铁没来赶紧 push 一版。</p> <p>十点四十三分,花都候车室。空旷的金属排椅,零星旅客。坐下继续搞。屏幕失焦的前景里全是终端和代码,周围人不是很多,就剩 Cursor 的输出跳动着。反正这种临时抱佛脚的事,干多了也就不慌了。</p> <p>十一点三十七分。硬卧车厢熄了灯,不知哪里投下幽绿色的光。平躺在窄窄的床上,看着行李架。</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;&quot; <img src="/uploads/pictures/2026-06-06-07:10:59-38.jpeg" alt="24c70e3d1da6e570e23df3161c553c97.jpeg"> <img src="/uploads/pictures/2026-06-06-07:11:15-e3.jpeg" alt="c3fe2fca0ecac67c0902ec4b1726d394.jpeg"> :::</p> <p>谢天谢地。今天终于休息一下了。</p> <h2>一个两重身份的人</h2> <p>最难过的其实不是车上的时间。</p> <p>公司里是职场新人。靠谱、主动、有精力。前晚八小时硬座,腰疼腿软,周一工位坐下开电脑,要学会表演一个「周末休息得挺好」。</p> <p>回学校是学生。课业、通知、事务,人不在学校的时候它们不放假。</p> <p>两边都觉得我「应该在那里」。</p> <p>周末从学校往公司赶,坐硬座上偶尔也会想:到底在奔赴什么。两边都重要,两边都想做好。在这八小时轨道上,把一个自己搬来搬去。</p> <p><del>说实话两边都不太及格。走神、分心、消息忘了回。两手抓就是两手都抓不好</del></p> <h2>累啊</h2> <p>来回的八小时(其实是地铁3h+两个8h),算是我一周里唯一真正属于自己的时间。</p> <p>硬座不舒服,过道不舒服,怎么坐都不舒服。可偏偏夹在两个身份中间的缝里。手机信号时断时续,企微和 QQ 也没有消息了,凌晨三点没人来找我。旁边的鼾声一阵一阵,过道那边飘来泡面味,腿麻了换个姿势,有时候膝盖手肘相互碰到,小声说句不好意思。</p> <p>无聊透顶。</p> <p>身体上。腰疼,腿没地方放,周末是假的。一个半小时地铁,然后八小时后下车,走路像踩棉花。出站风灌进来,脑子还在车上没下来。</p> <p>心里嘛。感觉要裂开了。</p> <p>我记得去年受伤的时候,每次往返一趟跟散架了一样,一周才能缓过来。今年硬座虽然也够呛,不过不连着的话,一觉还是能爬起来。</p> <p>年轻就是好啊。(大嘘)</p> <p><del>去年也是这么想的。</del> 然后该熬还是熬。年轻是底气,但不是免死金牌。这么搞下去,哪天身体再翻脸,我可没去年那股硬扛的力气了。</p> <p>不敢了。</p> <p>嘶,只不过没有到能喘口气的时候罢了。</p> <h2>后记</h2> <p>已经到学校了。</p> <p>今天凌晨过道睡满人的那趟车,大概是我见过最夸张的一次。地板每寸都有人,像个避难所。</p> <p>这篇文章其实是回忆一路上看到随手拍的那些照片,然后写成的,<del>因为我在等 Claude Opus 4.6 干活,顺便写写吧。</del></p> <p>路上有广州塔的晚风,维港的游艇,凌晨三点车厢里的笑声,过道地板上的鼾声。</p> <p>也不知道生活的这趟列车,什么时候能到下一个大站,让我出去透透气,也解解乏。</p>

G
grtsinry43

分享一点体测的小事

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/moments/2026/05/17/physicial-exercise-something">https://blog.grtsinry43.com/moments/2026/05/17/physicial-exercise-something</a></p></blockquote><!-- raw HTML omitted --> <hr> <p>分享一点小事。</p> <p>古人云:“庙小妖风大”,诚不欺我。今日有幸再识某“体育教研”部门之威风,当真是大开眼界,令人叹为观止。</p> <p>去年夏天我不幸骨折,卧床好几个月,为办理免测,想方设法去了体育馆办公室,简短来说,双拐步步捱梯而上,在家人的搀扶和帮助下好不容易到了二楼,本欲陈情以求半丝通融。然堂上诸公,端坐如泥塑木雕,张口便以“保研”、“履历”相恫吓。彼辈安知,我根本不在乎保研档案那些评优之类?然其死抱僵规,以手握之寸权,尽施拿捏之能事,宁令伤者枯立,绝不肯明示门径。真可谓“手握蚍蜉之权,尽施生杀之威”,刻薄寡恩,莫过于此。</p> <p>及至今日,强压疲惫,昨日连夜赶回体测,顶着不适之体测试一千米。本是分内之事,孰料簿曹点卯,竟能演一出“指鹿为马”的好戏。前人簇拥塞途,彼等双目浑茫,张冠李戴,及至吾前,对不上号,反嗔怪吾不应时而至,拒录成绩。其职分之事,竟能糊涂至此;推诿塞责之辞,倒说得理直气壮。</p> <p>吾尝深惑,彼辈项上所托究竟何物?两耳之间,莫非空谷传响?抑或是徒有其表的蹴鞠?身负健美之名,四肢倒是发达,奈何金玉其外,败絮其中,脑中未点半滴墨,胸中不存半寸仁。</p> <p>平素不修实政,唯在“为难学生”一事上造诣颇深,将那点可怜的微权最大化,把玩得出神入化。与这等颟顸无能、官僚习气深重之徒论理,犹如对牛弹琴,空掷岁月。可笑彼辈,区区斗筲之人,徒增笑耳!</p> <p>录此数语,非欲何求,不过聊发胸中块垒,本亦于事无补。昔日总聆世人之训,常谓黉门庠序之内,师长慈厚,同侪友善;一旦投身尘网,则世态炎凉,再无宽宥可期。然今日观此辈之行迹面目,方知此言大谬不然!古人常叹“世途多险阻”,孰料这象牙塔内之刻薄寡恩,较之市井市侩竟是不遑多让。所谓“庠序有温情”,今观诸公之状,实乃滑天下之大稽!</p>

G
grtsinry43

「手搓系列 02」深入浅出 Agent Skills:架构、实现与思考

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/posts/agent-skills-deep-dive">https://blog.grtsinry43.com/posts/agent-skills-deep-dive</a></p></blockquote><p>手搓系列 02。</p> <p>说来惭愧,01 和 02 之间隔了多久呢?久到海枯石烂...</p> <p>倒不是没动力——01 写完的第二天我就受伤了。<del>属于是身体抢在我之前完成了&quot;用力过猛&quot;的演出,接下来就是几个月的躺平(物理)。</del> 期间手动实现过微前端框架,写过简单的打包工具,但是一直没有发,感觉自己的理解还是不够,一拖就拖到了 AI 时代,这次也算是小小的蹭蹭热度,搞搞 skills。</p> <p>真难绷。一篇博客的更新节奏,中途隔绝了天堑。</p> <hr> <p>回到正题。</p> <p>最早听说 Skills 的时候,我的想法是&quot;就这?炒冷饭而已&quot;。</p> <p>动态加载提示词,找个文件写一堆 instruction,<del>感觉不如直接塞进 <code>CLAUDE.md</code> 省事</del>。但是实际测试中,不写进 <code>CLAUDE.md</code> / <code>AGENTS.md</code>,信息容易滑出上下文,compact 之后就失效;写太多,塞进去的内容一直占着上下文的位置,token 消耗巨大。</p> <p>于是 Skills 这么诞生了,算是一种新的协议规范。</p> <h2>先看概念吧</h2> <p>Anthropic 的工程博客《Equipping agents for the real world with Agent Skills》(2025-10-16)把 Skill 定义为:</p> <blockquote> <p>Organized folders of instructions, scripts, and resources that agents can discover and load dynamically to perform better at specific tasks.</p> </blockquote> <blockquote> <p>Building a skill for an agent is like putting together an onboarding guide for a new hire.</p> </blockquote> <p>我们可以圈几个关键词:<strong>folders</strong>(不是单个文件)、<strong>dynamically</strong>(不是预加载)、<strong>onboarding guide</strong>(不是 prompt 工程)。</p> <h3>Skills 的目录长什么样</h3> <p>最简形态是一个目录,里面放一个 <code>SKILL.md</code>,开头是 YAML frontmatter,正文是 markdown。frontmatter 的<strong>必需字段只有两个</strong>:<code>name</code> 和 <code>description</code>。</p> <p>更复杂一些的 skill 可以有 <code>scripts/</code>、<code>references/</code>、<code>assets/</code> 等子目录,正文里通过文件名引用。</p> <pre><code>my-skill/ ├── SKILL.md # 必需 ├── scripts/ # 可选:可执行代码 ├── references/ # 可选:参考文档 └── assets/ # 可选:模板/字体/图标 </code></pre> <h3>本质:Markdown + frontmatter 的结构化封装</h3> <p>看刚才的目录就明白,Skill 本质上就是一个 <code>.md</code> 文件,开头用 YAML frontmatter 定义元数据,正文是带结构的 prompt 模板。</p> <p>frontmatter 里能写的东西还挺多的(后文会展开讲):</p> <ul> <li><code>name</code>:技能叫什么</li> <li><code>description</code>:干什么的</li> <li><code>when_to_use</code>:什么时候该调用</li> <li><code>arguments</code>:接受哪些参数</li> <li><code>allowedTools</code>:执行时能用哪些工具</li> </ul> <p>所以 Skills 感觉更多是定义了一个规范。谁可以用、什么时候用、接受什么参数、输出什么格式,定义清楚了 AI 才能稳定执行。<del>听起来像废话,但是这样写感觉效果确实好一些</del>。</p> <h2>Skills 的优势架构</h2> <p>所以他相比提示词功能好在哪里呢?</p> <p>Skill 系统最核心的设计是把 Skill 的信息分成两层。</p> <p><strong>第一层是索引层</strong>:Skill 的 name、description、when_to_use。这部分在 AI 启动时就会注入上下文,AI 靠这个来做路由决策——(Claude 偷偷想)&quot;用户这句话好像匹配 brainstorming,我应该调用它&quot;。</p> <p><strong>第二层是正文层</strong>:Skill 文件里的完整 prompt 内容。这部分只有在 Skill 被真正调用时才会展开注入对话,不会一开始就塞进上下文,这样说不了几句就压缩了。</p> <p>这样做的好处是上下文经济学的微妙平衡:AI 不需要一开始就读完所有 Skill 的全部内容,只需要知道&quot;有哪些技能、干什么的&quot;,等真正要用了再加载正文。全塞进去的话,token 消耗巨大不说,AI 还容易在各种 Skill 的风格里左右摇摆 <del>,像个选择困难症患者</del>。</p> <p>这个「先路由、再加载」的设计,可能就是设计所在了。</p> <blockquote> <p>像一本组织良好的手册——目录在最前面,章节在中间,详细附录在最后,<strong>Claude 按需翻页</strong>。</p> </blockquote> <p>::: gallery height=&quot;300px&quot; caption=&quot;Skill 文件在编辑器中的样子,以及 Skill 列表里出现的形态&quot;</p> <p><img src="/uploads/pictures/2026-05-05-06:46:08-a1.png" alt="image.png"></p> <p><img src="/uploads/pictures/2026-05-05-06:46:25-4a.png" alt="image.png"></p> <p>:::</p> <p>然后 Anthropic 还说:</p> <blockquote> <p>Agents with a filesystem and code execution tools don't need to read the entirety of a skill into their context window when working on a particular task. This means that the amount of context that can be bundled into a skill is effectively unbounded.</p> </blockquote> <p>换句话说,只要 agent 有文件系统和代码执行工具,bundle 的内容就可以&quot;实质上无限大&quot;。Skill 不依赖任何特殊运行时,它只假设 agent 有 bash 和文件系统,由此他就能无缝迁移到别的 Agent 实现。</p> <h2>Skills 的调用机制</h2> <p>谈到这里,Skills 是怎么被使用的呢? Skills 有两条触发路径,用户和模型都可以调用,但最后执行的流程都是大同小异的。</p> <p><strong>用户入口</strong>:</p> <p>比如用户在对话框输入 <code>/blog-writer</code>,Agent 框架判断这是一个 prompt 类型的命令,生成完整的 skill 原文。skill 内容作为一条<strong>隐藏的用户消息</strong>注入当前对话,emm 至少形态上和普通对话绘画里的用户消息一样。同时,skill 声明的 hooks 会被注册,已调用的 skill 会被记录。</p> <p><strong>模型入口</strong>:</p> <p>模型启动时只能看到一份「技能索引」,就像你点菜时候看到的菜单一样:每个 skill 的 name、description、when_to_use,来自 SkillTool 的 prompt 和 skill_listing attachment。模型靠这份索引做路由决策——&quot;用户这句话好像匹配 git-commit,我应该调用 SkillTool&quot;。</p> <p><strong>fork 的情况</strong>:</p> <p>当然,有一个特殊情况,就是 Agent 是会使用小弟的,也就是 subagent 如果 skill 的 frontmatter 里声明了 <code>context: fork</code>,skill 的内容会被送往一个子 agent 独立执行。</p> <h2>Skills 的核心语义(也就是之前的字段)</h2> <p>然后前段时间 cc 的代码不是不小心开源了么,于是我们来看看 Anthropic 是怎么设计 Skills 的。</p> <p>::: callout type=&quot;warning&quot; title=&quot;注意&quot; 接下来说的是 Anthropic 的实现,因为我们想学习他们的设计,Skills 的通用字段其实很少 :::</p> <h3>context:inline 与 fork</h3> <p>frontmatter 里的 <code>context</code> 字段决定 skill 被调用后如何执行。</p> <p><code>inline</code> 是默认行为:skill 内容注入当前对话,AI 在当前上下文中继续工作。适合需要借助当前对话历史才能完成的技能,得知道用户之前聊了什么。(这里默认就是这样,同一个上下文)</p> <p><code>fork</code> 则是把 skill 内容发给一个子 agent 独立执行,完毕后再把结果汇回来。适合需要屏蔽当前上下文干扰的技能——<del>比如你让 AI 写代码,但它总想顺便帮你修 bug</del>。</p> <h3>paths:条件可见,而不是条件执行</h3> <p>skill 的 frontmatter 里可以声明 <code>paths</code>,指定绑定到哪些文件路径。</p> <p>也就是指定哪些 skills 可见:当 AI 操作的文件路径匹配了 skill 的 paths 声明,这个 skill 才进入可用技能列表;路径不匹配,这个 skill 对 AI 来说就不存在。 大仓库里不需要一次性暴露所有 skill,skill 和对应部分相关,AI 进入那片区域时对应的 skill 才出现。</p> <p>::: callout type=&quot;idea&quot; title=&quot;paths 的典型用法&quot; 比如你有一个 <code>css-naming</code> skill,专门检查命名规范,就可以用 <code>paths: [&quot;**/*.css&quot;, &quot;**/*.scss&quot;]</code> 绑定到样式文件。只有当 AI 在处理样式文件时,这个 skill 才会出现——平时它就像不存在一样。 :::</p> <h3>上下文压缩摘要保留</h3> <p>对话历史变长时,AI 会做上下文压缩。skill 内容是作为用户消息注入的,会随对话历史自然在上下文空间向后移动。 但是这里 Anthropic 开了个后门,压缩时系统不会把 skill 内容彻底删掉,而是<strong>摘要后作为 attachment 继续保留</strong>——记录 name、path 和内容摘要。所以压缩后 AI 仍然知道这个 skill 被调用过,继续遵守它的指引。</p> <p>但是 fork 出来的 skill,子 agent 结束后会主动清理 skill 内容,毕竟用完就扔掉了。(过河拆桥说是)</p> <h3>allowedTools、hooks、变量替换</h3> <p><strong>allowedTools</strong>:skill 可以声明执行时能用哪些工具,调用时会临时放开权限边界。</p> <p><strong>hooks</strong>:调用 skill 时可以规范下 agent 的行为,比如&quot;执行前先做 X&quot;、&quot;执行完后做 Y&quot;。</p> <p><strong>变量替换</strong>:skill 正文是带插槽的模板,cc 会插入一些东西。常用的有:</p> <ul> <li><code>$ARGUMENTS</code>:代表用户传入的参数</li> <li><code>${CLAUDE_SKILL_DIR}</code>:代表 skill 文件所在的目录,AI 可以基于这个路径去读取同目录下的资源文件 skill 文件里还支持 inline shell 块——用反引号包裹的 shell 命令会在执行时运行。不过这是本地 skill 的专属能力,来自远端 MCP server 的 skill 出于安全考虑不允许执行本地 shell。 不过这都是 cc 的设计了,还是很强的。</li> </ul> <h2>着手开始实现吧</h2> <h3>项目结构</h3> <pre><code>mini-skill-runtime/ ├── src/ │ ├── types.ts # 集中类型定义 │ ├── frontmatter.ts # YAML 解析 │ ├── registry.ts # 扫描 → 索引 → 按需加载 │ ├── compaction.ts # 上下文压缩保留 │ └── demo.ts # 演示入口 └── skills/ ├── greeter.md └── code-reviewer.md </code></pre> <p>生命周期可以分为五步:</p> <pre><code>扫描 → 索引 → 按需加载 → 注入对话 → 压缩保留 </code></pre> <h3>模块一:frontmatter 解析</h3> <p>核心就是一个正则:</p> <pre><code class="language-ts">export const FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)---\s*\n?/; </code></pre> <p>解析完拿到 <code>{ frontmatter, content }</code> ,frontmatter 用 <code>yaml</code> 库 parse 就行了。</p> <h3>模块二:registry</h3> <p><strong>Step 1: <code>scanSkillsDir</code></strong> 递归扫描 <code>.md</code>,子目录用冒号作为命名空间分隔符。</p> <p><strong>Step 2: <code>buildIndexPrompt</code></strong> 在字符预算内生成索引文本(给模型的菜单):</p> <pre><code class="language-ts">const MAX_DESC_CHARS = 250; // 对标 Claude Code 的 MAX_LISTING_DESC_CHARS export function buildIndexPrompt(skills: SkillIndex[], charBudget = 2000): string { if (skills.length === 0) return &quot;&quot;; const fullLines = skills.map((s) =&gt; { const desc = s.whenToUse ? `${s.description} - ${s.whenToUse}` : s.description; const trimmed = desc.length &gt; MAX_DESC_CHARS ? desc.slice(0, MAX_DESC_CHARS - 1) + &quot;…&quot; : desc; return `- ${s.name}: ${trimmed}`; }); const fullText = fullLines.join(&quot;\n&quot;); if (fullText.length &lt;= charBudget) return fullText; // 超出部分,那就截断 description const nameOverhead = skills.reduce((sum, s) =&gt; sum + s.name.length + 4, 0); const available = charBudget - nameOverhead; const maxDescLen = Math.max(20, Math.floor(available / skills.length)); // ... } </code></pre> <p><strong>Step 3: <code>loadSkill</code></strong> 调用时才读全文,做变量替换:</p> <pre><code class="language-ts">let prompt = content; prompt = prompt.replaceAll(&quot;${SKILL_DIR}&quot;, skillDir); if (args !== undefined) { if (prompt.includes(&quot;$ARGUMENTS&quot;)) { prompt = prompt.replaceAll(&quot;$ARGUMENTS&quot;, args); } else if (args) { // 没有占位符但有参数 → 追加到末尾 prompt += `\n\nARGUMENTS: ${args}`; } } </code></pre> <p><code>${SKILL_DIR}</code> 对应 Claude Code 的 <code>${CLAUDE_SKILL_DIR}</code>,让 skill 的 markdown 里能拿到自己所在目录的绝对路径,然后 AI 用 Read/Grep 工具去读同目录下的资源文件。</p> <h3>模块三:compaction</h3> <p>对话变长时上下文会被压缩,已调用过的 skill 内容不能彻底丢掉——因为 AI 还要&quot;继续遵守它们的指引&quot;。</p> <pre><code class="language-ts">export class InvokedSkillsStore { private skills = new Map&lt;string, InvokedSkillInfo&gt;(); add(name: string, path: string, content: string): void { this.skills.set(name, { skillName: name, skillPath: path, content, invokedAt: Date.now(), }); } } </code></pre> <p>同一个 skill 可能被多次调用,这里用 Map 天然去重。</p> <p>压缩时按调用时间倒序、截断保留头部:</p> <pre><code class="language-ts">const sorted = Array.from(all.values()).sort((a, b) =&gt; b.invokedAt - a.invokedAt); for (const skill of sorted) { const truncated = skill.content.length &gt; maxPerSkill ? skill.content.slice(0, maxPerSkill) + &quot;\n\n[... truncated]&quot; : skill.content; if (usedChars + truncated.length &gt; budget) break; usedChars += truncated.length; result.push({ name: skill.skillName, path: skill.skillPath, content: truncated }); } </code></pre> <p>::: gallery caption=&quot;demo.ts 的运行结果(左)和两个测试 skill 的样子(右)&quot; <img src="/uploads/pictures/2026-05-05-06:47:42-60.png" alt="image.png"> <img src="/uploads/pictures/2026-05-05-06:47:49-32.png" alt="image.png"> :::</p> <h2>来分析一下</h2> <h3>1. Progressive Disclosure 的作用</h3> <p>&quot;渐进披露&quot;不仅是节省 token 的小技巧,<strong>它真正解决的不是 token 经济,而是注意力分配</strong>。</p> <p>如果把所有 skill 的全文都塞进系统提示,会出现一个非常具体的问题——AI 在多种风格指引里左右摇摆。它一会儿想用写作助手的腔调,一会儿想套代码审查的格式,<del>像个开学第一周的大学生选课选麻了</del>。让 AI 先看到&quot;目录&quot;再去翻&quot;章节&quot;,其实也就是在帮它做注意力路由。</p> <h3>2. 字符预算 &gt; 条目数</h3> <p><code>buildIndexPrompt</code> 用的是字符预算(默认 2000,Claude Code 这里默认 8000)。</p> <p>这里之所以没用数量,可以这样理解:Haiku 和 Opus 不是同一个量级,更不要提以后的更小/更大模型。固定条目数会在跨模型时出问题,转向字符预算是一种跨模型的&quot;普通话&quot;。</p> <h3>3. 截断保留头部,因为 skill 文件的开始更重要</h3> <p>压缩时为什么截断保留头部、丢弃尾部?其实这里感觉是个设计取舍,分析 skills 感觉太过度了,Skill 文件本身就有一种<strong>倒金字塔结构</strong>约定:</p> <ul> <li>文件开头:你是谁、你该怎么做、什么时候该做</li> <li>文件中间:工作模式、分类规则</li> <li>文件末尾:示例、边界 case、扩展说明</li> </ul> <p>这个结构不是 Anthropic 强制的,但你去看官方 skill 仓库(<code>anthropics/skills</code>)里的写法、Claude Code 内置的那些 skill,几乎全是这种模式。<strong>截断保留头部和这种写法是配套设计</strong>——丢掉示例和边界 case,AI 还能干活;丢掉&quot;你是谁&quot;,AI 就没法搞了。</p> <h3>4. Skill 只有一份约定</h3> <p>所谓 Skill 运行时,根本没有什么不可替代的引擎。它就是一份约定:</p> <ul> <li>一个目录</li> <li>一个带 frontmatter 的 markdown 文件</li> <li>启动时把元数据塞进 system prompt</li> <li>让 AI 用 bash 自己去读全文</li> </ul> <p>剩下的事情,全是 agent 平台已经具备的能力——文件系统、bash 工具、对话注入。</p> <h2>自己写一个 Skill ?</h2> <p>我最近正在写一套自己的 Skill,可以试试。</p> <p><a href="https://github.com/grtsinry43/agent-skills">https://github.com/grtsinry43/agent-skills</a></p> <p>刚写完元 skill,还在更新。</p> <p>::: callout type=&quot;info&quot; title=&quot;参考资料&quot;</p> <ul> <li> <p>Anthropic 官方工程博客:<a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Equipping agents for the real world with Agent Skills</a></p> </li> <li> <p>Anthropic 官方完整指南:The Complete Guide to Building Skills for Claude(PDF)</p> </li> <li> <p>本文最小复刻代码:<code>mini-skill-runtime/</code>(仓库内)</p> </li> <li> <p>完整源码导读:<code>06-skill系统实现详解.md</code>(仓库内,AI 写的)</p> </li> </ul> <p>:::</p> <h2>自愿蒸馏</h2> <p>::: callout type=&quot;info&quot; title=&quot;&quot; 个人观点,仅供参考 :::</p> <p>有一天我突然意识到一件事。</p> <p>我花了很长时间写 skill 文件——就是那种告诉 AI &quot;遇到这种情况你应该怎么做&quot;的 markdown。写的时候很投入,把脑子里那些模糊的、说不太清的判断,一条一条拆成规则,写成机器能读的格式。写完之后 agent 真的变聪明了,PR 质量肉眼可见地上去了。觉得自己做了一件很酷的事。</p> <p>然后某个瞬间,一个念头冒出来:我是不是在免费给厂商蒸馏自己?</p> <p>以前的 prompt 是分散的,一次性的,格式随意,拿去训练也提取不出什么结构化知识。但 skill 不一样。它有 frontmatter,有触发条件,有适用范围,有正例反例。它是你主动把自己几年踩坑攒出来的经验,整整齐齐地打包成了训练集最喜欢的样子。而且你还会反复迭代,因为你自己要用,所以你会把它打磨得越来越精确。</p> <p>更妙的是,agent 用了你的 skill 之后跑出来的 PR 过没过、reviewer 改了多少,这些都是天然的训练数据。一份带标注的、高质量的、按领域组织好的专家知识库,附带效果验证——做训练数据的人做梦都想要这个(我们这种搞机器学习的最喜欢了)。</p> <p>我跟朋友说了这个想法,他说我阴谋论。我不确定他是不是对的。</p> <p>这不是 Anthropic 一家在做的事——Cursor rules、<code>AGENTS.md</code>、Gemini 的配置文件、Windsurf 的规则集——整个行业都在让你做同一件事:把你脑子里的东西外化成机器可读的格式。谁先让用户完成这个动作,谁的 agent 就更懂你,你就越难迁移。</p> <p>所以真正的意图可能不是训练,而是锁定。你在一个平台的 skill 格式上投入了一百个小时,迁移成本就是一百个小时。</p> <p>但这两件事并不矛盾。锁定是短期动机,训练是长期可能。说&quot;他们不会拿去训练&quot;我是不信的。</p> <p>但是写的过程有些经验经得起推敲,写下来之后更清晰了;有些经验写到一半我发现自己其实说不清楚为什么要这么做,只是一直这么做而已。</p> <p>至于厂商会怎么用,那是他们的事。我能控制的只有:写不写,写多具体,以及写完之后我自己有收获了。</p> <h2>写在最后</h2> <p>至于未来, Skills 会变成 AI 协作工具的基础设施——不只是 Claude Code,各种 AI 工具都会需要一种方式来 &quot;安装能力&quot;。&quot;Markdown + frontmatter + 按需加载&quot; 这种模式,至少活到现在,说明还是有优点在的。</p> <hr> <p>这一期算是比较简单的了,一共也没多少代码。 之后还是回到前端的基建,手搓点好玩的</p>

G
grtsinry43

路的尽头还是路

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/moments/2026/04/19/never-ending-ways">https://blog.grtsinry43.com/moments/2026/04/19/never-ending-ways</a></p></blockquote><p>累。</p> <p>拿到了 offer,事情貌似在向好发展,按理说应该松一口气了。可就是累。那种弥散在空气里的疲惫,似乎常伴左右了。</p> <p>这学期的课表像上辈子欠的债一次性来还。骨折落下的课要重修,小组作业排着队,垃圾水课一大堆,考试一门接一门。</p> <hr> <p>之前看到一个鸡汤,说<em>坚持下去,就能熬到想要的生活</em>。</p> <p>嗯,说得真好。</p> <p>小时候觉得,长大就好了。 高中的时候想着,高考完就好了。 上了大学觉得,放假就好了。 然后是,找到实习就好了。 然后是,坚持到最后就好了。</p> <p>然后呢?</p> <p>然后就该上班了。上班之后怎么回事,还不知道呢。</p> <p>打算回到原来的组了。可是回去就能转正么?毕业之前还能不能出去走一走?工作之后又是什么光景?前面永远还有下一关,接下来要面对的东西只会更重——社会,柴米油盐,一整个世界。</p> <p>&quot;就好了&quot;这三个字,好像从来没有兑现过。永远在前面一步。我走一步,它也走一步。以为快到了,抬头一看,还是那么远。</p> <p>可人就是这样吧,明明知道没有终点,还是步履不停。停不下来。可是也不敢停。</p> <hr> <p>上一周和朋友玩了好久的 Minecraft。</p> <p>挖矿、建房子、然后掉进岩浆装备都烧没了从头再来,一次次刷凋灵骷髅头想办法合成信标。什么 offer,什么入职流程,什么课设考试,全部不存在了。脑子里只剩方块世界,和朋友的笑声。</p> <p>庆幸自己还有打游戏的最高配置,还有一群一起疯的朋友,就是几个人坐在那里,在一个虚拟的世界里,做着一些完全没有意义但快乐得不行的事情。</p> <p>然后退出游戏,一下午晚上错过了非常多消息。</p> <p>有 HR 又加我了,入职材料催了。课设群里有人 @all。考试的时间也马上到了。</p> <p>像从一个很暖的梦里被闹钟震醒。于是从虚拟回到现实,走进鸡飞狗跳的生活。</p> <p>开始越来越珍惜和朋友同学待在一起的时间。以前觉得这种事情稀松平常,现在才发觉,能什么都不想、就单纯坐在一起笑,是很奢侈的事情了。</p> <hr> <p>说实话,从来没有这么想家过。</p> <p>哪怕是之前受伤,一个人在广州拄着拐杖坐火车回来,都没这么想。那时候心里还在憧憬,觉得外面有更大的世界,觉得再撑一撑就能看到。</p> <p>现在...&quot;更大的世界&quot;走近了,灰蒙蒙的。就只是很想回家,躺在自己的床上,把门一关,什么都不用管。</p> <p>看来又得等到寒假了。十个月。</p> <p>十个月,好长。</p> <hr> <p>我这个人吧,脑子里永远同时在想好几件事。</p> <p>四象限法试过,把想法写纸上也试过,番茄钟也试过,冥想也试过。每种方法都管用——也许三天,也许三分钟。然后焦虑就从所谓“方法论”的缝隙里重新长出来,比之前还茂盛。</p> <p>道理没用啊,脑子并不会听话。想睡觉的时候它提醒你课设没做,做课设的时候它提醒你考试没复习,复习的时候它又提醒实习工作。一个永远关不掉的后台进程,就这样在我的想法里肆意的内存泄露(?。建议人脑支持 <code>kill -9</code></p> <p>焦虑大概是赶不走了。看来只能和谐共生了</p> <hr> <p>写到这里也没什么结论。</p> <p>什么也没有改变。写完这些字,生活依旧。</p> <p>好想一直和朋友疯下去,是真的很开心。</p> <p>大概就是这样吧。大部分时间在嗡鸣声里赶路,偶尔能在一个方块世界里停一停,挖挖矿,建建房子。然后带着那一点余温,继续走。</p> <p>好在我还有幸福在的,</p> <p>虽然也没有面朝大海,春暖花开</p> <p>但是还是得坚强,就像以前一样,</p> <p>或许,且将新火试新茶,诗酒趁年华,才是对的</p> <p>从来不是为了未来而忍受现在,而是,现在就是为了现在。</p> <hr> <p>不知道最近我的文笔为啥有点变成这样了,还是想坚持手写,因为手写的文章才有温度,但是感觉根据最近心情写的文字太苍白无力了,满满都是负情绪。</p> <p>...等最近尝试全程 vibe 的项目写完的吧,写一篇文章记录下全程,也算是尝试跟紧时代了。</p>

G
grtsinry43

二十一岁,然后......

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/moments/2026/04/03/21-years-old">https://blog.grtsinry43.com/moments/2026/04/03/21-years-old</a></p></blockquote><p>去年写了篇《致二十岁的晨光与希望》。emm 很漂亮的标题对吧,晨光,希望,又比喻又排比,一听就是那种对未来充满热忱的年轻人会写出来的东西,我还记得当时写了好久,穷尽词藻。</p> <p>::: link-card href=&quot;/moments/2025/04/03/hello-20-years-old/&quot; title=&quot;致二十岁的晨光与希望&quot; desc=&quot;此刻,且让年轻的热望继续野蛮生长。因为每个不曾起舞的昨日,都在为明天的腾跃积蓄力量;每个尚未拆封的黎明,都藏着命运馈赠的礼物。&quot; newtab=&quot;true&quot;</p> <p>:::</p> <p>今年本来也想起一个这样的标题,想了半天,发现脑子里只剩下&quot;啊?&quot;</p> <p>坐在电脑前想了十分钟,看了看之前的文章,又看了看 TODO List,放弃了。</p> <p>主要是今年的状态跟去年真的不一样。去年那个时候算是初生牛犊不怕虎,觉得二十岁了,不一样了,要写点什么纪念一下。觉得不确定是浪漫的,觉得未来虽然看不清但是闪闪发光的,觉得自己只要一直跑一直写就能到达什么地方。</p> <p>然后这一年就……嗯,经历了亿些事情。开年重写了博客,发现 AI 写代码完全爆杀自己,春招开始投简历。年终总结写了一大篇,你们有兴趣自己翻,我就不在这里复读了。</p> <p>日历又到了新的日期,手机弹出来一个提醒,哦,又大了一岁。</p> <p>然后呢?</p> <p>然后我发现我说不出&quot;然后&quot;。</p> <p>去年写的那些话,什么&quot;不确定性是未来惊喜的伏笔&quot;,什么&quot;有些答案留给二十五岁去拆封&quot;,现在读起来,怎么说呢,不是觉得矫情,是觉得那个人真的好勇敢。他还相信有个叫&quot;答案&quot;的东西在前面等他哦(。</p> <p>二十一岁的我想跟他说:兄弟,你想多了,先活过这一年再说。</p> <p>按理说应该有点什么感慨吧。但说实话,从过完年到现在,每天忙得跟陀螺似的,根本没有时间去&quot;感慨&quot;。感慨是需要闲下来才能做的事情,而我最近的闲下来大概就是刷机的那个下午。<del>小米 17 的 bootloader 比我的人生好解锁多了。</del></p> <p>那就趁今天生日,勉强闲一会儿,写点东西吧。</p> <h2>近况</h2> <p>找实习。投简历,等回复,挂了,继续投。面试的风格今年变了,不怎么考手搓算法了,全是拷问底层八股,蚂蚁还搞了 AI Coding 笔试,挺魔幻的。</p> <p>博客 v2 总算上线了,Go 后端,新设计系统,问题一大堆但是能用。上个月写了篇《我患上了 token 的瘾》,写完瘾没戒掉,反而更理直气壮地找朋友借 Claude 了。</p> <p>身体恢复得差不多了,正常走路没问题。<del>下楼梯会多看两眼,原来 PTSD 是这么来的。</del></p> <p>每天日程排得爆炸,课、项目、面试准备、各种杂事。忙完躺床上回想今天干了啥,脑子一片空白。</p> <h2>想说的</h2> <p>额</p> <p>因为我不太确定我想说什么。<del>去年搞什么小作文只需要读起来舒服就好了,今年考虑的就多了。</del></p> <p>最近的状态就是,事情很多,非常多,多到你本不敢停下来想。春招的事,项目的事,课程的事,技术的事,未来的事,全堆在那里。知道每一件都该做,每一件都不能拖,每一件都跟未来有关系。</p> <p>然后很想逃避,算是很本能的,看到一堆事情摆在面前,第一反应是能不能暂时先不面对。想再刷会儿手机,想再折腾一下没用的东西,想再赖一会儿。</p> <p>...但是话说回来这些事情它们就在那儿等着。而且以后只会更多不会更少。</p> <p>去年我觉得长大是我自己选的。<del>我要学技术,我要进大厂,我要变强,我要证明自己。</del></p> <p>今年发现,不是的。长大不问你准不准备好。问题来了,面试来了,ddl 来了,挫折来了,该学的东西来了,AI 更新了你不跟就掉队了。你来不来?你不来它也来。你没准备好?无所谓,谁会在乎你。</p> <p><del>大概这就是从少年漫画进入职场剧的感觉吧。</del></p> <p>只是方向我是有的——学习,进大厂,以后做点能帮到别人的东西,文艺(?一点叫什么“点亮别人”。这个想法从很早就有了,也算是让我撑下来。</p> <p>但方向是远处的事。远处的东西想想就好,今天的事情还是得一件一件做。而今天的事情就是……太多了。多到你来不及想为什么要做,只能先做起来再说。</p> <p>可能这就是 21 岁吧。不再有余裕去想&quot;我是谁&quot;&quot;我在干嘛&quot;这种问题了,光是应付&quot;我今天要干嘛&quot;就已经够呛了。</p> <p>要干嘛?</p> <p>我暂时不知道。</p> <h2>碎碎念</h2> <p>去年那篇里我说&quot;有些答案留给二十五岁、三十岁的清晨去拆封&quot;。</p> <p>现在觉得,二十五岁那时候大概率也在被推着走,也在忙得不可开交,哪有空拆封什么答案。<del>人类的本质就是被 ddl 追。</del></p> <p>不过也不全是坏事,至少麻了。</p> <p>也许这就是所谓的成长?不是变得不焦虑了,是焦虑的保质期变短了。就像学会了跟 bug 共处一样——你知道它在那儿,你知道迟早得修,但你不会因为它的存在否定整个项目。</p> <p>去年结尾是&quot;你好,二十岁!&quot;,感叹号,冲劲十足,真是有干劲啊这个人(。</p> <p>今年就:</p> <p>嗯,二十一岁,然后......</p> <p>在搞一个 7×24 的 AI agent 工作流,想看看全自动能跑到什么程度(距离失业还有多久)。Rust uniffi 也想折腾一下,感觉这个跨平台很优雅。</p> <p>游戏的话最近在玩《奥日与精灵意志》,音乐,操作,都非常非常舒服,尤其是音乐真的太爽了。《空洞骑士:丝之歌》也在打,太难了,手残,但是<del>战斗,爽</del>。</p> <p>还有一件事,想好好规划一下时间。这个我大概每个月都会想一次,然后每个月都不了了之。但还是想试试。</p> <p>该来的来呗。反正先活过今天。</p> <p><del>然后活过明天</del></p> <p><del>以此类推</del></p> <p>感谢你听我碎碎念,写点莫名其妙的东西。</p> <!-- raw HTML omitted --> <!-- raw HTML omitted --> <!-- raw HTML omitted -->

G
grtsinry43

我患上了 token 的瘾

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/posts/token-addiction">https://blog.grtsinry43.com/posts/token-addiction</a></p></blockquote><p>键盘就在手边,滴答清单里的待办事项还在默默倒数。</p> <p>我想写点什么。在这个连底层框架都能在一夜之间被大模型重构的时代,我总想写写感受,但又不知从何说起。</p> <p>于是只能从我自己的视角,谈谈这不到一年的时间里,我作为一个正在长株潭这片土地上读书、满怀憧憬准备在技术圈大干一场的大三学生,所经历的狂喜、震撼,以及——深深的恐惧。</p> <p>巨大的信息轰炸和技术迭代,让我产生了一种强烈的失语感。我习惯了在 JetBrains 的 IDE 里口若悬河的讲着自己的看法,习惯了在 Linux 终端搞点好玩的东西,习惯了学习从后端架构到前端 UI 的每一个只是,但现在,面对眼前这个以天为单位进化的庞然大物,我突然不知道该从何说起。</p> <p>那就从一切开始发生微妙变化的 25 年上半年说起吧。那时候,我依然觉得是我们的时代。</p> <h2>第一阶段:实验室里的初探与“手工作坊”的野蛮生长</h2> <p>时间拨回 2025 年的上半年。那时候我还在学校,日常是上课、应付期末和做实验。一切都还处于一种“掌控感十足”的状态——写代码主要还是靠自己一行行敲,最多开一下 Copilot 的补全。</p> <p>直到 Gemini 2.5 Pro 的出现。当时正好赶上 Google 的活动,我顺手试用了一个月。那是我第一次切实感受到多模态带来的直观冲击:做实验遇到那种玄学问题,我干脆直接举起手机拍下屏幕扔给它,它竟然能精准判断软件操作,指出问题所在。</p> <p>这感觉真的太上头了,在那个还没有学生认证白嫖的时候,一个月试用期结束,我甚至不过瘾地自己用 20 刀学费。后来,我又发现了 AI Studio 这个宝藏,有着极其丰富的免费额度和超长上下文支持。</p> <p>我的野心开始膨胀。借着 AI Studio 的超长上下文,我又开始问这问那:我弄懂了 Monorepo 架构,开始着手搞自己的 Amore UI 组件库;后来为了写个文档站,我甚至跑去闲鱼收了个学生认证,用那种好像叫什么“引导学习模式”,硬生生把每天的 Pro 额度全部榨干。</p> <p>但这个时候的 AI,在我眼里依然只是个“高级辅助”。虽然它帮我读了大量开源代码,但写代码的主力依然是我自己。那是一个充满折腾乐趣的时候,他确实帮助我学了好多东西。</p> <h2>第二阶段:大厂的现实毒打与开发者的傲骨</h2> <p>带着在学校里和自己积累的项目,2025 年 6 月底,我拖着行李箱走进了 🐧 的大门,开始实习。</p> <p>当时正值行业里 DeepSeek R1 私有化部署的炒作狂欢,满世界都在鼓吹 AI 马上就要接管一切。但是这个时候我还依然对 AI 提不起兴趣。</p> <p>当我真正面对那种错综复杂、体量庞大、充斥着历史包袱的企业级代码时,司内的模型显得极其笨拙。</p> <p>不仅是工作,平时的开发,当时的主力模型还是 Claude 4 (Copilot 教育认证),大项目它根本理不清拓扑关系,小问题更是层出不穷,经常给你瞎编一些根本不存在的 API。</p> <p>我的工作流被迫退回了古典的“手工作坊”模式:遇到卡壳的地方,用 GitHub Copilot 问一下,把代码片段复制出来,然后小心翼翼地缝缝补补。那时候我最常干的事,就是对着屏幕里的 AI 骂:“给我完整的代码!别动我原本的逻辑!”</p> <p>为了突破工具的限制,我狠下心充了 20 刀一个月的 Cursor,第一次被 Agent 模式震撼;又偶然发现了能白嫖的 Anyrouter,开始摸索 CLI 模式(当时还是 cc v1.x)。</p> <p>然而,当时为了省钱,我把每天只有 5 次免费额度的 Claude 网页版当“架构师”,让 CLI 工具当“打字员”去落地。</p> <p>无论是工作写库,写 Runtime,还是平时自己项目写组件,处理跨平台问题,我坚持核心的掌控权必须死死攥在自己手里。经历了上半年的惊艳后,实习期的现实让我对 AI 彻底“祛魅”——它充其量只是个带点智能的搜索引擎,真正的工业级工程,还得靠人堆出来。</p> <h2>第三阶段:荒野求生、震撼与防线的失守</h2> <p>真正的认知颠覆,发生在 2025 年的下半年。</p> <p>就在我用 AI 抽卡写完文档站的第二天,我意外受伤了。</p> <p>生活半径被迫缩小到了床和书桌之间。</p> <p>后来我依然坚持着上班。那段时间(11月左右),业余和折腾的时间我用 cc 写了好多项目:用 Kotlin Multiplatform 写跨平台的 RSS 阅读器 Pureflow,研究安卓,写服务器监控,写日志系统。</p> <p>结果后来 Anyrouter 死了,我才发现那个白嫖的模型劣质得像个假货。</p> <p>因为有了 CLI 模式,我开始摸到了 Vibe Coding 的雏形。但我吃过 AI 乱改代码的亏,这算是一种“如履薄冰的 Vibe”,一直在仔细 Review 它的每一行逻辑。</p> <p>直到我遇到了 Codex 5.2,以及年底发布的 Gemini 3 Pro。</p> <p>11 12 月同时我买了codex(当时听说好用),我发现了很多别人的文章,如何纯 vibe ,然后效果特别好:</p> <p>当时的世界唯快不破,但 Codex 给出了截然不同的答案。把一个复杂的后端任务丢给它,它慢条斯理地跑上半个小时,但这半小时你完全不需要干预。最后直接 Production-Ready 。</p> <p><del>一个任务虽然跑了半小时,但是写完效果真的是生产可用的,当时我真的惊了</del></p> <p>如果说后端的失守还算温水煮青蛙,只是潜移默化,那前端的沦陷则是降维打击。</p> <p>新模型发了,Gemini 3 Pro 在前端设计上展现出了超过好多人的能力。哪怕当时 Google 的 Antigravity 天天报错、难用到反人类,我也硬是耐着性子用它生磕出了大量惊艳的前端 UI。后来换到 Gemini CLI,终于承认了一个事实:<strong>不管是设计还是写代码,前端也真的写不过 AI 了。</strong></p> <h2>第四阶段:赛博圆桌会议与主理人的克制</h2> <p>带着满脑子的震撼,今年 1 月中旬放寒假回到老家,窗外是灰蒙蒙的天和白雪,我开始重写 Grtblog v2。</p> <p>写这个博客的时候我和 codex 和 Claude(每天5条免费)帮我设计了好多架构,包括 go 的 Clean Arch 还有 DDD,前端和 admin 的目录结构等等</p> <p>那段时间,我在 GitHub 上极其熟练地让 AI 互相 Code Review(<code>@codex review</code>, <code>@copilot review</code>)。UI 方面,我在 AI Studio 里高频抽卡找灵感,然后自己回到 Figma 里研究哈几天,抽离出了你看到的这套带着标志性绿色和小圆角的设计系统。</p> <p>::: callout type=&quot;info&quot; title=&quot;底线&quot; 即使当时的 AI 已经能一次写完一个完整功能,但在这个我最在意的“亲儿子”项目上,我依然保持着极大的克制。因为安全问题和 AI 天生的“反骨”,我小心翼翼地把 AI 的实际代码贡献率死死压在 35%-40%。 :::</p> <h2>第五阶段:算力自由、多线操作与深渊的凝视</h2> <p>如果说在家重构博客还保留着一丝人类的体面,那么 2 月底回到学校后的那几天,则彻底击穿了我的认知。</p> <p>剧情在这里发生了一次不可思议的转折。Anthropic 发了 Claude Opus 4.6,OpenAI 掏出了 Codex 5.3,我立刻买了这两个订阅。两家巨头互换了剧本:曾经快如闪电的 Claude 降速提质,成了一个疯狂吞噬 Token 的大模型;而 Codex 反而提速降本,限额翻倍。</p> <p>那会儿我 20 刀的 Claude Pro 账号,5 小时限额只够跑两个大 Session。但就是这两个 Session,Opus 4.6 做到了一遍过,唉,这个时候就开始害怕了。</p> <p>直到 2.28 我回到学校,我有一个朋友他恰好财力雄厚,有几个 Claude Max 账号,因为开学了他用不完了,于是就把其中一个 Claude Max 20x 账号借给我了用,真是*了,太逆天了...</p> <p>那是一个极其疯狂的下午。我在宿舍的电脑前,同时跑着 4 个顶级 Claude Opus 4.6、1 个 Codex、1 个 Gemini CLI。我彻底进入了终极的“纯 Vibe”状态。无需构思语法,甚至无需自己管理项目,我的工作变成了纯粹的决策和调度——哪里亮了点哪里。</p> <p>但随之而来的是:<strong>我发现用 AI 竟然比自己写还要累。</strong></p> <p>开发历史上的瓶颈,第一次从“敲代码的手速”变成了“人类审查逻辑的脑力带宽”。面对 6 个大模型源源不断吐出的高质量代码,我根本 Review 不过来。我不是在写项目,我是在被算力的洪流推着、甚至“逼”着往前狂奔。</p> <p>几天后,博客 V2 摧枯拉朽般地写完并发布了。但在那个跑满算力的下午,我极其兴奋,但也极其害怕。那种害怕,是你作为一个个体,直面指数级进化时的渺小感。</p> <h2>终章:49年入国军与温暖的 Token</h2> <p>时间拨回现在,三月底的春招季。</p> <p>我带着刚刚重构完博客的余温,准备寻找暑期实习。迎面撞上的却是触目惊心的裁员潮。外包被砍,团队按比例缩减。我们这群学生和同行们私下打趣,却笑得比哭还难看:</p> <blockquote> <p><strong>“冰冷的前端同事,终于还是变成了温暖的 Token。”</strong></p> </blockquote> <p>更可怕的反噬已经在我身上显现。我察觉到自己手写代码的基本功在下滑。那曾经引以为傲的肌肉记忆,正在被轻易获得的正确答案所腐蚀。</p> <p>面试的规则也彻底翻篇了。我刷了很久的算法,结果今年面试官根本不考手搓算法,全是疯狂拷问 19、20 年极其底层的“老八股”,蚂蚁甚至直接搞出了 AI Coding 笔试。</p> <p>我问了一圈朋友和前同事:很多公司的团队已经全面拥抱 AI,几乎不怎么手写代码了。既然大模型能写出完美的逻辑,人类的价值就被迫转移到了“审计”。</p> <p>就在这段时间,Claude Opus 4.6 的 1M 超大上下文推广开了。我们学校比较复杂的前后端、客户端和 Admin 项目,上下文可以一股脑塞进去,几个 Sub-agent 协同 5分钟就重构了 admin。还有曾经需要我们翻遍文档、掉光头发研究的问题,它不仅瞬间秒杀,效果还远超人类。</p> <p>我看着屏幕,感到了一种深刻的焦虑和无力。这就像是你苦读了三年,好不容易练就了一身全栈本领,准备在行业里大展拳脚,却发现这个行业的运作方式已经被连根拔起。这种“49年入国军”的战栗感,在此刻达到了顶峰。</p> <p>我似乎患上了 Token 的瘾。明明知道自己在失去手写的能力,明明心里充满了对未来的深渊般的恐惧,但面对这种降维打击的效率,我已经形成了致命的路径依赖。</p> <p>面对屏幕上那些汹涌而来的 Token,我没有答案,只有战栗。</p>

G
grtsinry43

Xiaomi 17 标准版刷机折腾记:解锁、官改ROM与必备模块

<blockquote><p>该内容由 RSS 渲染生成,最佳阅读体验请前往:<a href="https://blog.grtsinry43.com/posts/xiaomi-17-bootloader-unlock-custom-rom">https://blog.grtsinry43.com/posts/xiaomi-17-bootloader-unlock-custom-rom</a></p></blockquote><p>纠结了很久,还是入手了 Xiaomi 17 标准版。</p> <p>买这个主要起源于最新小米设备上爆出的解锁漏洞,使得 8e5 机型重新解锁 bootloader 成为可能。</p> <p>这篇文章主要讲讲我的折腾经历,但是隐去了解锁的流程,大家随便搜索论坛,酷安上,还有搞机 QQ 群都能拿到,等到解锁之后,就可以正式开始折腾了。</p> <p><img src="/uploads/pictures/2026-03-12-07:43:06-95.jpg" alt="一下子回到了上个时代哈哈"></p> <h2>官改 ROM</h2> <p>我选择的是酷安上 <a href="https://www.coolapk.com/u/710841">白羊唐黎明</a> 的官改ROM,版本 3.0.301.0。</p> <p>需要搭配底包 3.0.44.0 刷入,可以去</p> <p><a href="https://miuirom.org/">https://miuirom.org/</a></p> <p><a href="https://xiaomirom.com/">https://xiaomirom.com/</a></p> <p>这两个平台找一下,要的话这里也有一个<a href="https://bkt-sgp-miui-ota-update-alisgp.oss-ap-southeast-1.aliyuncs.com/OS3.0.44.0.WPCCNXM/pudding_images_OS3.0.44.0.WPCCNXM_20260131.0000.00_16.0_cn_3c11e63b6e.tgz">直链</a>,然后下一个 MiFlash,emm可以在</p> <p><a href="https://xiaomiflashtool.com/">https://xiaomiflashtool.com/</a></p> <p><img src="/uploads/pictures/2026-03-12-07:55:09-c3.png" alt="image.png"></p> <p>把下载好的官方线刷包解压到任意文件夹,手机音量下+电源键进入 FASTBOOT ,打开 MiFlash,点击“Driver”安装好对应的驱动之后点击“刷新设备”。</p> <p><img src="/uploads/pictures/2026-03-14-04:30:25-1c.jpeg" alt="就是这个页面"></p> <p>::: callout type=&quot;info&quot; title=&quot;注意&quot; 这里如果要命令的话是 <code>adb reboot bootloader</code> :::</p> <p>::: callout type=&quot;warning&quot; title=&quot;Emm&quot; 打开 MiFlash 第一步确保右下角选择全部删除而不是删除并回锁,要不就白解锁了</p> <p>:::</p> <p><img src="/uploads/pictures/2026-03-12-07:59:31-2e.png" alt="image.png"></p> <p><img src="/uploads/pictures/2026-03-12-07:57:21-6b.png" alt="image.png"></p> <p><img src="/uploads/pictures/2026-03-12-07:57:37-c1.png" alt="image.png"></p> <p>选择刚刚解压到的文件夹,之后点击刷机,耐心等待即可。</p> <p>开机之后尽量 oobe 该跳过的跳过,确认能正常进入桌面之后,没问题,然后重新手机音量下+电源键进入 FASTBOOT ,连接电脑,解压好官改包。</p> <p><img src="/uploads/pictures/2026-03-12-08:01:44-f8.png" alt="image.png"></p> <p>先装一下驱动,然后双击打开刷机脚本即可。</p> <p><img src="/uploads/pictures/2026-03-12-08:02:17-82.png" alt="d1709e212429b1bfbbc0c89ea5dbd9f9.png"></p> <p>不出意外的话,等待进度条跑完,手机重启,官改就刷好了。</p> <h2>Play 完整性与 bl 解锁状态隐藏</h2> <p>进入桌面的第一件事,就是找到刚刚官改 zip 里面的 ksu 管理器安装包装好,这样就可以准备刷模块了。</p> <p>我们只需要刷入这几个模块:</p> <p><img src="/uploads/pictures/2026-03-12-08:05:16-01.jpg" alt="e8e1bc40b9be2cd6287793044bd92a66_720.jpg"></p> <p>顺序是:</p> <p><a href="https://github.com/Dr-TSNG/ZygiskNext">https://github.com/Dr-TSNG/ZygiskNext</a></p> <p><a href="https://github.com/5ec1cff/TrickyStore">https://github.com/5ec1cff/TrickyStore</a></p> <p><a href="https://github.com/MeowDump/Integrity-Box">https://github.com/MeowDump/Integrity-Box</a></p> <p>刷完重启就 OK 了</p> <h2>必备软件和模块</h2> <p>我自己用的一些工具</p> <p>Scene:https://www.omarea.com/#/</p> <p>爱玩机工具箱:https://www.aiwanjitool.com/</p> <p>一些模块:</p> <p>Reqable 安装</p> <p>自动救砖</p> <p>::: gallery height=&quot;400px&quot; caption=&quot;KSU&quot; <img src="/uploads/pictures/2026-03-12-08:11:24-7c.jpg" alt="cf943b262476d5d6851f8c59cadbcf05.jpg"> <img src="/uploads/pictures/2026-03-12-08:12:41-34.jpeg" alt="4039249504fe07b87b03d59d3016d96b.jpeg"> :::</p> <p>就到这里,一时兴起写的一篇文章,就当是重新经历刷机时代了。😋</p>