打分 → 生成话术。
最近发现这一段忽长忽短:快的几秒、慢的好几分钟,看不出原因。
本页把这一段拆成 3 个子环节,先讲每段在干什么 →
用今天「零星」+「小文」账号实测定位瓶颈 →
再串讲今天一天 PR #349(节奏门收紧)→ #355(事件驱动 + 城市超时)→ #358(5s 软冷却)→ #359(perAccountMax 1→3)四次接力,
一步步把这一段从一周前估计的 ~75s 砍到 PR #355 实测 41s → 预期最终 ~18s(待明日实测复评)。
直接跳第 6 节看总结 ↓
runDispatch 事件驱动,绕过 cron tick 天花板。perAccountMax 1 → 3。真正的最后一公里—— 实测发现小文 A=39s 仍是 cron tick 主导,原因是每账号每轮 trigger 最多入队 1 条,余下 mid/high 等下一轮(事件驱动 2min / cron tick 1min)。改 3 后一次最多入队 9 条,把"等下一轮"那一档也消除。脚本 scripts/_breakdown-lingxing-score-to-opener.ts 拉「零星」账号 2026-06-15 北京时间今天所有 dispatch_queue.status=sent 的前 10 条 ——
| # | 客户 (评论片段) | A 等派单 | B 准备料 | C LLM 写 | 合计 | 3 段分布 | 重试 |
|---|---|---|---|---|---|---|---|
| 1 | 四方田 (亳州可以做吗) | 29s | 11s | 3s | 43s | 1 | |
| 2 | 柿柿如意的人生 (那里的) | 13s | 14s | 5s | 33s | 1 | |
| 3 | 老鼠爱大米 (顶楼今年想装修…) | 17s | 13s | 4s | 34s | 1 | |
| 4 | 桐桐妈 (老板是在那个城市) | 4s | 9s | 5s | 18s | 1 | |
| 5 | 下一站 (4楼总9层落地窗…) | 23s | 10s | 4s | 37s | 1 | |
| 6 | 暖暖1331 (给我一份) | 1m4s | 12s | 5s | 1m21s | 1 | |
| 7 | 爆炸妹儿 (需要一份辟雷手册…) | 35s | 11s | 5s | 51s | 1 | |
| 8 | 用户人生如梦 (包柜门拉篮一套…) | 48s | 11s | 5s | 1m4s | 1 | |
| 9 | 雪花 (1,给我来一份) | 21s | 20s | 17s | 58s | 1 | |
| 10 | 玻璃1 (厂在哪里) | 41s | 17s | 5s | 1m3s | 1 | |
| 中位 / 最大 | 26s / 1m4s | 12s / 20s | 5s / 17s | 47s / 1m21s | — | — | |
attempts=1(首轮自检全过),没有重试。说明 prompt 工程已经做得不错;C 段优化收益最低。| 当前中位 | 优化项 | 优化后中位 | 节省 | |
|---|---|---|---|---|
| A 等派单 | 26s | cron tick 60s → 30s(白等时间砍半) | ~13s | −13s |
| B 准备料 | 12s | 城市反查 2s 超时 + IP 兜底 + 4 个 DB 读改并发 / 合 1 个 RPC | ~2s | −10s |
| C LLM 写话术 | 5s | 不动(已经很稳,attempts=1 全场,没低垂果实) | 5s | 0 |
| 合计中位 | 47s → 优化后 | ~20s | −27s(−57%) | |
vercel.json)+ ② 城市反查加超时 + 4 个 DB 读改并发,
总工程量不到 1 小时,就能把这一段中位从 47s 砍到 ~20s(−57%)。
C 段(LLM 写话术)目前 5s 是物理下限,不动。
下面 7 个机会,前 3 个就是上面"优化后效果"表里那些;后 4 个是边际收益小的二期项,做完前 3 个再看 ——
* * * * * 已经是它支持的最高频,不能改成 30s。
改方案:事件驱动 —— 在 /api/cron/analyze 打分完末尾同步调 runDispatch(enforcePacing=true),新评论直接被派、不等下个 cron tick。1min cron 保留兜底(老 backlog)。
已部署:2026-06-15 15:33 CST · commit 14f8c51。
src/app/api/cron/analyze/route.ts + 加 60s 预算保险enrichCommentCity 调外部接口反查城市,接口抽风时整条派单被它卡死。
已落地方案 A:fetchUserProfileFromWorker 加 opts.timeoutMs,默认仍是 8s(peer gate 不变,宁慢勿漏同行),仅 enrichCommentProfile 内部传 2000ms。
超时即 city=null,dispatch 已 fail-open 降级到 comments.ip_location(IP 库 → 省/市,精度够开场白用)。
已部署:2026-06-15 15:33 CST · commit 14f8c51(含 self-review fix 279efc0)。
src/lib/enrich-user-city.tsresolveAddressForm 兜底),省掉这次 LLM 调用 → 直接砍 1~2s。
generateOpener 内部改 Promise.all / 删掉 smart 走规则37b3541)。节奏门 base 60s → 30s + jitter 30s → 5s + 三个云电脑账号 accounts.min_send_interval_seconds DB UPDATE。
效果:节奏门要求从 60~120s 砍到 30~35s < cron tick 60s。节奏门不再是 A 段的限速器,cron tick 接管成为天花板(直到 PR #355 把这个天花板也绕过)。
继续砍到 15s 没意义 —— 实际等待已经是 cron tick / dispatch 自身耗时决定,不是节奏门。详见姊妹页《四道闸门》。
复评日 2026-06-22,无 7911 触发即固化。
59a1ca4)。PR #355 部署后实测 A 中位 26s → 25s 几乎没动,诊断发现 dispatch lib 的 shouldPaceSkip 仍按 30s 拦事件驱动 trigger,paced_skip 后等下一 cron tick。
改动:DispatchOptions 加 softCooldownSec?,enrichCommentProfile 路径传 2000ms,仅 analyze 末尾 trigger 时节奏门 base 用 5s(cron 路径仍 30s 不变)。
硬门(积压/小时/日限/滚动 24h)全保留,总量风控不变。
c717986)。PR #358 后实测小文 A=39s(n=7,case "我的我" A=1m45s 连撞两轮 cron tick),诊断:小文相邻发送 3~20min >> 30s 节奏门,节奏门 / 软冷却根本没机会咬 —— 真正的瓶颈是 perAccountMax=1 让每次 trigger 最多入队 1 条/账号,余下 mid/high 要等下一轮 trigger。
改动:两条路径(事件驱动 + 1min cron)都改成 3,一次最多入队 9 条。节奏门继续约束实际发送间隔,总量上限仍由小时门/日限门锁死。
预期:A 中位 39s → ~5s、合计 56s → ~18s。
provider routing 偏好速度,让请求自动落到延迟最低的 provider。
不推荐方案:本地缓存——每条评论的 prompt 都不一样(含评论原文/姓名/城市),命中率几乎为零。
LLM_CHAT_MODELpreviousFailureReason)。
收益看现在自检失败率有多高 —— 需要先拉 Langfuse 看真实分布。
load_dispatch_context RPC| 序 | 动作 | 影响段 | 预计省时 | 实现成本 / 风险 |
|---|---|---|---|---|
| ✓ 1 | 事件驱动派单(cron tick 改不了 30s,改了别的) | A | ~24s | 已完成 PR #355 · 2026-06-15 15:33 |
| ✓ 2 | 城市反查超时 8s → 2s(仅富化路径) | B | ~10s | 已完成 PR #355 · 2026-06-15 15:33 |
| 3 | 城市富化提前到 analyze 阶段 | B | 中位 ~500ms | 改 /api/cron/analyze 多一步写回;风险:analyze 慢一点但 270s 预算够 |
| 4 | 称呼解析改回规则 / 并行化 | C | ~1.5s | 改 generateOpener;风险:低,已有规则兜底,最坏退化为旧行为 |
| ✓ 5 | 节奏门 base 60s → 30s、jitter 30s → 5s | A | 节奏门退出限速器 | 已完成 PR #349 · 2026-06-15 13:09(复评日 6/22) |
| ✓ 5' | 事件驱动专用 5s 软冷却 | A | 绕过 30s 节奏门拦截事件驱动 | 已完成 PR #358 · 2026-06-15 16:37 |
| ✓ 5'' | perAccountMax 1 → 3(绕过 cron tick 批次天花板) | A | A 中位 39s → ~5s(预期) | 已完成 PR #359 · 2026-06-15 18:22 |
| 6 | 主 LLM 模型 bake-off | C | ~2~4s | 需要走 eval harness,建议 AKKE_USE_EVAL_KEY=1 烧 OpenRouter eval key 跑对比 |
| 7 | 4 个 DB 读合 1 个 RPC | B | ~150ms | 收益小,不优先 |
claimedFromPoolAt + openerFinishedAt 两个字段),
跑一周收集真实分布数据,再用真实占比决定优先级 ——
比如如果 A 段中位是 50s、B 段中位是 0.5s、C 段中位是 5s,那城市反查的优化就完全不该排第 2。
现在的优先级是基于"理论上哪段最长尾",需要数据校正。
把今天落地的 4 个 PR 串起来看,从"一周前的状态"到"今天 18:22 第四次接力部署完",这一段中位的演进 ——
| 时间点 | 关键改动 | A 段 | B 段 | C 段 | 合计中位 | 瓶颈在哪 |
|---|---|---|---|---|---|---|
| ~2026-06-07 PR #315 之前 |
节奏门 base 120s/60s + jitter 0~min_interval | 推 50~90s | ~12s | ~5s | ~75s+ | 节奏门要求 60~240s > cron tick,常被顶到下一班车 |
| 2026-06-08 之后 PR #315 |
jitter 上限 30s + 三账号统一 60s base | 推 40~60s | ~12s | ~5s | ~57s | 节奏门 60~90s 仍可能顶到下一班,cron tick 60s 也常咬 |
| 2026-06-15 13:09 PR #349 后(实测) |
节奏门 30s + 5s · 「踢出限速器位置」 | 26s | 12s | 5s | 47s | 节奏门退场 · cron tick 60s 接管 + 城市反查长尾 12s |
| 2026-06-15 16:13 PR #355 后(实测,零星) |
事件驱动 trigger + 城市反查 2s 超时 | 25s | 11s | 5s | 41s | 效果远低于预期 · 节奏门拦截事件驱动 |
| 2026-06-15 17:41 PR #358 后(实测,小文 n=7) |
事件驱动专用 5s 软冷却 | 39s | 9s | 4s | 56s | 节奏门虽绕过,但 perAccountMax=1 + cron tick 仍主导 |
| 2026-06-15 18:22 PR #359 后(预期,待明日实测) |
perAccountMax 1 → 3(绕过 cron tick 批次天花板) | ~5s | ~9s | ~4s | ~18s | 一次 trigger 入队最多 9 条,余下不用等下一轮 cron tick |
| 从 6/7 前到 6/15 末:合计中位 75s+ → ~18s · −76%(最终待实测复评) | 四次接力归零 cron 限制 | |||||
每解决一层,下一层就浮出来当瓶颈。本以为两层就够,实际四层才到 dispatch lib 自身:
shouldPaceSkip(30s) → paced_skip → 还是等下一 cron tick → A ≈ 25s(几乎没动)。最终预期:A 段瓶颈降到 dispatch lib 本身耗时(DB 读 + claim RPC + insert)≈ 2-5s。 总量风控(小时门 10/h + 日限 25/d + 滚动 24h × 2)一直没动,7911 风险无增量。
_breakdown 复评 ——
预期 A 中位 39s → ~5s、合计 56s → ~18s(−76% vs 一周前 75s)。
复评日跟 PR #349 一起 2026-06-22,观察一周无 7911 + 无举报即固化。
/api/public/cloud-pc-dm-live(监控页 API)· src/lib/cloud-pc-dispatch.ts(派单主流程)·
src/lib/llm.ts generateOpener(话术生成)· supabase/migrations/20260519115500_llm_observability_foundation.sql(latency_ms 字段)·
scripts/_breakdown-lingxing-score-to-opener.ts(账号 8af08f10 零星·北京 2026-06-15 当天 dispatch_queue.status=sent 前 10 条实测)。37b3541(节奏门,13:09)· PR #355 = 14f8c51(事件驱动 + 城市超时,15:33)·
PR #358 = 59a1ca4(5s 软冷却,16:37)· PR #359 = c717986(perAccountMax 1→3,18:22)。
第 6 节"累计时效提升"中 PR #349 之前的数据是用 dispatch-four-gates-2026-06-15.html 里 6/12-6/14 间隔反推估算;之后为实测;PR #359 后为预期,待明日复评。
生成于 2026-06-15 · 四次接力陆续部署后更新。