AI 编码 Agent 需要的是护栏,不是更多信任

这是协作问题,不是技术问题 这个场景在各个团队反复上演:有人打开了 Agent,看着它干活,然后某一天发现只读开关不见了,或者在你还在看第一个 diff 的时候它还在继续改。一小时后分支上有四十个改动,一半跟任务无关,没人说得清 src/legacy/ 为什么被动过。 接下来的抱怨总是同一句:我已经不认识这份代码了。 严格说,这不是 Agent 的 bug,而是一条从没被写下来的规则,正在被一次次事故发现。 写一段更长的提示词解决不了 第一反应通常是写更长的 prompt:「不要改无关文件、不要删测试、不要动部署配置」。它能撑过这个 session,然后就消失了。 提示词是「每个 session、每个人」的;放在仓库里的文件会被每一次 session、每一位同事、每一个你换用的 Agent 读到——更关键的是,它可以像代码一样被 review。团队只需要在一个 PR 里吵一次,而不是每次被 Agent 吓到才吵。 四道护栏,按收益顺序 1. 规则文件。 AGENTS.md(或 CLAUDE.md,或你的 Agent 从项目根目录读取的那个文件)定义什么叫「做完」:哪些指令才算验证、哪些路径不能碰、哪些事绝对不能自作主张。短到人也会愿意读。 2. 权限清单。 三份清单,结构比语法更重要: 清单 放什么 例子 allow 只读操作,加上项目本来就会跑的 test / lint / build Bash(pnpm test:*) ask 会改写历史、安装依赖、连网的行为 Bash(git push:*) deny 机密文件、正式环境配置、部署流程、破坏性指令 Read(./.env) 没列到的一律回到「问人」。真正要避免的失败模式是:权限宽到没人愿意读。 3. 保护路径。 机密文件、正式环境配置、数据库 migration、CI 定义都要被明确点名,规则文件和 .gitignore 里各写一份。这一步把「判断题」变成「机械检查」——而只有机械检查能扛住截止日期。 4. 合并前的审查清单。 护栏判断不了设计好坏,所以清单负责补位:diff 是不是超出了这个任务该有的规模、有没有删掉或放宽测试、有没有把错误悄悄吞掉、总结里的数据是否都能对应到某次命令输出。 护栏生成器 可以用一份短表单产出上面这四份文件——命令、允许路径、保护路径、要强制的规则——并且跟随页面语言切换中英文。 护栏做不到什么 说清楚边界比夸大宣传重要,因为夸大最容易让团队信错东西: ...

September 13, 2026 · 1 min · 106 words · NavShelf Team

怎么核对 AI 回答里的数字有没有编造

一种没人及时发现的失误 让 AI 总结一条 CI pipeline,你会得到一段很整齐的话:lint 阶段 42 秒、build 3.5 分钟、整条 pipeline 16.4 分钟、比上周快 18%。读起来像一份报告。两个小时后才有人发现 build 从来没有花过 3.5 分钟,而失败率是从另一周抄来的。 这段话看起来没有任何可疑之处。问题就在这里:编造的数字和真实的数字,排版上完全一样。 为什么模型会这样 AI 在写总结时并不是在查你导出档里的行,而是在生成「最像下一个词」的内容——而「像」不等于「有出处」。两种失误最常见: 编造:那里需要一个数字,于是就生成了一个。「失败率 2.4%」会出现,是因为 pipeline 总结里通常有失败率,而不是因为 2.4% 真的存在。 漂移:数字本身是真的,但在流转中变了样——被四舍五入两次、秒和分钟换算错、从相邻的行/周/项目里串了行。 这两种都能通过人工审阅,因为审阅看的是文字逻辑,不是算术。 五分钟核验流程 1. 留原始导出,不要只留摘要。 把 CSV、日志、SQL 查询结果交给 AI。如果来源本身就是摘要,就没有东西可以核对了。 2. 把每个数字都当成需要出处的断言。 一条实用规则:没有来源行号,就不进报告。 这跟新闻业要求引用出处是一个道理,只是用在算术上。 3. 先对单位,再对数值。 1500 ms、1.5 s、0.025 min 是同一个时长。AI 总结里大量「看起来错」的数字其实是单位或四舍五入造成的,而真正编造的数字就藏在这片噪声里。 4. 留出容差。 摘要里保留三位有效数字的数值不可能和原始的 4183000 完全相等。设一个小的相对容差(1% 是个合理默认值),超出容差的判定为「待核实」,而不是直接判错。 5. 把「待核实」和「错误」分开。 待核实代表你贴的来源里找不到它——它可能是对的,只是来自你还没提供的数据;但在找到那个来源之前,它不能进报告。 AI 数字核验器 把第 3~5 步自动化了:把 AI 回答和来源一起贴进去,它会抽出每个数字、归一化单位与倍数量词、逐一比对,并把找不到出处的标红,同时给出对应的来源行号作为证据。 标红之后做什么 按影响从大到小处理,并给每个数字归类: 现象 常见原因 处理方式 完全找不到,但量级合理 编造 删掉,或者要求给出出处 差几个百分点 四舍五入、口径不同、周期不同 确认统计周期再用 只在单位换算后才匹配 摘要产生的偏差 可以用,但要写清单位 匹配到相邻但不同的行 串行 改正,并复查相邻数字 这套方法的边界 比宣传更重要的是说清限制:核验工具确认的是可追溯性,不是真实性。 ...

September 13, 2026 · 1 min · 106 words · NavShelf Team

等额本息和等额本金怎么选?用一张表算清房贷利息

一个让很多人意外的数字 贷款 100 万,年利率 4.5%,30 年: 月供 5,066.85 还款总额 1,824,067 其中利息 824,067,相当于本金的 82% 更让人意外的是前五年:五年一共还了 304,011,但其中只有 88,421 是本金,剩下 215,590 全是利息。还了五年,本金几乎没怎么动。 这不是陷阱,而是"余额计息 + 长期限"的必然结果。看懂这个形状,你才是在有意识地选贷款,而不是只盯着月供。 你可以在贷款计算器里用自己的数字跟着算。 两种还款方式 等额本息:每月还款额固定不变。前期利息占大头,后期本金占大头。好规划,但总利息更多。 等额本金:每月还的本金固定,所以利息逐月减少、月供也逐月减少。首月最高,末月最低,总利息更少。 计算公式 等额本息:M = P × r × (1+r)^n / ((1+r)^n − 1) 等额本金:每月本金 = P / n,利息 = 剩余本金 × r 其中 P 是本金,r 是月利率(年利率 ÷ 12),n 是还款月数,M 是等额本息的固定月供。 年限的影响比利率还大 同样 100 万、4.5%,只改年限: 年限 月供 总利息 还款总额 10 年 10,363.84 243,660.91 1,243,660.91 20 年 6,326.49 518,358.50 1,518,358.50 30 年 5,066.85 824,067.12 1,824,067.12 从 20 年拉到 30 年,月供只降了 20%,总利息却多了 305,709。这就是多出来的那十年真正的价格。 ...

September 13, 2026 · 1 min · 175 words · NavShelf Team

复利是怎么滚起来的?用一张表算清资产增长

资产增长只有两股力量 你的资产增长永远来自两个来源:你投入的钱,和已经在那里的钱产生的收益。前期几乎全靠前者,越往后后者越占主导——长期财富主要来自这个转折点之后。 单利是线性的:100 元按 7% 每年固定赚 7 元,永远如此。复利是几何的,因为每年的收益是按"更大的基数"算出来的。差别就这一点,结果却天差地别。 计算器用的公式 年末资产 = 年初资产 × (1 + 年化收益率) + 当年投入 有两个假设需要说明,因为它们会直接影响结果: 收益按「年初资产」计算——这正是复利的来源 当年投入按年末计入,从下一年才开始产生收益——这是偏保守的假设。如果你是按月定投,实际结果会比预测略好 你可以用资产增长计算器自己跑一遍,全部在浏览器本地完成。 一个具体例子:10 + 每年 10,收益 7% 初始 10(可以理解成 10 万),每年再投 10,年化收益 7%。 年份 年初资产 当年收益 当年投入 年末资产 1 10.00 0.70 10.00 20.70 2 20.70 1.45 10.00 32.15 3 32.15 2.25 10.00 44.40 4 44.40 3.11 10.00 57.51 5 57.51 4.03 10.00 71.53 6 71.53 5.01 10.00 86.54 7 86.54 6.06 10.00 102.60 8 102.60 7.18 10.00 119.78 9 119.78 8.38 10.00 138.16 10 138.16 9.67 10.00 157.84 十年下来你一共投入 100,最终拿到 157.84——其中 47.84 来自投资收益,接近最终资产的三分之一。 ...

September 13, 2026 · 1 min · 212 words · NavShelf Team

每月该存多少钱才能攒够目标?反过来算一下就清楚了

多数人真正想问的是反过来的问题 大多数计算器告诉你「你将来会有多少钱」。但真正的问题通常是另一个方向:「我想在某个时间点攒到某个数,每月该存多少?」 这是个能直接解出来的方程,而且答案往往比想象中乐观——因为收益替你分担了一部分。 你可以一边看一边用储蓄目标计算器算自己的数字。 先看基准线:收益率 0% 是什么样 目标 100 万,已存 5 万,期限 10 年。 如果完全没有收益,剩下的 95 万要平摊到 120 个月: 950,000 ÷ 120 = 7,916.67 / 月 这是"纯靠自律"的数字,后面每一点收益都会把它往下压。 收益率承担了比想象中更多的份额 同样的目标、同样的 10 年、同样的起始金额,只改收益率: 年化收益率 每月需存 累计存入 收益贡献 0% 7,916.67 950,000.00 0.00 3% 6,673.27 800,792.49 149,207.51 5% 5,909.56 709,146.87 240,853.13 8% 4,859.45 583,134.58 366,865.42 按 5% 算,你只需要存入约 70.9 万,而不是 95 万——目标的四分之一由收益完成。8% 时接近 40%。 但别把这几行当成菜单。 更高的收益率意味着更高的风险和更大的不确定性。稳妥的做法是用保守值(5% 甚至更低,扣掉费用和通胀),到时候比预期好是惊喜。 时间才是威力最大的杠杆 同样的 100 万目标、5 万起始、5% 收益: 期限 每月需存 累计存入 5 年 13,761.01 825,660.32 10 年 5,909.56 709,146.87 20 年 2,102.91 504,699.09 从 10 年拉到 20 年,每月需存从 5,910 降到 2,103,不到一半;而且累计存入反而更少,因为复利多了整整一倍的时间。 ...

September 13, 2026 · 1 min · 187 words · NavShelf Team

Base64 和 URL 编码有什么区别?各自该在什么时候用

Base64 编解码工具 两种编码,两个任务 Base64 和 URL 编码都会把「不安全」的字符替换成安全字符。这种表面相似,正是它们经常被搞混的原因——要么该用一种却用了两种,要么干脆用错了。 一句话版本: Base64 让二进制数据能通过只支持文本的通道 百分号编码 让文本能安全地放进 URL 各自到底做了什么 Base64 用 64 个字符的字母表(A–Z a–z 0–9 + /,末尾用 = 补齐)重写字节。每 3 个字节变成 4 个字符,体积因此增加约 33%。 Man → TWFu Hello → SGVsbG8= 百分号编码把在 URL 里不安全的字符替换成 % 加两位十六进制数(对应 UTF-8 字节)。 a b → a%20b 书签管理 → %E4%B9%A6%E7%AD%BE%E7%AE%A1%E7%90%86 a&b → a%26b 关键区别 Base64 百分号编码 目的 让二进制穿过文本通道 让文本安全地待在 URL 里 字符集 固定的 64 个字符 任意字节,写成 %XX 体积变化 +33% 变化很大 谁能还原 任何人 任何人 提供安全性 否 否 常见位置 JSON 字段、data URI、邮件附件、JWT 查询参数、路径片段 什么时候用 Base64 把小块图片以 data URI 内嵌进 CSS 或 HTML 在 JSON 里传文件、缩略图或签名 通过 MIME 发邮件附件 构造 Authorization: Basic 请求头 JWT 的 header 与 payload 段 需要双向转换时,直接用 Base64 编解码工具,不用装任何东西。 ...

September 12, 2026 · 2 min · 214 words · NavShelf Team

Unix 时间戳是什么?怎么转换成日期时间

一串看不出含义的数字 1735689600 是一个合法的时间,1735689600000 也是。两者含义相差 1000 倍,肉眼看不出区别——这正是最容易踩的第一个坑。 它们都是 Unix 时间戳:从 1970-01-01T00:00:00Z(纪元时间)起经过的时间。数据库存它、接口返回它、日志里全是它,但人脑读不了它。 秒还是毫秒? 知道规则就很简单: 位数 单位 大致对应 10 位 秒 2001 → 2286 年 13 位 毫秒 同样日期,数值 ×1000 JavaScript 的 Date.now() 返回毫秒,而多数后端语言和 Unix 命令返回秒。这个不匹配是经典 bug:毫秒值除以 1000 会得到 1970 年附近的日期,秒值当成毫秒用同样会落到 1970 年。 Unix 时间戳转换工具 会自动识别位数,两种都显示。 为什么转换出来"不对":时区 时间戳本身没有时区,它表示一个绝对时刻;是渲染方式带了时区。 2026-01-01T00:00:00Z(UTC)在北京是 2026-01-01 08:00:00 在纽约是 2025-12-31 19:00:00 所以当时间戳"显示成了前一天",问题几乎总是:少写了 Z、缺了时区偏移,或者服务端按本地时间格式化而客户端按 UTC 理解。 转换工具会把 ISO 8601(UTC) 和 本地时间 两行并排显示,差异一眼可见。 实际使用中的几个场景 数据库:存 UTC,按用户时区渲染。存本地时间是少数几个很难挽回的日期决策之一。 日志:请求旁边那个 10 位数字,基本都是秒级 epoch 时间。 接口:看字段名——created_at、createdAt、timestamp 常常是 epoch 值,但单位不能靠猜,看位数。 ...

September 12, 2026 · 1 min · 153 words · NavShelf Team

JSON 怎么格式化和校验?常见错误与修复方法

为什么 JSON 总是难以阅读 每个接口返回、每份配置文件、每行日志都是 JSON。压缩后它是一整块字符墙;格式化之后同样的数据两秒就能扫完。数据完全相同,差的只是空白——这也是「JSON 格式化」成为开发者最常用搜索之一的原因。 格式化、压缩、校验的区别 操作 改什么 什么时候用 格式化 加缩进和换行 阅读、评审、排查问题 压缩 去掉所有多余空白 传输、存储配置 校验 不改内容,只报语法错误 提交请求体或配置文件之前 这三件事在 JSON 格式化工具 里都只差一次点击,而且全程在浏览器本地完成。 什么才算合法的 JSON JSON 的语法非常小,而且比 JavaScript 严格得多: 键名必须用双引号包起来 字符串必须用双引号,单引号不合法 不允许多余的逗号 不允许注释(// 和 /* */ 都不行) 值只有这几种:对象、数组、字符串、数字、true、false、null 数字不能有多余的前导零,NaN / Infinity 也不是合法值 如果你写过 JSON5、JSONC(VS Code 配置)或者 JavaScript 对象字面量,其中一些习惯在 JSON 里是非法的。 最常踩的五个错误 1. 多了一个逗号 { "name": "NavShelf", "version": "1.0", } "1.0" 后面那个逗号,是 JSON 报错的第一大来源。 2. 用了单引号 { 'name': 'NavShelf' } JavaScript 合法,JSON 非法。 3. 键名没加引号 { name: "NavShelf" } 同样:JavaScript 合法,JSON 非法。 ...

September 12, 2026 · 1 min · 160 words · NavShelf Team

URL 编码(百分号编码)完全指南:查询参数怎么正确转义

一个典型的坏链接 你拼了一个搜索链接,英文下一切正常,用户一输入中文就崩: https://example.com/search?q=书签管理 & page=2 服务器收到的 q 是 书签管理 ,还多了一个叫 page 的参数——本该属于查询值的 & 被当成了分隔符。#、=、?、+ 和空格也有同样的问题。 解决办法是百分号编码(URL 编码):把不安全字符替换成 % 加两个十六进制数字,表示它的 UTF-8 字节。 书签管理 → %E4%B9%A6%E7%AD%BE%E7%AE%A1%E7%90%86 & → %26 空格 → %20 哪些字符是安全的 RFC 3986 把字符分成"未保留"和"保留"两类,只有未保留字符可以原样出现: 类别 字符 说明 未保留 A–Z a–z 0–9 - _ . ~ 任何位置都安全 保留(结构类) : / ? # [ ] @ 在 URL 中有结构含义 保留(子分隔符) ! $ & ' ( ) * + , ; = 在查询串中有含义 其他 空格、"、<、>、%、{}、中文… 必须编码 保留字符不是"不能用",而是"有含义"。关键问题永远是:这个 & 是想表达结构,还是想表达数据?如果是数据,就编码它。 ...

September 10, 2026 · 1 min · 204 words · NavShelf Team

Base64 编码是什么?原理、用途与在线工具使用指南

Base64 要解决什么问题 很多系统只传"文本":邮件协议为 7 位 ASCII 设计,JSON 定义为文本,HTML 属性里放的是字符串。但我们真正想传输的东西——图片、PDF、密钥、二进制协议数据——是字节流,里面很容易混进控制字符、引号和换行。 把原始二进制直接塞进文本通道,迟早会出问题:换行被改写、引号提前结束字符串、代理服务器吃掉一个字节。Base64 的做法是:只用 64 个所有文本系统都认的字符重新表示这些字节。 A–Z a–z 0–9 + / 末尾的 = 只用于补齐。整个字母表就这些。 Base64 的原理 Base64 每处理 3 个字节(24 位),就把它们重写成 4 个字符(4 × 6 位): 输入 位数 输出 Man 24 位 TWFu Ma 16 位 + 补齐 TWE= M 8 位 + 补齐 TQ== 由此直接得到两个结论: 结果大约比原文大 33%(3 个字节变成 4 个字符); = 的数量告诉解码器最后一组缺了几字节,一个或两个 = 表示末尾不完整。 Base64 是可逆的、完全公开的编码,没有密钥,也没有任何保密性。 日常开发中在哪里遇到 Base64 Data URI:background-image: url(data:image/png;base64,...) 把小图标直接内嵌进 CSS。 JSON 接口:在 JSON 字段里传文件、缩略图或签名。 邮件附件:MIME 用 Base64 编码附件,让它们能穿过只支持文本的邮件服务器。 HTTP Basic 认证:Authorization: Basic dXNlcjpwYXNz 就是 user:pass 的编码结果。 JWT:Token 的 header 和 payload 两段都是 Base64URL 字符串。 Base64 不是加密 这是最重要的一点:Base64 不提供任何保密性。 ...

September 10, 2026 · 1 min · 209 words · NavShelf Team