为什么 AI 账单比主机账单难预测得多

两种账单,两种形状 主机账单是容量。你加 CPU、带宽、存储,表针跟着流量曲线走;看过一个月,下个月能猜到几个百分点以内的误差。 token 账单是行为。两个流量完全一样的团队,账单可以差 20 倍——因为一个团队每次请求带 12,000 token 的检索上下文,另一个只缓存了 400 token 的系统提示、其余什么都不带。同样的用户、同样的功能,账单天差地别。 这不是定价的猫腻,而是计量方式决定的:你按 token 付费,而 token 数量是设计决策。 让花费变跳的三个效应 1. 输入通常远多于输出,两者单价还不一样。 在多数对话与检索功能里,输入 token 是输出的 5~20 倍,而输出 token 的单价往往是输入的几倍。所以「我们只生成一小段回答」这句话,对成本没有任何说明力。 2. 缓存输入是另一套费率。 供应商对重复出现的输入给更便宜的价格——固定的系统提示、不变的长文档、大段指令。忽略缓存,就等于每次请求都为同样的 3,000 token 付全价。 3. 每次请求的上下文能差一个数量级。 一个每轮都追加对话历史的总结任务,等于每次都把整份记录重新发一遍。成本增长比轮数更快:第 20 轮很贵,是因为第 1 到 19 轮又在账单上出现了一次。 重试和工具调用还会再加一个在任何用量图表里都看不见的乘数:一次失败后重试的调用会计费两次;每轮调四个工具的 Agent,每轮计费五次。 杠杆,按收益排序 团队的第一反应通常是去换模型。那很少是最大的杠杆。建议按这个顺序试: 先砍上下文。 删掉检索到却不影响答案的文档、限制回溯的历史长度、把永不变的部分放进缓存。这往往是单项收益最大的一步。 限制输出长度。 直接要求形状(「三条要点,不要前言」),而不是给一个宽松的 token 上限。模型生成的那 900 token 客套话,是你在付费。 不紧急的走批次。 夜间补数、回填、评测这类任务通常可以接受更慢但更便宜的路径。 最后才换模型。 把摘要任务降级到更小的模型确实是省钱——但这是在前面三步已经压小的那个数字上,再省一次。 上线前先估一遍 你需要每次请求的两个数字:输入 token 与输出 token。功能已经上线,就直接从 API 返回里读,不要估。还没上线,只能先猜: 每月成本 ≈ 每天请求数 × 30 × (输入 ÷ 1M × 输入单价 + 输出 ÷ 1M × 输出单价) 猜的时候有两个坑:一是平均数会掩盖最贵的那次请求(一份长文档的 p95 请求可能是中位数的 30 倍,而账单正是它决定的);二是多轮功能让平均数失去意义,因为每一轮都拖着完整历史。 ...

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

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

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