新农上路
- 积分
- 94
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2012-2-15
- 最后登录
- 1970-1-1
|
注册一亩三分地论坛,查看更多干货!
您需要 登录 才可以下载或查看附件。没有帐号?注册账号 
x
说明:本文基于我自己的系统设计学习笔记,并使用 AI 协助整理结构。它不是 Cursor 内部架构披露,也不是面经或生产经历。文中的公开数据附有来源,其余数字和架构均为设计假设,欢迎大家纠正。
最近准备 AI coding assistant 相关的 system design 时,我发现这类题很容易被回答成“普通 autocomplete + RAG”。但 Tab 类产品的核心约束其实不太一样:它运行频率极高、延迟预算极小,而且错误建议会直接打断开发者。
我想讨论的问题是:如果把“暖会话、邻近 region”的 editor event → first useful paint p95 目标设为 100ms,系统应该怎么设计?
一、公开事实与设计假设
Cursor 公开过几个可以用来估算的数字:
- 2025 年公布的 Fusion 是用于代码编辑的 custom sparse model,server latency 为 p50 260ms,上下文长度为 13k token。
- Cursor 后来披露 Tab 每天处理超过 4 亿次请求。
- 一次 online RL 更新让建议数量减少 21%,同时让显示出来的建议 acceptance rate 提高 28%。
- Tab 的目标不只是插入文本,还包括替换、删除、跳转到下一个位置,以及在不确定时不显示任何内容。
来源:
https://cursor.com/blog/tab-update
https://cursor.com/blog/tab-rl
https://cursor.com/blog/problems-2024
我设定的 p95 100ms 比公开的 260ms server p50 更激进,所以这里只把它当作一道设计题,不能说成 Cursor 已经实现的数据。
二、先定义输出和边界
模型输出不应该只是一段字符串,而应该是 typed action:
- Insert
- Replace/Delete
- Jump
- NoOp
NoOp 必须是一等公民。开发者的注意力也是稀缺资源:低质量或者晚到的建议,可能比不显示建议更差。
其他假设:
- 100ms SLO 只覆盖暖会话和邻近 region。
- 冷启动、跨洲网络或者系统过载时允许静默降级。
- Editor buffer 和 document version 是唯一权威。
- 隐私策略和 ignored files 在客户端先执行;不允许发送的上下文不能离开设备。
- UI 不显示 spinner:要么及时显示建议,要么保持安静。
三、容量估算
按照每天 4 亿次请求:
400,000,000 / 86,400 ≈ 4,630 average RPS
如果按平均值的 5–10 倍设计峰值,大约是 23k–46k global peak RPS。
如果一次请求在系统中停留约 100ms,那么峰值时同时在途的请求数量级约为:
46,000 × 0.1s ≈ 4,600
这些数字仍然不能直接推出需要多少 GPU,因为模型大小、硬件、量化方式、batch size 和输出长度都未知。
更合理的方法是先压测出满足延迟目标时每个 model replica 的 goodput,再计算:
regional replica 数量
≈ regional peak RPS /(单 replica goodput × 目标利用率)
目标利用率不能设得太高,否则突发流量会迅速转化为排队延迟。我会先假设 60%–70%,再额外预留单 AZ 或 replica group 故障的容量。
四、热路径设计
整体路径:
Editor
→ 本地 gate 和增量 context
→ Regional Session Service
→ Deadline-aware Scheduler
→ Warm Tab Model
→ 客户端版本校验
→ ghost text / inline diff / jump
异步旁路:
- Code Index 提前计算和预热候选上下文
- Policy/Model Registry 下发版本化配置
- 隐私过滤后的 feedback 进入 eval、training 和 canary pipeline
关键原则是:数据库查询、全量语义检索,以及每次重新拼接完整 13k prompt,都不应该出现在每个 keystroke 的热路径上。
客户端可以增量维护 AST、cursor neighborhood、最近的编辑轨迹和 diagnostics。代码索引在后台提前准备候选片段,请求只发送 delta 和已经验证、预热的相关上下文。
一个最小请求需要携带:
requestId、sessionId、documentVersion、fileHash、delta、cursor、deadlineAt
响应则携带:
requestId、documentVersion、actionType、edits、nextCursor、confidence、modelVersion
五、100ms 延迟预算
以下全部是设计假设:
- 本地 gate 和增量 context:5–8ms
- 邻近 region RTT:20–30ms
- gateway 和 scheduler:5–8ms
- inference:30–40ms
- 客户端校验和渲染:5–10ms
按上界相加已经接近 96ms,因此 scheduler 不能为了凑更大的 batch 无限等待。
如果请求到达时 queue budget 已经超限,应该 load shed、使用本地简单 fallback,或者直接 NoOp,而不是返回一个已经失去价值的晚到结果。
六、最容易忽略的是取消与一致性
用户输入通常比模型响应更快。新的 keystroke 到来时:
- 客户端立即取消上一请求;
- gateway 和 scheduler 也停止对应工作,而不只是让 UI 忽略结果;
- 每个响应必须携带 requestId、documentVersion 和 fileHash;
- 客户端拒绝任何旧版本、越界或 overlapping edit。
这样既避免 stale suggestion 被画出来,也能减少已经没有价值的 GPU 工作。
七、几个主要 trade-off
- Batch efficiency vs latency
更大的 batch 可以降低单位推理成本,但会增加 queue delay。Tab 这种高频交互应该采用小型连续 batch、严格 queue cap,并根据 queue delay 而不是单看 GPU utilization 扩容。 - 上下文丰富度 vs 新鲜度
每次现查全库太慢;提前检索可能过期。我的选择是后台预热、所有 snippet 携带版本或 hash,热路径只消费经过验证的上下文。 - Sticky session vs 负载均衡
Sticky session 能提高 prefix/KV cache hit rate,但可能造成热点。需要 TTL、容量感知路由和有界 rebalance,而不是永久绑定到一台 replica。 - 建议数量 vs 打扰成本
只优化 acceptance rate 可能鼓励模型输出大量短小、保守的建议。更好的目标应该同时考虑建议长度、后续保留率、连续 action chain,以及错误建议带来的打扰。 八、故障处理
- GPU queue 超过预算:load shed 或 NoOp。
- Session cache 丢失:牺牲一次建议,用 compact snapshot 重建。
- Region 故障:只有在隐私政策和 deadline 都允许时才跨区。
- 模型返回 malformed edit:客户端直接拒绝,不做危险的 best-effort patch。
- 隐私策略拒绝:fail closed,不能为了可用性绕过策略。
九、指标
我会重点观察:
- p50/p95/p99 event-to-useful-paint
- display、accept、partial accept 和 retained-edit rate
- cancellation 和 stale-result rate
- prefix/context cache hit rate
- load-shed rate
- GPU-ms per accepted retained character
最后一个指标比“每次请求成本”更接近真实价值:如果生成了很多内容但用户没有保留,即使单次请求很便宜也没有意义。
想请教大家三个问题:
- p95 100ms 是否值得牺牲这么多 batch efficiency?如果放宽到 150–200ms,应该优先换更强的模型还是更丰富的上下文?
- NoOp 的 reward 应该怎么设计,才能同时考虑接受率、建议长度、后续保留率和打扰成本?
- Code index 和 context prewarm 应该更多放在客户端还是 region 侧?大家会怎么权衡 cache hit、设备资源和隐私边界?
求米,谢谢大家!!
|
上一篇: 讲讲如何防止prompt injection攻击下一篇: 请推荐ai agent design的学习资料
|