返回博客列表
最佳实践2026-07-2212 分钟阅读

第一性原理砍需求:一个"多会话并发"方案从立项到自我否决的完整思辨

第一性原理 · 需求拆解 · 复杂度税 · 收益上限分析 · 分阶段决策门

WeClaw_70|第一性原理砍需求:一个"多会话并发"方案从立项到自我否决的完整思辨

第五季系列文章第 1 篇(总第 70 篇) - 第一性原理 · 需求拆解 · 复杂度税 · 收益上限分析 · 分阶段决策门


📚 专栏信息

《从零到一构建跨平台 AI 助手:WeClaw 实战指南》专栏 · 第五季

专栏定位:面向开发者和技术决策者的实战专栏,用真实案例和完整代码带你理解如何构建生产级 AI 应用

本文记录一次罕见的完整决策闭环:一个"多会话并发执行"需求,经历了 UltraPlan 三代理方案设计 → 三视角专业评审(发现 5 个 Critical)→ 两轮修订 → 第一性原理收益/成本评估 → 最终砍掉 65% 的方案,只保留 35%。这不是失败的故事,而是工程决策的最佳实践:最贵的代码是不该写的代码。


👨‍💻 作者与项目

作者简介:翁勇刚 WENG YONGGANG 新概念龙虾-WeClaw 开发团队负责人,一群专注于跨平台 AI 应用的实践者 理念:"再复杂的技术,也能用代码讲清楚"


📝 摘要

本文结构概览: 从一个看似理所当然的需求出发——"桌面 AI 助手应该支持多个会话同时执行任务"——完整走一遍方案设计、专业评审、两轮修订的流程,然后在实施前的最后一刻,用第一性原理把需求拆回原子层面,发现"并发"只是手段而非目的,真正的痛点是"可观察性"。最终砍掉多 dispatcher 调度架构,保留会话隔离渲染地基,工作量降至 35%,回归风险降一个量级。

核心问题: 当一个技术方案在评审后已经"技术上完全成立",你还应该问什么?答案是:收益的物理上限在哪里、复杂度税由谁支付、以及——用户真的高频需要它吗?

关键成果

  • 一套可复用的需求拆解方法:把"我想要 X 功能"拆为原子需求 N1/N2,分别评估现状满足度
  • "收益上限由瓶颈资源决定"分析框架:并发架构的收益被 LLM 后端焊死
  • "永久复杂度税"概念:一次性实施成本可以付清,架构复杂度是付不清的按揭
  • 分阶段决策门模式:先做无悔的地基,用真实运行数据决定是否继续

适合读者:技术负责人、独立开发者、任何需要在"做与不做"之间做决策的工程师

阅读时长:约 15 分钟

关键词第一性原理需求拆解复杂度税方案评审并发架构决策门


一、需求的诞生:一个"理所当然"的想法

WeClaw 的桌面端有一套指令队列机制:用户发出的每条指令进入 SQLite 持久化队列,由一个全局串行调度器(SerialQueueDispatcher)逐条执行。这套机制是 v7.0.0 引入的,解决了"任务执行中新指令会丢"的问题——现在指令可以排队,永不丢失。

但很快出现了新的抱怨(来自我自己):

论文生成任务要跑十几分钟。这期间我点「新会话」问一个简单问题——"帮我查个天气"——它排在论文任务后面,十几分钟后才回答我。

于是需求自然而然地浮现:多会话并发执行。当前会话跑长任务时,新会话的指令立即执行;点会话列表切回去,聊天区实时显示那个会话的进行中内容。

这个需求听起来无懈可击。ChatGPT 网页版不就是这样吗?每个对话独立,互不阻塞。

二、方案设计:三代理并行研究 + 三视角评审

2.1 UltraPlan:先摸清家底

我们没有直接开写,而是走了完整的规划流程。三个研究代理并行产出三套候选方案(简洁可维护 / 性能可扩展 / 最小改动),再由主流程亲自读代码核实关键论断。摸清的家底包括:

  • agent.chat_stream(target_session_id)会话级锁 _session_locks——跨会话天然可并行,会话内互斥
  • 队列的 claim_next_itemBEGIN IMMEDIATE 事务 + 条件 UPDATE——多个调度器并发领取不会重复
  • EventBus 的工具调用/思考事件已经携带 session_id——会话级过滤有现成字段

综合出的方案架构相当干净:

每个会话一个独立 dispatcher(scope 分片为 desktop:{session_id})
    ├── DispatcherManager 统一管理(并发上限 3,=1 时回退旧行为)
    ├── GuiAgent 全部核心信号追加 session_id 首参
    ├── UI 按"当前显示会话"过滤渲染
    └── 后台会话内容写入 LiveSessionBuffer,切换时重放续流

2.2 三视角评审:5 个 Critical

方案成文后,我们派出三个独立评审代理,分别从完整性(需求覆盖)、正确性(技术论断验证)、影响面(下游契约回归)三个视角审查。合并结果:

严重级数量典型问题
Critical5buffer 按内容去重会丢消息;并发槽位补启动存在"永不启动"死区;scope 迁移不彻底会导致同会话双执行破坏串行语义;队列控制 API 仍假设单 dispatcher;版本回滚后新格式队列永久无人消费
Warning9删除执行中会话未处理、退出只关一个 dispatcher、无速率限制……

注意这个信号:一个经过三代理研究、亲自核实代码的方案,评审仍然发现 5 个 Critical。这不说明方案写得差——每个 Critical 都有清晰的修复路径,我们也确实完成了修订——它说明的是:这个问题域的固有复杂度就是这么高。并发 + 持久化迁移 + UI 状态机的三重叠加,每个角落都藏着时序陷阱。

修订后的方案 v3 有 200 多行,包含迁移 SQL、断言降级、回滚脚本、双触发点补启动、12 类测试。技术上,它成立了。

三、关键转折:实施前的第一性原理拷问

方案技术成立 ≠ 应该实施。在按下开工按钮前,我们做了最后一轮评估,这次不问"怎么做",只问三个第一性问题。

3.1 问题一:剥掉方案外壳,原始痛点到底是什么?

"多会话并发执行"是一个解决方案,不是需求。把它拆回原子层面:

  • N1 不阻塞:长任务执行中,我想立刻发新指令,不想等
  • N2 可观察:切回后台任务的会话,能看到实时进展

然后逐个对照现状:

原子需求现状真实缺口
N1队列已支持"边执行边接收",指令排队不丢只是第二条指令的等待延迟
N2完全缺失——切换会话只见陈旧的持久化内容,执行中的流式输出、工具调用状态全部不可见整个能力

这一拆立刻暴露了不对称性:N1 已被满足了一半,N2 是零。而"多会话并发"方案把 80% 的复杂度花在了 N1 的那一半上(多 dispatcher、scope 迁移、并发上限、补启动),N2 需要的其实只是信号带上 session_id + 一个实时缓冲。

并发是满足 N1 的一种手段,且是最重的一种。

3.2 问题二:收益的物理上限在哪里?

这是最容易被忽略的一问。并发架构做得再精妙,收益上限被瓶颈资源焊死——对 AI 助手来说,瓶颈是 LLM 推理后端:

后端形态并发的真实收益
云 API✅ 真并行;代价是限流风险 + 费用随并发线性上升
本地 llama-server(单卡)⚠️ 两条流在服务端仍是分时/排队;开 -np 2 意味着 KV cache 内存翻倍;吞吐几乎不变,甚至双双变慢
工具 I/O 段(下载/爬取)✅ 真并行,但这部分本来就不长

换句话说:如果哪天从云模型切回本地模型为主(本地化恰恰是 WeClaw 的长期方向之一),这套并发架构的收益立即归零——而它的复杂度成本不会退回。

一个架构的收益会随外部条件蒸发,成本却是刚性的。这种不对称本身就是危险信号。

3.3 问题三:复杂度税由谁支付、付多久?

实施成本好算:12 步改造、约 10 个核心文件、4–6 人日。这是一次性成本,付清即止。

真正贵的是永久复杂度税

  • 此后每一个触碰聊天渲染、队列、停止按钮、TTS、工具确认弹窗的新功能,都必须先回答"多会话并发时怎么办"
  • 评审发现的那些问题就是首期税单:后台会话的确认弹窗弹给谁?删除一个正在执行的会话怎么办?停止按钮是停当前还是停所有?
  • 并发 bug 的调试成本是串行的数倍——日志交织、时序依赖、难以复现

而 WeClaw 是一个高速迭代的项目(v7.0 → v8.1 只用了一个月,期间还塞进了 OA 系统融合)。每个新功能都要过一遍"多会话拷问",这个税会在每次迭代中反复征收。

3.4 灵魂拷问:所以,高频吗?

三个问题问完,决策收敛到一个事实判断:"长任务执行中、第二条指令等不起"这个场景,到底多高频?

诚实的回答:论文生成、批量文献下载这类超长任务,一周也就几次。而为这个低频场景,要永久支付高额复杂度税。

答案不言自明。

四、裁剪:从方案 B 到方案 A

最终决策用一张对比矩阵呈现(这也是我们做技术决策的固定格式——多方案、多维度、明确推荐):

需求满足工作量回归风险复杂度税可回退性
方案0 维持现状N1 半、N2 无0
方案A 只做可观察性N1 半、N2 全~35%git revert 即可
方案B 完整并发N1+N2 全100%中高高且永久中(配置回退)

方案A 的内容

  1. 信号携带 session_id:GuiAgent 全部核心信号(message_/reasoning_/tool_call_*)首参加 session_id
  2. 显示会话过滤 + LiveSessionBuffer:信号归属当前显示会话 → 渲染;否则 → 写缓冲。切回时"持久化重放 + 缓冲续流",思考态、工具日志一并恢复
  3. 两个存量 bug 修复(评审的意外收获):
    • _enqueue_and_refresh 漏传 session_id——所有消息落同一个队列,归属和审计一直是错的
    • _workflow_item_executor 用临时 connect/disconnect 捕获执行结果——存在信号串扰竞态,改为 chat() 直接返回 (content, error)
  4. /new_session 语义修正:不再粗暴取消旧会话的执行——旧任务跑完,新指令排队

执行层完全不动:还是那一个 SerialQueueDispatcher,还是全局 FIFO。没有迁移、没有并发配置、没有新调度组件。

4.1 方案A 不是妥协,是"无悔选项"

这里有个精妙之处:方案A 恰好是方案B 的正确性地基。信号 session_id、LiveSessionBuffer、显示会话过滤——如果未来云模型长任务真的变高频、串行等待真的成为实际痛点,重启并发只需补上调度层那一小块,方案A 的全部工作直接复用,零返工

我们把重启条件也写进了文档,作为未来的决策门:

① 长任务期间"第二条指令等不起"的实际发生频率(方案A 上线后排队是可见的,会有体感数据);② 长任务是否以云模型为主;③ 可否接受并发 API 费用与限流风险。

被废弃的方案B 文档原样保留,头部加废弃说明和重启指引。思考痕迹本身就是资产——半年后如果重启,不需要重新踩一遍 5 个 Critical 的坑。

五、方法论沉淀

这次决策闭环可以压缩成五条可复用的原则:

1. 需求要拆到原子层面再评估。 "我想要多会话并发"是方案,不是需求。拆成 N1/N2 后发现:一个已被半满足,一个完全缺失,而原方案把复杂度花错了地方。

2. 收益上限由瓶颈资源决定,不由架构决定。 在动手前先问:这个架构的收益会不会被某个外部资源焊死?会不会随条件变化蒸发?本地 LLM 后端让"并发"的收益近乎虚幻。

3. 区分一次性成本与永久税。 实施人日可以咬牙付清;架构复杂度是按揭,每次迭代都要还——项目迭代越快,税率越高。评审发现的 Critical 数量是问题域固有复杂度的测量仪

4. 评审的价值不只是修 bug,更是复杂度探测。 三视角评审发现的 5 个 Critical 全部可修,但"一个精心设计的方案仍有 5 个 Critical"这个元信息,比任何一个具体问题都更有决策价值。

5. 优先选择"无悔选项"。 如果全量方案中存在一个子集:独立有价值、风险低、且是全量方案的必要地基——先做它,把剩余决策推迟到有真实数据的时刻。这不是拖延,是把决策权交给证据。

六、总结

一个需求从"理所当然"到"自我否决",走过了:三代理方案设计 → 三视角评审(5 Critical + 9 Warning)→ 两轮修订 → 技术上完全成立 → 第一性原理三问 → 砍掉 65%

最终留下的 35%(会话可观察性 + 两个存量 bug 修复)是确定性净收益:无论未来是否重启并发,这些工作都不白做。而砍掉的 65%(多 dispatcher 调度架构)连同全部思考痕迹被封存在废弃文档里,等待——或永远等不到——它的重启条件。

写代码之前最重要的工程能力,是判断哪些代码不该写。


下期预告:会话可观察性改造(方案A)的实施记录——信号签名改造如何做到零遗漏、LiveSessionBuffer 的续流重放如何处理持久化时序竞态。

系列文章

  • WeClaw_69|总结与展望:Harness工程的方法论与被验证的方向
  • WeClaw_68|Loop_Detection:检测和中断Agent的死亡循环
  • WeClaw_67|Pre-completion_Checklist:AI的交接前自检清单