一句话定义
请求合并(Request Coalescing)指的是:当多个内容完全相同的请求几乎同时到达时,系统只真正执行一次计算,其余请求会等待这次计算完成,并共享同一个结果。
它是怎么发生的
打个比方。办公室里只有一台咖啡机,早上十点,十个人几乎同时按下“美式”按钮。机器不会做十杯、排十次队;它做一壶,然后分给这十个人。等人散了,下一批人来了,它再做新的一壶。
工程上的实现大概三步:
1. 计算 key:把请求里所有会影响结果的字段拼成一个指纹,比如模型名、完整的提示词、采样参数、工具配置等。
2. 查“在途表”:维护一张表,记录“当前正在计算哪些 key”。如果新请求的 key 已经在表里,就不再发起新的计算,而是挂到那次计算上,等待同一个结果(同一个 future、promise 或回调)。
3. 广播结果:那次计算完成后,结果发给所有等待者,在途表删掉这个 key。
关键在于第二步之后的时间窗口:只有在计算正在进行的那段时间里,合并才会生效。算完,条目就没了,后来的人照样要重新算。
和几个相邻概念的区别
| 概念 | 生效时机 | 匹配方式 | 结果是否留存 |
|---|---|---|---|
| 请求合并 | 计算进行中(秒级以内) | 精确相等 | 不留存,算完即弃 |
| 结果缓存 | 计算完成后的一段时间 | 精确相等 | 留存,可长期复用 |
| 语义缓存 | 任意时刻 | 向量相似、意思相近 | 留存 |
| 批处理 | 攒够一批再发 | 不需要相同 | 不留存 |
最容易混淆的是语义缓存:它靠向量相似度判断“这两个问题意思差不多”,所以“怎么退款”和“退款流程是什么”可能命中同一条。请求合并完全不做这种判断,它要求两个请求一模一样,属于精确去重。差一个标点、改一个参数,就是两个请求。
和批处理(Batching)也不同:批处理是把不同的请求攒在一起送进去,目的是提高吞吐;请求合并是把相同的请求并成一个,目的是少算。
对从业者的实际意义
- 成本与延迟:一个热门提示词被上百人同时触发,合并之后后端只算一次,账单和队列压力都按“一次”算。
- 常见场景:仪表盘定时刷新、同一份报表被多人同时打开、热门内容的首屏加载、Agent 里多个子任务撞上同一个工具调用。
- 必须注意的坑:key 一定要包含所有影响输出的字段,包括租户和权限信息,否则可能把 A 用户的结果发给 B 用户;共享计算失败时,所有等待者会一起失败,要设计好重试;一个等待者取消,不该把其他人的计算也取消掉。
- 一个前提:只有当相同输入必然产生相同输出时,共享才成立。如果采样带随机性,同样的提示词本来就会给出不同答案,这时候合并等于替所有人抽了同一次签,是否可接受要看业务。
对普通职场人来说,请求合并解释了一个日常现象:为什么十几个人同时点“刷新”,页面反而一起变慢。系统并非算不过来,它更可能在为同一件事重复排队。做产品时给按钮加防抖、给报表加共享刷新时间,本质上是在应用同一个思路。
