
简介这是一份面向软件工程学习者、系统分析与设计人员及 UML 初学者的序列图学习资料围绕问答系统这一典型场景系统讲解时序图的核心概念与建模方法。内容涵盖角色、对象、生命线、激活期与消息五大元素并深入说明对象三种命名方式、生命线绘制规则、激活期与 C 语言花括号的类比、消息的条件表达式与分支语义以及对象创建与删除的 X 标识等细节帮助读者掌握用序列图描述对象间消息交互与动态协作的能力。资源包共 1 个 docx 文档约 31KB结构紧凑适合作为课堂笔记或自学提纲使用。目前已有 386 人学习浏览说明其在 UML 入门与复习场景中具有一定参考价值。通过阅读读者可理解时序图纵轴时间、横轴对象的坐标体系学会从上到下分析消息交换并借助同步、异步消息及激活期控制焦点等知识提升系统行为设计的可读性与可维护性。1. 从一次问答系统的联调事故说起为什么需要 UML 序列图去年帮一个团队排查智能问答系统的线上问题现象很怪用户提问后前端一直转圈后端日志显示检索服务已经返回但答案就是拼不出来。三个人对着代码看了半天最后画了一张 UML 序列图十分钟定位到问题——重排模块在等待一个永远不会到达的回调。这就是序列图的价值它把「谁在什么时候给谁发了什么消息、谁在等谁」这件事画在了一张纸上。UML 序列图Sequence Diagram也叫时序图、循序图是 UML 行为图的一种专门描述对象之间按时间顺序发送消息的动态协作过程。它有两个坐标轴纵轴是时间从上往下流逝横轴是参与交互的对象。问答系统这类多组件协作的场景——用户、前端、网关、检索、大模型、缓存——天然适合用序列图来建模因为它的核心矛盾就是「消息顺序」和「同步/异步边界」。这篇内容面向需要做系统设计、写设计文档、准备软考中级 UML 建模题的读者从元素语义讲到问答系统的完整建模再落到工具实操和常见坑。2. 序列图五大元素在问答链路里的对应关系2.1 角色、对象与生命线谁参与了一次问答角色Actor是系统外部与系统交互的实体可以是人、其他系统或子系统。在问答系统里最典型的角色就是「提问用户」如果系统对接了企业微信或客服工单那「工单系统」也是一个角色。角色画在序列图最左侧用小人图标表示。对象Object位于图顶部代表交互中扮演角色的实例。命名有三种方式对象名:类名完整、:类名匿名对象只显示类名、对象名只显示对象名。我一般建议在架构设计阶段用完整命名比如retriever:VectorRetriever评审时一眼能看出这是哪个模块的哪个实现到了给产品经理看的图里可以退化成只写对象名。生命线Lifeline是对象下方那条垂直虚线代表对象在这段时间内的存在。问答系统里有个容易忽略的点如果检索服务是每次请求临时创建的那它的生命线应该从「创建」消息之后才开始而不是从图顶部一直画到底。很多新手画的图里所有对象生命线等长这在语义上是错的。2.2 激活期同步调用和异步回调的分界线激活期Activation是生命线上的窄矩形代表对象正在执行某项操作。原文里有个很精准的类比它可以理解成 C 语言里一对花括号{}包住的内容——进入花括号激活开始出花括号激活结束。在问答系统里激活期直接对应「同步还是异步」这个关键设计决策。同步调用时调用方的激活期会一直延伸到被调方返回异步调用时调用方发完消息激活期就结束被调方自己开一段激活期返回时再画一条虚线箭头回来。下面这张表是我在评审时常用的对照交互类型箭头样式问答系统典型场景激活期表现同步消息实线实心箭头网关调用检索服务调用方激活期覆盖被调方异步消息实线开放箭头提交大模型生成任务调用方激活期立即结束返回消息虚线开放箭头检索结果回传被调方激活期结束自调用折线实心箭头缓存未命中转查库生命线上叠加小矩形提示判断一张序列图画得对不对先看激活期和箭头类型是否自洽。异步消息配了覆盖式激活期基本可以判定画错了。2.3 消息同步、异步、条件分支与顺序号消息Message是序列图的灵魂用于对实体间通信内容建模。消息可以是信号、操作调用也可以是类似 RPC、RMI 这样的远程调用。在问答系统里一条消息通常写成方法名(参数): 返回值的形式比如search(query, topK5): ListChunk。消息可以带条件表达式表示分支各分支互斥。比如缓存查询可以写成[cacheHit] return answer和[!cacheHit] retrieve(query)。消息也可以带顺序号但序列图本身已经用垂直位置显式表达了顺序所以顺序号很少用——只有在嵌套调用层级很深、需要跨图引用时才加。对象可以被创建和销毁创建用指向对象框的create消息销毁在生命线末端画一个X。问答系统里会话对象就是典型——用户开始对话时创建Session超时或主动退出时销毁。3. 用 PlantUML 把问答系统主流程画成可执行序列图3.1 环境准备与最小可运行示例手绘序列图适合讨论但设计文档里的图必须可版本管理、可 diff。我一般用 PlantUML文本描述、Git 可追踪、CI 里能自动出图。本地跑需要 Java 环境和 plantuml.jar或者直接用 VS Code 的 PlantUML 插件。下面是一个问答系统主流程的最小示例startuml actor 提问用户 as User participant Web前端 as FE participant API网关 as GW participant 检索服务 as RET participant 大模型服务 as LLM database 向量库 as VDB User - FE : 输入问题 FE - GW : POST /qa/ask activate GW GW - RET : search(query, topK5) activate RET RET - VDB : 向量相似度查询 activate VDB VDB -- RET : TopK 文档块 deactivate VDB RET -- GW : 召回结果 deactivate RET GW - LLM : generate(query, context) activate LLM LLM -- GW : 生成答案 deactivate LLM GW -- FE : 答案 引用 deactivate GW FE -- User : 渲染回答 enduml这段描述里activate和deactivate显式控制激活期-是同步消息--是返回消息。逻辑上它表达的是网关同步等待检索检索同步查向量库拿到结果后再同步调大模型。参数说明上topK5是召回数量context是拼装好的上下文。把这段贴进 PlantUML 渲染器就能出图改一行文本就能重新出图比拖拽工具高效得多。3.2 加入缓存分支和异步生成真实系统不会这么理想。缓存命中要短路大模型生成通常要流式返回。下面这版加了条件分支和异步消息startuml actor User participant API网关 as GW participant 缓存 as CACHE participant 检索服务 as RET participant 大模型服务 as LLM User - GW : ask(query) activate GW GW - CACHE : get(queryHash) activate CACHE CACHE -- GW : cachedAnswer deactivate CACHE alt 缓存命中 GW -- User : 直接返回 else 缓存未命中 GW - RET : search(query) activate RET RET -- GW : chunks deactivate RET GW - LLM : generateAsync(query, chunks) activate LLM LLM -- GW : streamToken LLM -- GW : streamToken LLM -- GW : [DONE] deactivate LLM GW -- User : 流式答案 end deactivate GW endumlalt/else/end是互斥分支对应原文说的「某一时刻仅可发送分支中的一个消息」。-和--是异步消息和异步返回激活期不再覆盖调用方。这里有个细节流式返回画了多条streamToken实际建模时如果 token 数量不确定可以只画首尾两条加省略号避免图被撑爆。3.3 消息顺序与生命线对齐的检查清单画完图别急着交付按这几条过一遍角色是否都在最左侧、对象命名是否统一、每条消息的箭头类型和激活期是否匹配、创建/销毁是否有对应标记、分支条件是否互斥且完整。我见过最常见的错误是把返回消息画成实心箭头或者异步调用却让调用方激活期一直挂着——这两种在评审时都会被一眼挑出来。4. 问答系统序列图建模的典型坑与排错方法4.1 把「等待」画成了「执行」回到开头那个联调事故。团队最初的图里重排模块的激活期一直延伸到答案返回看起来一切正常。但实际代码里重排是异步回调回调注册后主流程就继续走了回调永远不触发。图错在把异步画成了同步掩盖了真实的控制流。修正方法很简单凡是CompletableFuture、Promise、消息队列投递这类操作一律用异步箭头调用方激活期在发送后立即结束。4.2 对象粒度过粗或过细有人把整个后端画成一个Backend对象所有消息都指向它图是简洁了但完全失去了建模意义。也有人把每个类都画成对象一张图三十条生命线没人看得下去。我的经验是按「部署单元 关键职责」切分网关、检索、大模型、缓存、存储各一个对象内部类不展开。如果某个对象内部逻辑复杂单独再画一张细化图。4.3 用序列图反推接口契约序列图不只是文档还能当接口设计的校验工具。画完图后每条指向对象的同步消息都应该能在代码里找到对应的方法签名每条返回消息的类型都应该和实际返回类型一致。我习惯在评审时把图投出来逐条消息对照接口定义对不上的当场改。这一步能拦掉大量「设计文档和代码两张皮」的问题。注意序列图描述的是动态协作不要往里塞静态结构信息。类之间的关系该用类图别在序列图里画继承和聚合。5. 从序列图到可维护的问答系统设计文档序列图真正的价值在于它能让设计文档活起来。我现在的做法是把 PlantUML 源文件放进代码仓库的docs/sequence/目录和接口代码同一个 PR 提交改接口必须改图CI 里加一步渲染检查图渲染失败就卡住合并。这样序列图不会像 Word 里的图片那样半年就过期。再进一步可以把序列图和契约测试挂钩。每条同步消息对应一个契约测试用例测试失败时输出对应的序列图片段排查问题时直接看图定位。对于智能问答系统这种链路长、组件多的场景这套做法比单纯写接口文档有效得多。软考中级 UML 建模题里常考的元素语义和消息类型判断本质上也是这套东西——把图当代码一样对待语义自然就清楚了。本文还有配套的精品资源点击获取