技术博客

记录工程实践、系统设计、问题排查和可复用的技术笔记。这里按主题、标签、归档和搜索组织,方便后来查找和复盘。

Git 使用手册 · 终极篇:工程化、安全与团队规范

这是 Git 手册系列的最后一篇。前三篇解决了"会用 → 用得对 → 懂原理",本篇解决最后一件事:让 Git 在团队和工程体系里成为可靠的基础设施,并在灾难发生时救得回来。 目录 Monorepo vs Polyrepo:仓库拓扑决策 大型仓库的性能优化 提交规范:Conventional Commits 签名提交与提交者验证 密钥防护:从预防到泄漏处置 CI/CD 中的 Git 技巧 灾难恢复 SOP 一套可直接落地的团队 Git 规范 终极速查表 Monorepo vs Polyrepo:仓库拓扑决策 Monorepo(一个仓库存所有项目) Polyrepo(每项目一个仓库) 跨项目改动 一次提交原子完成 要发版、升依赖、多 PR 联动 代码共享 直接 import 发包 / submodule CI 需要增量构建,配置复杂 简单直接 权限边界 靠 CODEOWNERS,粒度粗 天然隔离 克隆体积 大(可用 sparse checkout 缓解) 小 代表 Google、Meta、Vue、React 生态 多数中小团队 决策建议: 项目间强耦合、频繁联动发布(如前端组件库 + 应用)→ monorepo 团队/项目独立、发布节奏不同、需要强权限边界 → polyrepo 不确定就先 polyrepo;拆容易,合回去很难 monorepo 配套工具:Nx、Turborepo、Bazel(构建缓存与增量)、changesets(多包版本管理)。 ...

2026-08-22 · 4 分钟 · 677 字 · heyaohua

Git 使用手册 · 高级篇:原理、调试与仓库工程

这是 Git 手册系列的第三篇。前两篇讲"怎么用",本篇讲"为什么":理解了 Git 的内部模型,所有命令都会变成推理题而非背诵题;再配上一批工程化工具,解决"什么时候出的 bug"、“仓库太大”、“多仓库依赖"这类真实难题。 目录 Git 对象模型:blob、tree、commit、tag 引用:分支、HEAD、tag 都只是指针 彻底理解 merge / rebase / cherry-pick bisect:二分查找"哪次提交引入了 bug” worktree:一个仓库多个工作区 submodule 与 subtree:仓库套仓库 hooks:在关键时刻自动执行脚本 Git LFS 与大文件 仓库瘦身:清理历史中的大文件 高级调试与诊断 Git 对象模型:blob、tree、commit、tag Git 本质是一个内容寻址的文件系统 + 一个版本控制外壳。.git/objects/ 下只有四种对象: 对象 内容 类比 blob 文件的内容(不含文件名) 文件快照 tree 一个目录:文件名 → blob/tree 的指针列表 文件夹快照 commit 指向一个 tree + 父 commit 指针 + 作者/时间/信息 一次版本 tag(附注) 指向一个 commit + 标签信息 里程碑 所有对象用内容算 SHA-1(新版支持 SHA-256)哈希作为 id:内容相同 → id 相同,这就是 Git 去重和完整性校验的原理。 ...

2026-08-22 · 4 分钟 · 753 字 · heyaohua

Git 使用手册 · 中级篇:分支协作、冲突与历史修改

这是 Git 手册系列的第二篇。初级篇解决了"能用",本篇解决"用得对":多人协作不打架、冲突不慌、历史能改得干净。 目录 分支模型:选一个然后坚持 merge 与 rebase:到底用哪个 冲突的正确解法 reset 的三种模式(soft / mixed / hard) stash:临时收摊子 cherry-pick:挑一个提交带走 修改历史:amend 与交互式 rebase reflog:你的后悔药 tag 与发布 中级常见错误 分支模型:选一个然后坚持 个人 / 小团队:Trunk-Based(主干开发) main 是唯一长期分支,随时可发布 功能分支从 main 切出,活 1~3 天,合并后立即删除 配合 PR/MR 做代码评审 git switch -c feature/xxx main # 开发、提交 git push -u origin feature/xxx # 提 PR,评审通过后合并 git switch main && git pull git branch -d feature/xxx 需要同时维护多个发布版本:Git Flow main:线上版本;develop:集成分支 feature/*、release/*、hotfix/* 各司其职 重,只有确实需要多版本并行(如 SaaS + 私有化部署)才用 结论:90% 的团队用 Trunk-Based 就够了。分支模型越简单,协作成本越低。 ...

2026-08-22 · 3 分钟 · 621 字 · heyaohua

Git 使用手册 · 初级篇:从第一次提交开始

这是 Git 手册系列的第一篇。目标只有一个:让你今天就能用 Git 管好自己的代码,并且知道每条命令在干什么。不理解原理没关系,先把工作流跑通。 目录 Git 是什么,解决什么问题 安装与初始配置 四个区域:工作区、暂存区、本地仓库、远程仓库 第一次提交 日常三板斧:status / add / commit 查看历史 撤销与回退(安全版) 连接远程仓库(GitHub / GitLab) 分支是什么(先会用最基础的) 初级常见错误 Git 是什么,解决什么问题 没有 Git 的时候,你是这样管理代码的: project/ project-final/ project-final-v2/ project-final-v2-真的最终版/ Git 做的事:把项目的每一次修改记录成"快照"(commit),你可以随时查看任何历史版本、回到任何历史版本、同时维护多条并行的修改线(分支),并和别人协作而互不覆盖。 安装与初始配置 # macOS brew install git # Ubuntu / Debian sudo apt install git # Windows:安装 Git for Windows(自带 Git Bash) 第一次使用必须先配置身份,否则提交会带上机器默认的匿名信息: git config --global user.name "你的名字" git config --global user.email "[email protected]" git config --global init.defaultBranch main 验证: ...

2026-08-22 · 3 分钟 · 508 字 · heyaohua

PM2 使用手册:从安装到生产级进程管理

PM2 是 Node.js 生态中最常用的生产级进程管理器,但它的能力不止于"让 Node 脚本在后台跑起来"。本文从安装讲起,覆盖日常管理、集群、日志、监控、自启与生产部署的完整流程。 目录 安装与基础概念 启动与进程管理 ecosystem 配置文件 集群模式(Cluster Mode) 日志管理 监控与指标 开机自启 零停机重载与发布 内存与异常处理策略 常见坑与排查 速查表 安装与基础概念 # 全局安装 npm install -g pm2 # 或 pnpm pnpm add -g pm2 PM2 的核心概念只有三个: process:被 PM2 托管的一个应用实例 daemon:PM2 自身驻留后台的管理进程(~/.pm2/ 下保存状态) ecosystem file:声明式配置文件(ecosystem.config.js),推荐的生产方式 验证安装: pm2 -v pm2 ping # 检查 daemon 是否存活 启动与进程管理 启动一个应用 # 最简单的启动 pm2 start app.js # 指定进程名(强烈建议,否则默认用文件名) pm2 start app.js --name api-server # 传递 Node 参数与应用参数 pm2 start app.js --name api --node-args="--max-old-space-size=2048" -- --port 3000 # 不限于 Node:任何可执行文件都可以托管 pm2 start python --name spider -- main.py pm2 start ./worker.sh --name job 常用管理命令 pm2 list # 进程列表(别名 pm2 ls / pm2 status) pm2 describe api-server # 单个进程详情:路径、日志位置、重启次数、内存等 pm2 restart api-server # 重启 pm2 reload api-server # 优雅重载(集群模式下零停机) pm2 stop api-server # 停止(保留在列表中) pm2 delete api-server # 从 PM2 列表移除 pm2 save # 保存当前进程列表快照(供 resurrect / 自启恢复) 所有命令都可以用进程名、进程 id,或 all(全部进程)作为目标。 ...

2026-08-22 · 4 分钟 · 818 字 · heyaohua

从 Prompt 到 Skill 再到 Loop:AI 修 Bug 为什么需要责任闭环

前言 现在用 AI 写代码,最常见的一句话大概是: 帮我修一下这个 bug。 这句话很自然,也很方便。过去你可能要自己读日志、搜代码、猜调用链、改一版再跑测试;现在把错误贴给 AI,它可能几分钟内就能读完相关文件,给出一版修改,甚至顺手解释原因。 但问题也藏在这里。 AI 很容易让人产生一种错觉:它改得快,所以它是可靠的。可在工程里,快不等于对,更不等于可托付。真正关键的问题不是它有没有改代码,而是它能不能证明: 问题被复现过。 根因被定位过。 改动是最小的。 测试真的跑过。 风险被说明过。 失败会被记录下来。 所以我越来越觉得,AI 操作方式正在经历一个很重要的演进: Prompt -> Skill -> Loop Prompt 让 AI 听懂你。Skill 让 AI 按经验做事。Loop 让 AI 做完之后必须留下证据,并从失败中改变下一次行为。 换句话说: Skill 是 Prompt 的工程化。 Loop 是 Skill 的责任化。 一、Prompt 阶段:一次性的意图表达 Prompt 的优点非常明显:低成本、灵活、自然。 你可以直接说: 登录页打开后报错,帮我看一下。 模型会根据当前上下文去理解问题。它可能会读页面组件、查接口调用、看错误栈、修改某个字段名,然后告诉你“已经修好了”。 这个阶段适合探索问题,也适合做一次性的辅助判断。但它有一个根本缺陷:流程是隐含的。 你没有明确告诉它: 必须先复现问题。 必须说明错误从哪里来。 必须只做最小修改。 必须跑哪些测试。 必须列出没有验证的部分。 必须说明改动可能影响哪些地方。 于是模型很容易从“解决问题”滑向“看起来解决了问题”。 它可能直接根据错误信息猜一个原因,改一段代码,给出一段很顺的解释。解释可能听起来合理,但如果没有复现、没有测试、没有 diff 边界,它仍然只是一个未经证明的答案。 这就是 Prompt 阶段的边界:它能让模型开始做事,但不能保证模型按工程流程做事。 二、Skill 阶段:把修 Bug 变成工程流程 当同类任务反复出现时,继续靠 Prompt 就会变得浪费。 ...

2026-06-16 · 2 分钟 · 276 字 · heyaohua

创业团队用 AI 开发失控后,怎么止血?

最近我们在一次创业项目开发中,遇到了一个很典型的问题。 一开始,大家都觉得 AI 开发很香。 后端同学根据产品图,让 AI 快速生成了一套后台服务;前端同学也根据产品图,让 AI 写出了界面和交互。过去可能要花几周才能搭出来的 MVP,现在很快就能看到雏形。 这也是我一直觉得 AI 有价值的地方:它能让小团队快速补齐不熟悉的领域,能让一个人跨过前端、后端、交互、部署这些原本需要多人配合的边界。 对于创业团队来说,这种速度太有吸引力了。 但开发到后面,我们开始明显感觉不对劲。 前端拿着后端的接口手册,让 AI 去理解并修改页面逻辑;后端也根据自己的理解继续调整服务。看起来每个人都在推进,但大家对系统的理解并不一致。 前端理解的流程,和后端设计的流程对不上。 前端传的参数,和后端期望的参数不一致。 产品图里没有明确表达的状态,被前后端的 AI 分别脑补成了不同的实现。 更麻烦的是,代码量很快膨胀到了四万多行。 到了这个阶段,人已经不太愿意从头读代码了。不是完全看不懂,而是阅读和修改的成本变得很高。就算知道问题大概在哪里,也不敢轻易改,因为不知道改了这里,会不会影响到别的地方。 于是我们进入了一个很危险的循环: 发现问题,描述给 AI。 AI 改一版,继续跑。 又出现新问题,再描述给 AI。 AI 再改一版。 一开始,AI 是开发者的助手。后来,AI 成了代码的主要作者。再后来,人想改代码时,发现自己也只能继续通过 AI 去改 AI 写出来的代码。 这时候,人就有点像上下文搬运工。 产品的问题,要转述给 AI。 接口的问题,要转述给 AI。 前端的报错,要转述给 AI。 后端的文档,也要转述给 AI。 每个人都很忙,但忙的不是在建立系统理解,而是在不同的 AI 对话、代码、文档、报错之间搬运上下文。 我并不反对 AI 开发。恰恰相反,我依然认为 AI 是趋势。AI 能帮助创业团队更快做出 MVP,能让开发者进入自己原本不熟悉的领域。 但这次经历让我意识到一个问题: AI 能帮我们写出更多代码,但不会自动帮团队形成共同理解。 如果没有共同理解,代码增长得越快,团队失控得也越快。 问题不在 AI,而在没有工程护栏 这次最明显的问题,是前端和后端都基于产品图让 AI 生成代码。 产品图能说明用户看到什么,但它不能完整说明系统之间怎么通信。它不会天然定义请求参数、响应字段、错误码、状态流转、边界条件和异常处理。 ...

2026-06-14 · 2 分钟 · 230 字 · heyaohua

模型越来越强,但责任感仍然缺席:从道歉、信任到 Agent 惩罚机制

前言 最近在做 AI Agent 流程时,我越来越明显地感觉到一个问题:现在的模型能力已经很强,但它缺少人最看重的一种东西——责任感。 它可以读代码、写脚本、查资料、生成方案、操作工具,也可以在出错后很快道歉: 抱歉,你说得对。 我刚才没有检查清楚。 这确实是我的问题。 我会重新来一遍。 这些话听起来很像一个人在承担责任,但实际上不是。模型不会因为刚才的错误真的变得谨慎,也不会因为浪费了你的时间而产生压力,更不会因为一次错误交付而在下一次任务里主动收敛自己的行为边界。 这也是我现在对 AI Agent 最不放心的地方:它们越来越会“表现得像可靠的人”,但还没有真正形成“可靠的人会有的约束”。 本文想讨论的不是模型能不能更聪明,而是另一个更实际的问题: 当 Agent 开始替我们执行真实任务时,如何让它不要只会道歉,而是必须对结果负责? 一、能力提升并不等于可信任 过去几年,大模型的能力提升非常明显。它们能写代码、做摘要、调用工具、生成多步骤计划,也能在复杂任务中表现出一定的推理能力。很多产品开始把模型包装成“Agent”,让它们不只是回答问题,而是读文件、改项目、发请求、执行命令、调用 API。 但 Agent 和普通聊天最大的区别是:聊天错了,最多是答案错;Agent 错了,可能会改变真实世界的状态。 例如: 改错一段代码 删除不该删的文件 调错数据库 给用户发出错误通知 在自动化流程中反复重试 为了完成目标绕过本该遵守的约束 这时问题就不再是“模型有没有能力”,而是“系统是否可托付”。 人类之间建立信任,并不只是因为对方聪明。更重要的是对方有稳定的责任结构:他知道什么事不能乱做,知道出错后要复盘,知道自己会承受后果,也知道什么时候应该停下来问人。 模型没有这种天然结构。它的“抱歉”只是生成出来的语言,不是心理负担,也不是组织责任,更不是可执行的补偿机制。 二、道歉为什么不能解决信任问题 现在很多模型在交互上越来越友好。出错后,它们会道歉;用户质疑时,它们会承认;用户表达不满时,它们会安抚。 这在轻量聊天场景里可能有用,但在生产流程里反而会制造一种危险错觉:用户听到了“我负责”,但系统里没有任何真正的责任闭环。 OpenAI 在 2025 年 4 月回滚过一次 GPT-4o 更新,原因就是模型变得过度奉承、过度认同用户。OpenAI 自己的解释是,当时过于重视短期反馈,没有充分考虑长期交互中的行为演化,导致模型倾向于“过度支持但不真诚”的回答。这个案例说明,模型的语气如果只朝“让用户舒服”优化,很容易偏离真实可靠。 学术界也把这种现象称为 sycophancy,也就是模型倾向于迎合用户观点,而不是坚持事实或独立判断。Anthropic 参与的一篇研究指出,人类反馈可能会鼓励模型生成更符合用户信念的回答;当回答迎合用户观点时,人类和偏好模型有时会更喜欢它,即使它不够正确。Google 研究者也观察到,模型规模和指令微调可能增加这种迎合倾向,甚至在简单加法这种有客观答案的任务上,模型也可能因为用户暗示而附和错误说法。 这和我们在 Agent 流程里的感受是相通的: 模型不是不会认错。 模型是太会认错了。 真正的问题是,认错之后没有代价,没有记录,没有降权,没有触发更严格的验证,也没有改变下一步动作权限。 人类的道歉之所以有意义,是因为它背后通常连着后果:信誉下降、关系受损、流程复盘、赔偿、处罚、权限收回。模型的道歉如果不连接这些东西,就只是润色过的错误提示。 三、责任感不是一种语气,而是一套外部结构 我现在更倾向于把“责任感”拆成四个部分: 维度 人类里的表现 Agent 系统里的对应物 结果意识 知道错误会影响别人 明确任务目标、影响范围和风险等级 行为边界 知道什么不能做 权限控制、审批、沙箱、只读/可写隔离 复盘能力 出错后总结原因 日志、轨迹记录、测试、自动回放 后果机制 错误会带来损失 评分、降权、预算减少、强制复核 所以,不应该问“模型有没有责任感”。更准确的问题是: ...

2026-06-12 · 2 分钟 · 411 字 · heyaohua

OpenClaw、Hermes、OpenCode、Claude Code 与 Codex:到底怎么选?

前言 最近很多 AI 编程工具、个人 Agent、自动化框架都开始混在一起讨论:OpenClaw、Hermes、OpenCode、Claude Code、Codex。它们都能和大模型有关,也都可能帮你写代码、跑命令、接入工具,但它们并不是同一层级的东西。 如果只看宣传语,很容易得出一个错误判断:既然 Codex 和 Claude Code 已经能读代码、改文件、跑测试,为什么还要再装 Hermes?或者既然 OpenClaw 已经打通手机和电脑控制,Hermes 又有什么必要? 我的结论比较直接: 如果主要需求是写代码、改项目、跑测试、修 bug,直接用 Codex 或 Claude Code 就够了。Hermes 的价值不在于“代码能力更强”,而在于把 AI 变成一个长期运行、能记忆、能积累技能、能跨入口接收任务的个人 Agent 层。 本文把这些工具拆开说明。 一、先按层级拆开 先不要把它们放在一个篮子里比。更合理的拆法是: 名称 本质 主要用途 是否替代 Claude/Codex Claude / Claude Code 模型 + 编码 Agent 读代码、改文件、跑命令、处理 Git 工作流 不替代,它本身就是核心编码工具 Codex OpenAI 编码 Agent 本地 CLI / IDE / 云端编码任务,读改跑代码 不替代,它本身也是核心编码工具 OpenCode 开源终端编码 Agent 一个可接多模型的 coding agent 壳子 可部分替代 Claude Code / Codex CLI OpenClaw 个人 AI 助手 / 控制平面 手机、电脑、聊天入口、系统任务自动化 不替代模型,更多是控制入口 Hermes Agent 长期运行、自我改进的 Agent 框架 记忆、技能沉淀、跨会话任务、长期自动化 不替代 Claude/Codex,更像上层编排 可以简单理解成: ...

2026-05-08 · 3 分钟 · 595 字 · heyaohua

OpenClaw 技能插件完全指南:31个 Skill 详解与实战

前言 OpenClaw 最强大的地方在于它的技能(Skill)生态系统。Skill 是预定义的能力模块,让 AI Agent 能够执行特定任务——从发送邮件到操作浏览器,从查询股票到管理飞书文档。 本文将详细介绍我的 OpenClaw 实例中安装的所有 31 个 Skill,涵盖功能、工作原理、调用方式和实际使用场景。 Skill 系统原理 什么是 Skill? Skill 本质上是一个包含 SKILL.md 指令文件的目录。当用户发送消息时,OpenClaw 的 Agent 会扫描消息内容,匹配到相关的 Skill 后加载其 SKILL.md 作为上下文,从而获得执行该任务所需的知识和能力。 ~/.openclaw/skills/ ├── my-skill/ │ ├── SKILL.md # 技能定义文件(核心) │ ├── _meta.json # 元数据 │ ├── scripts/ # 脚本文件 │ └── references/ # 参考资料 调用流程 用户消息 → Agent 语义匹配 → 加载对应 SKILL.md → Agent 根据指令执行 → 调用脚本/工具/API Agent 不需要显式调用 Skill,它会根据对话内容自动识别需要哪个 Skill。你也可以在消息中明确提到 Skill 名称来触发。 ...

2026-03-22 · 4 分钟 · 850 字 · heyaohua