GitHub Copilot 的 session / weekly rate limit header
前几天盯 Copilot 的一次响应,看到里面多了两行之前没留意的 header:
1 | x-usage-ratelimit-session: ...rem=5.7&rst=... |
rem=5.7。这个数在掉。我不知道它按什么规律掉,也不知道掉到几要出事。
晚上花了点时间去追,想搞清楚四件事:这俩 header 啥时候冒出来的,rem 到底是什么,它怎么往下走,单次调用扣多少。
前几天盯 Copilot 的一次响应,看到里面多了两行之前没留意的 header:
1 | x-usage-ratelimit-session: ...rem=5.7&rst=... |
rem=5.7。这个数在掉。我不知道它按什么规律掉,也不知道掉到几要出事。
晚上花了点时间去追,想搞清楚四件事:这俩 header 啥时候冒出来的,rem 到底是什么,它怎么往下走,单次调用扣多少。
你每天开的 IDE,到底在为谁设计?
为代码吗?为你吗?还是为”你的手”?
这个问题以前不用问。答案太明显:执行器就是你自己。你盯着光标,一行行写,一个参数一个参数改,一个文件一个文件过。
IDE 所有能力,从语法高亮到 refactor,从跳转定义到 diff,都在服务这个动作链。
可今天不一样了。Copilot coding agent 在后台接活,Codex 在云上并行跑任务,Claude Code 拿到一个 issue 就能自己开 worktree 干活。
你发出的是目标,回来的是 PR。中间那层微操作,开始不在你手里了。
过去一年我写了四篇跟 AI Agent 有关的文章。
洗脑 Copilot 讲怎么用指令让 agent 按你的方式工作。
Agent 陷阱 讲构建 agent 时那些看起来对实际上坑的模式。
AI 育儿博主 讲怎么把大量领域知识喂给 AI。
MCP 启动优化 讲逆向工程 Claude Code 的 MCP 初始化流程。
四个完全不同的话题,写的时候也没想过它们之间有什么关系。
但写完 MCP 那篇之后,我发现它们在讲同一件事。
最近在用 Claude Code 时,用得越顺手,启动时的那阵漫长等待就越显得碍眼。
我装了 9 个 MCP 服务器:sequential-thinking 用来思考,memory 用来记东西,firecrawl 用来抓网页……每一个都是得力助手,但加在一起,每次启动都要对着终端干等十几秒,才能看到输入框。
这十几秒的延迟虽然不算长,但在频繁使用(比如反复重启会话)的场景下,确实有点消磨耐心。
家里那本《崔玉涛育儿百科》,700 多页,厚得像块砖。
不是不想看——是真的没时间。但眼看宝宝马上满周岁了,第 14 章「12-14 个月幼儿」的内容马上就要用上了。什么疫苗要打、吃什么辅食、怎么引导走路……这些知识点散落在几十页密密麻麻的文字里,每次翻书都要重新定位。
我想:能不能把这些精华提取出来,做成那种「一图读懂」的海报?这样需要的时候直接翻手机相册就行。
问题是——我不会设计。不过,我有 Claude。
最近在优化一个序列化框架时,遇到了一些类型安全方面的意外行为。这让我重新审视了JVM泛型系统的底层机制。虽然类型擦除是个老话题,但当我深入分析Kotlin的reified实现时,发现了一些值得思考的细节。
我们都知道Java的类型擦除,但最近在排查问题时,我又重新观察了这个现象:
1 | List<String> stringList = new ArrayList<>(); |
这是类型擦除的基本表现:编译器将泛型参数替换为边界类型。不过这让我想到一个问题:既然编译器会进行严格的泛型类型检查,那反射是如何绕过这些检查机制的?
在构建 Cline AI agent 的过程中,我们发现最危险的不是那些一眼就能看出来的坏想法,而是那些理论上听起来完美、实践中却一败涂地的诱人陷阱。

在 Cline 构建 AI agent 的征程中,我们发现最危险的其实不是那些一眼就能识破的馊主意,而是那些理论上完美无缺、实践中却惨败收场的”陷阱”。这些思维病毒早已蔓延整个行业,吞噬了数百万工程师小时,把一个又一个团队拖进了架构死胡同。
以下是我们见过的三大最常见陷阱:
This message is used to verify that this feed (feedId:97818615095497728) belongs to me (userId:97817750660390912). Join me in enjoying the next generation information browser https://folo.is.
GitHub Copilot 就像一个天赋异禀但野路子出身的“新兵”。它枪法精准(编码能力强),但缺乏战场纪律(工程规范)。
你让它冲锋,它能迅速拿下山头,但阵地上一片狼藉:没有构筑工事(错误处理),不关心侧翼安全(边界情况),弹药随意堆放(命名混乱)。
我们需要的不是一个只会冲锋的“莽夫”,而是一个懂得协同作战、遵守战场纪律的“精锐士兵”。因此,我决定为它编写一套严格的“作战条令”(Prompts),对它进行一次彻底的“军事化改造”,让它乖乖听话。
经过一段时间的研究和实践,我发现 Copilot 这类 AI 工具实际上可以被深度”引导”,甚至达到一种”洗脑”的效果,让它们按照我们的意愿来行动。
flowchart TD
subgraph 被动信息接收
style 被动信息接收 fill:#f9d6c1,stroke:#000,stroke-width:2px;
A[被动接受信息] --> B[算法过度控制]
B --> C[信息茧房]
C --> D[注意力消耗]
end
subgraph 信息主动消费
style 信息主动消费 fill:#c1e1f9,stroke:#000,stroke-width:2px;
E[回归RSS] --> F[掌握信息主动权]
F --> G[自主订阅]
G --> H[控制信息摄入质量]
H --> I[主动选择信息来源]
I --> J[避免无用信息轰炸]
J --> K[减少干扰]
K --> L[专注高质量内容]
L --> M[享受纯粹阅读乐趣]
M --> N[高质量阅读体验]
N --> O[注意力回归有价值内容]
O --> F
end
D --> E
在一些情况下,可能需要将Microsoft Office文件转换为其他格式:
LibreOffice是一个免费、开源的办公套件,在某种程度上可以被视为微软Office的开源替代品。
Spring Integration JDBC分布式锁的实现会需要使用一个serializable级别的事务来获取锁。
如果多个线程同时尝试获取锁,这些事务之间可能会出现顺序问题。
具体而言,可能会遇到以下错误:
1 | org.postgresql.util.PSQLException: ERROR: could not serialize access due to read/write dependencies among transactions |
发生这样的问题其实也不可怕,因为JDBC锁会进行重试。
在一个Kubernetes(K8s)集群中,部署了Prometheus和Grafana用于监控集群本身和应用的状态。
在其中一个Java应用对应的Pod级别观察到了内存上升的现象。具体而言,当该应用刚启动时,内存占用并不高。如果不发送请求给应用,内存将保持在启动时的水平上。
如果大量发送请求给应用并在短时间内持续发送,内存会迅速增加。这在一定程度上是正常的。
一旦内存增加之后,即使停止发送请求和压力,内存使用也不会下降,一直保持在高峰水平。
上面的状况是由Grafana中观察到的。
观察到的现象看起来像是内存泄漏,但实际上并不一定是内存泄漏。
最近在项目中需要使用Spring Integration提供的基于JDBC实现的分布式锁。
在实践的过程中,我们遇到了一些有趣的问题,现在在此记录和总结一下。
一共遇到了两个问题,第一个和time to live有关,第二个还是和time to live有关。
sequenceDiagram
actor event_initiator
participant instance_1
participant instance_2
event_initiator->>instance_1: do something
note over instance_1: instance 1 获得了 lock
instance_1->>instance_1: start doing its thing
event_initiator->>instance_2: do another thing
note over instance_2: instance 2 等待 lock
note over instance_2: 等 ......
note over instance_2: 等 ......
note over instance_1: lock的超时时间TTL到,instance 1还没干完活,但是它失去了 lock<br>失去不同于主动release<br>失去lock后,instance 1还会继续干活<br>而这些活里面可能会有SQL写操作
note over instance_2: instance 2 获得了 lock
instance_2->>instance_2: start doing its thing
note over instance_1,instance_2: 此时二者同时干活,有撞车的风险,因为二者干活的先后顺序没有保证<br> instance 1尚未把它干完活后才能确定的状态写入DB,而instance 2已经开始干活了
note over event_initiator,instance_2: 为了降低风险,可以: <br> ① 想办法尽量让instance 1能在超时前干完活 <br> ② 以防万一可以考虑在合适的时间节点延长锁的过期时间
根据上图所示,我们有两个实例。
2007年,我在读大二。
当时经常会去学校食堂对面的报刊亭买杂志,一本,是《大众软件》,另一本,是《程序员》。
印象中当时《程序员》上的多数文章充满了我没听过的各种缩写与稀奇古怪的名词,文风是老成持重,我看不懂,但很是佩服。
而这当中偶尔会夹杂着几篇文风犀利,睥睨天下的文章,加上作者头像很是非主流,我虽也看不懂,但印象深刻。
这些犀利文章的作者,便经常冠有TW的头衔。
2012年,我在一家小软件公司上了两年的班。
当时我们每半年发布一个版本,每到要发布前夕,程序员便都停止写代码,去做回归测试。