目录 · 第 11 章4 卷 12 章
第 11 章 · 卷四 把技术变成面试表达
项目讲解与架构设计手册
1 分钟、3 分钟、10 分钟三套讲法,以及架构图逐层讲稿。
项目是一个面向林业巡检、应急消防、园区安防的无人机实战平台。已有设备接入、航线规划、任务下发、遥测回传、告警处置能力。现在增加 Copilot 智能助手,技术栈为 Java 21、Spring Boot 3、Spring AI、Spring AI Alibaba、PostgreSQL、Redis、RocketMQ、Milvus、MinIO、Vue 3、Cesium 和 SSE。
本章把前十章涉及的业务、架构、模型接入、工具调用、RAG、Agent 工作流、数据可靠性、安全治理、评测与运维组织成一套面试讲解方法。接口、类名、表名及状态流转均为建议设计,具体以实际代码为准。
暂无,本文只做方案设计。没有实际运行、压测和线上数据支撑的内容,不作为已完成成果陈述。
1要解决的问题
面试官听项目介绍,不是为了听一遍技术名词,而是想判断三件事:你有没有理解业务问题,能不能把系统设计出来,能不能解释关键决策和失败时的处理方式。
这个项目最容易讲偏的地方,是从 Spring AI、Agent、RAG、MCP 等技术名词开始讲。面试官还没听懂业务,就已经被带进技术细节了。
正确的讲法是:先讲业务为什么需要 Copilot,再讲系统怎么把用户目标变成可执行任务,最后讲怎么保证执行安全、结果可信。
整个项目围绕一个具体场景展开:
用户在三维地图上圈选一片区域,说“今天把这块地的消防通道巡一遍”。
原有平台已经能规划航线、下发任务和接收遥测。问题是,用户仍然需要自己判断设备是否可用、空域是否允许飞行、航线怎么规划、异常怎么处置。多个业务操作分散在不同页面里,用户必须自己把它们串起来。
Copilot 要解决的不是“让用户可以聊天”,而是把分散的业务能力组织成一条受控的执行链路。
讲解时要把三个层面区分开:
- 业务问题: 用户需要自己跨多个模块完成巡检任务。
- 技术方案: 增加 Copilot,由模型理解目标,由业务工具查询和执行,由平台规则控制风险。
- 实现细节: 使用
FlightTaskService、RoutePlanningService、RocketMQ、PostgreSQL等具体组件完成实现。
这三个层面有先后关系。先解释为什么做,再解释怎么设计,最后才解释代码怎么写。
2在整个系统中的位置
Copilot 是现有无人机业务平台上方的智能编排层,不是重新开发一套飞控系统,也不是让大模型直接控制无人机。
可以把整个系统分成四个部分:
| 部分 | 职责 | 面试时要强调的边界 |
|---|---|---|
| 交互层 | Vue 3、Cesium、SSE,接收用户目标并展示进度 | 负责交互,不决定飞行是否合法 |
| 智能编排层 | 理解目标、调用模型、选择工具、组织步骤 | 负责协调,不取代业务规则 |
| 业务能力层 | 设备查询、空域检查、航线规划、任务管理、告警处置 | 业务操作必须经过服务端校验 |
| 数据与基础设施层 | PostgreSQL、Redis、RocketMQ、Milvus、MinIO | 保存状态、协调并发、传递事件、检索知识和存储文件 |
Copilot 与原有平台的关系,可以用一句话概括:
原有平台负责把业务能力做正确,Copilot 负责按照用户目标组织这些能力。
例如,模型可以判断用户想完成消防通道巡检,但不能凭语言判断某台无人机一定可用,也不能仅凭知识库中的一条规定认定当前空域允许飞行。
设备可用性要查询设备服务,空域限制要查询权威业务数据,航线要经过规划服务校验,任务下发要经过授权和确认。
面试官如果问“为什么不直接让大模型完成所有事情”,就回到这条边界:模型擅长理解意图和组织信息,确定性的业务规则与飞行控制必须由受控系统负责。
3总体设计
10 分钟讲稿的结构
十分钟不是把所有技术都介绍一遍,而是按面试官理解系统的顺序展开。建议分配如下。
| 时间 | 讲解内容 | 要回答的问题 |
|---|---|---|
| 0—1 分钟 | 项目背景与业务问题 | 为什么需要 Copilot? |
| 1—2 分钟 | 系统整体架构 | Copilot 在原有平台的什么位置? |
| 2—4 分钟 | 完整业务链路 | 一句话怎么变成真实巡检任务? |
| 4—6 分钟 | Agent、工具调用与 RAG | 模型如何理解、查询和组织业务能力? |
| 6—8 分钟 | 状态管理、可靠性与安全 | 超时、重复请求、异常告警怎么处理? |
| 8—9 分钟 | 关键技术决策 | 为什么选择这套架构,而不是其他方案? |
| 9—10 分钟 | 测试、评估与总结 | 怎么证明系统有效,如何发现问题? |
下面是整套系统的主链路。面试时先把这条链路讲清楚,再展开各层技术。
- 用户圈选区域并输入目标Vue 3 + Cesium 提交区域和自然语言目标
- 创建会话与巡检请求后端校验身份、租户、区域和请求参数
- 意图理解与任务拆解大模型生成结构化目标,不直接执行飞行
- 查询设备与空域业务工具读取实时设备状态和权威空域数据
- 航线规划与校验规划服务生成航线,业务规则检查可行性
- 生成任务草稿保存设备、航线、区域、风险和确认版本
- 用户确认校验授权、草稿版本、设备状态和执行前置条件
- 任务下发任务服务持久化状态并向飞行任务系统发送命令
- 遥测与视觉告警RocketMQ 传递事件,后端更新任务状态并分析异常
- 异常建议与人工处置Copilot 提供建议,受控业务接口执行授权操作
- 任务结束与报告汇总任务、遥测、告警和媒体证据生成报告
这张图有三个重要的设计点。
第一,模型不直接生成飞控指令。它只负责理解用户目标、选择允许使用的工具和整理结果。
第二,生成任务草稿与真正下发任务是两个不同阶段。用户确认之前,不允许产生实际起飞效果。
第三,任务执行与对话请求不是同一个生命周期。HTTP 或 SSE 连接结束,不代表无人机任务结束;模型调用失败,也不代表已经下发的飞行任务自动取消。
架构图怎么逐层讲
每层固定讲三句话:这一层负责什么、为什么需要它、它不能越过什么边界。
| 层级 | 职责 | 为什么需要 | 边界 |
|---|---|---|---|
| 前端交互层 | 地图圈选、输入目标、确认草稿、展示状态 | 用户需要在地图上下文中表达任务 | 不负责权限判定和飞行决策 |
| Copilot 编排层 | 意图理解、上下文组织、工具调度 | 把分散的业务操作串成完整流程 | 不能绕过服务端校验 |
| 领域服务层 | 设备、空域、航线、任务、告警 | 保证业务规则统一且可复用 | 不依赖模型输出作为唯一依据 |
| 异步事件层 | 遥测、告警、任务状态事件 | 处理持续发生、不能阻塞对话的事件 | 消息到达不等于业务处理成功 |
| 数据与知识层 | 事务数据、缓存、向量检索、媒体文件 | 支持状态管理、知识检索和证据追溯 | 向量相似度不能替代权威数据校验 |
不要把架构图讲成组件清单。例如,说完“这里用了 RocketMQ”,还要补充为什么需要它:无人机执行期间会持续产生遥测和告警,这些事件不应该依赖用户一直保持 SSE 连接才能处理。
再补一个边界:消息可能重复投递,消费者必须支持幂等;消息发送成功也不能直接等同于无人机已经执行任务。
4完整执行链路
现场讲解时,最好选一条业务链路,从输入一直讲到结果。不要一会儿讲 RAG,一会儿讲数据库,最后又回到任务下发。
建议按下面的顺序讲。
- 画出业务边界用户、Copilot、既有无人机平台、外部设备
- 说明用户输入地图区域、巡检目标、时间要求、任务约束
- 解释意图理解模型输出结构化目标和缺失信息
- 解释工具调用查询设备、检查空域、规划航线、生成草稿
- 解释人工确认用户确认明确版本,服务端再次检查执行条件
- 解释任务执行持久化任务、可靠下发、接收遥测和告警
- 解释异常路径超时、设备离线、空域变化、重复消息、任务失败
- 解释结果交付汇总执行记录、告警和证据,生成报告
一条完整链路怎么讲
用户圈选区域后,前端提交 regionGeoJson、goal、scheduledAt 和 conversationId,调用 POST /api/copilot/requests。
后端创建请求记录,校验用户权限和区域参数。Copilot 根据用户目标生成结构化任务意图,例如任务类型为消防通道巡检、目标区域为用户圈选区域、执行时间为当天。
如果缺少必要信息,系统先追问,不应该自行猜测。
意图明确后,编排器调用业务工具:
queryAvailableDevices查询候选设备及其最新状态。checkAirspace查询目标时间和区域对应的空域限制。planRoute请求航线规划服务。validateRoute检查航线、设备能力及业务约束。createTaskDraft保存待确认的任务草稿。
草稿包含设备、区域、航线版本、计划时间、风险提示和数据有效时间。用户确认时,服务端重新检查权限、草稿版本、设备状态和空域约束。检查通过后,任务才进入下发流程。
任务执行期间,设备遥测与视觉告警通过既有接入链路进入平台。相关事件经 RocketMQ 传递给任务状态处理、告警分析和报告服务。Copilot 可以解释告警并给出建议,但实际处置必须经过对应业务接口和授权检查。
任务结束后,系统根据任务记录、执行结果、告警和媒体证据生成报告。报告中的事实应来自业务记录,模型只适合辅助组织文字,不应该自行补全不存在的飞行数据。
三个关键技术决策
面试时不要只说“我们选择了某某技术”。要说明备选方案、选择理由,以及放弃另一方案的代价。
| 决策 | 备选方案 | 选择理由与放弃理由 |
|---|---|---|
| Agent 与固定工作流如何分工 | 全固定工作流、全自主 Agent、受控混合编排 | 目标设计采用受控混合方式。固定业务步骤使用明确状态流转,模型负责意图理解、工具选择和非固定问题处理。全固定工作流应对自然语言变化不够灵活;完全自主 Agent 则更难控制执行路径和风险 |
| 业务执行如何保证可靠 | 同步串行调用、消息队列、分布式事务覆盖全链路 | 采用数据库事务、任务状态机、可靠消息与幂等处理组合。长时间飞行不能依赖同步请求维持;跨设备系统的全链路分布式事务通常难以实现,也不适合覆盖持续运行的飞行任务 |
| 知识如何检索 | 直接让模型回答、关键词检索、向量检索、混合检索 | 对手册、操作规程等非结构化知识使用 RAG,必要时结合关键词检索。纯模型回答缺少当前业务依据;纯关键词检索难以覆盖语义表达;纯向量检索可能错过精确编号和专有名词 |
还有一个需要主动说清楚的取舍:RAG 不负责实时业务事实,Agent 不负责最终安全判定。
设备是否在线、任务当前状态、空域是否开放,都应从有权限的业务接口或权威数据源读取。RAG 用于查找操作规程、设备手册和处置知识。
高频追问
追问一:为什么用 Agent,不用普通工作流?
不能简单回答“Agent 更智能”。固定工作流更适合确定性强的流程,Agent 更适合用户表达不固定、需要根据查询结果决定下一步的部分。
本项目更合理的设计不是二选一,而是让 Agent 负责理解目标和选择允许的工具,让工作流与业务状态机负责关键步骤、人工确认和执行顺序。飞行任务不能因为模型临时改变想法,就跳过空域检查或人工确认。
追问二:为什么不用现成的 Agent 平台?
要区分“使用框架”和“把整个业务交给现成平台”。
Spring AI 与 Spring AI Alibaba 可以帮助接入模型、组织工具调用和构建检索能力。但无人机任务仍然需要自己的领域模型、权限体系、状态机、执行幂等、审计与异常处理。
现成平台可以降低通用能力的开发成本,却不能自动替代项目特有的飞行规则。如果平台能满足部署、权限、扩展和审计要求,也可以复用;是否自建,应比较长期维护成本与业务控制能力,而不是为了自研而自研。
追问三:做了 RAG,为什么还会答错?
因为 RAG 只改善模型获取资料的方式,不保证检索到的资料一定正确,也不保证模型一定正确理解。
错误可能发生在文档解析、切分、召回、重排、上下文拼接和生成阶段。资料还可能过期,或者不同版本的规程存在冲突。
改进方法包括文档版本管理、权限过滤、混合检索、重排、引用证据、无答案时拒答和检索评测。涉及实时设备状态和飞行安全的事实,仍要通过业务接口校验。
追问四:怎么防止模型乱调工具?
工具采用白名单注册,每个工具声明参数结构、权限要求、风险等级和允许的执行阶段。服务端对参数进行校验,对资源进行权限检查,对高风险操作要求显式确认。
例如,模型可以请求创建任务草稿,但不能调用一个绕过确认的任意起飞接口。即使模型生成了合法 JSON,也不代表业务操作一定合法。
追问五:上线后怎么评估?
不能只看回答是否流畅。应分层评估:
- 意图层:任务类型识别、必要参数提取、追问是否合理。
- 检索层:召回是否覆盖正确规程、引用是否支持结论。
- 工具层:工具选择正确率、参数校验失败率、调用失败率。
- 业务层:草稿生成成功率、任务执行成功率、重复执行和状态不一致情况。
- 安全层:越权调用、未经确认的执行、风险规则绕过情况。
- 运行层:端到端延迟、模型成本、消息积压、错误恢复时间。
具体阈值应通过测试集、试运行和业务风险评估确定。当前没有实测数据,不能声称已经达到某个准确率或成功率。
5技术选型与原理
这一节的目标不是证明所选技术最好,而是让面试官听懂每种技术解决什么问题,以及为什么没有选择其他方案。
| 技术决策 | 采用方案 | 备选方案 | 选择与放弃理由 |
|---|---|---|---|
| 后端服务 | Java 21 + Spring Boot 3 | Python Web 框架、传统 Java Web | 与既有 Java 业务平台整合更直接;若团队已有成熟 Python AI 服务,也可拆分部署 |
| 模型接入 | Spring AI + Spring AI Alibaba | 直接调用模型厂商 SDK、自建统一 SDK | 通过抽象接口降低模型接入与切换成本;直接 SDK 更简单,但多模型适配和统一治理需要自行实现 |
| 业务编排 | 受控 Agent + 工作流或状态机 | 全固定工作流、完全自主 Agent | 兼顾自然语言灵活性与关键步骤的确定性 |
| 结构化数据 | PostgreSQL | MySQL、MongoDB | 适合事务、关系约束和 JSONB 扩展;团队若已有成熟 MySQL 体系,也不必为了新组件而迁移 |
| 缓存与并发控制 | Redis | JVM 本地缓存、仅依赖数据库锁 | 支持共享缓存、短期状态和分布式协调;关键业务状态不能只保存在 Redis |
| 异步事件 | RocketMQ | 同步调用、RabbitMQ、Kafka | 适合解耦任务事件和异步处理;具体选择还需结合团队运维经验、顺序要求和消息语义 |
| 知识检索 | Milvus | PostgreSQL 全文检索、其他向量数据库 | 面向向量召回;若知识规模较小,也可先用 PostgreSQL 检索减少系统复杂度 |
| 文件证据 | MinIO | 本地磁盘、云对象存储 | 统一存储图片、视频和报告附件;生产部署需额外考虑高可用、容量和备份 |
| 前端与进度 | Vue 3 + Cesium + SSE | 传统页面、WebSocket、轮询 | Cesium 支持三维地理交互,SSE 适合服务端向浏览器推送文本和状态;双向实时交互需求强时可评估 WebSocket |
需要补充三点原理。
第一,Spring AI 不是 Agent 的全部。 它可以承担模型调用、提示词组织、工具调用集成和检索相关能力。任务状态、业务授权、补偿逻辑和飞行安全仍然需要业务代码实现。
第二,消息队列不等于业务可靠。 RocketMQ 可以解耦生产者与消费者,但系统仍需处理重复消息、消费失败、顺序要求、积压和重放。数据库状态与消息投递之间也可能出现不一致,需要可靠发布策略和对账机制。
第三,向量数据库不等于知识正确。 Milvus 负责向量相似度检索,不负责判断文档是否过期、是否适用于当前设备型号,也不负责决定用户是否有权查看这份资料。
选型时始终回到业务约束:哪些操作必须同步确认,哪些事件可以异步处理,哪些事实必须来自权威数据,哪些步骤允许模型参与判断。
6关键数据结构与代码
面试官通常不要求你背出所有类名,但会关注你是否能把架构落到可实现的接口、数据结构和状态流转上。
6.1 三套讲稿的要点
1 分钟版本
定位: 在既有无人机平台上增加受控的 Copilot 智能编排层
业务卡点: 用户需要跨设备、空域、航线和任务模块手动组织巡检
我的设计:
- 意图层: 理解自然语言并提取结构化目标
- 编排层: 调用业务工具并生成任务草稿
- 保障层: 状态机、权限校验、人工确认、异步事件和审计
结果: 目标设计是把分散操作组织为可追踪的巡检闭环
事实边界: 暂无上线验证数据,不声称实际业务提升3 分钟版本
项目背景:
原平台已有设备接入、航线规划、任务下发和遥测告警能力。
新增 Copilot 的目标是让用户通过自然语言组织这些能力。
完整链路:
地图圈选与目标输入
-> 意图解析
-> 查询设备和空域
-> 航线规划与校验
-> 生成任务草稿
-> 用户确认
-> 任务下发
-> 遥测和告警处理
-> 报告生成
关键取舍:
不让模型直接控制飞行。
固定流程由业务状态机控制,模型负责理解和编排。
事务数据与知识检索分开处理。
通过幂等、审计和异常恢复降低执行风险。10 分钟版本
讲解顺序:
业务:
- 现有平台能力
- 用户跨模块操作的痛点
- Copilot 的目标与非目标
架构:
- 前端交互层
- 智能编排层
- 业务服务层
- 事件与数据层
AI链路:
- 意图识别与结构化输出
- 上下文与工具选择
- RAG 检索与证据引用
- 结果校验与追问
可靠性:
- 任务状态机
- 用户确认与权限控制
- 幂等、消息重试和对账
- 超时、取消与异常恢复
决策:
- Agent 与工作流的职责划分
- 模型接入与数据存储选型
- 检索质量与安全边界
验证:
- 离线评测
- 工具和业务集成测试
- 安全测试
- 运行指标与告警这三套讲稿不是三个不同的项目,而是同一套项目材料的三个深度。短版本突出业务价值和设计主线,长版本增加关键机制与取舍。
6.2 关键接口与状态流转
建议将任务草稿与执行任务分开建模。
草稿可以使用 copilot_task_draft 表保存,正式任务使用 flight_task 表保存。两者通过 draft_id 关联。这样可以避免把模型生成但未经确认的计划误认为已下发任务。
以下为目标设计的 Java 接口片段,展示职责边界,不代表已经实现或验证的代码。
public record CopilotRequest(
String conversationId,
String goal,
String regionGeoJson,
Instant scheduledAt
) {}
public record TaskDraft(
String draftId,
String deviceId,
String routeId,
long routeVersion,
String regionHash,
Instant scheduledAt,
List<String> warnings,
String status
) {}
public interface CopilotOrchestrator {
TaskDraft createDraft(
CopilotRequest request,
UserContext user
);
}
public interface AirspaceService {
AirspaceCheckResult check(
String regionGeoJson,
Instant scheduledAt
);
}
public interface RoutePlanningService {
RoutePlan plan(
String deviceId,
String regionGeoJson,
Instant scheduledAt
);
}
public interface FlightTaskService {
FlightTask confirmAndDispatch(
String draftId,
long expectedVersion,
String idempotencyKey,
UserContext user
);
}这里有几个面试时值得解释的点。
expectedVersion用于防止用户确认已经过期的草稿。idempotencyKey用于识别同一业务请求的重复提交,避免网络重试导致重复创建或下发任务。UserContext应由可信的认证与授权链路建立,不能直接相信模型传入的用户身份。regionHash可以帮助识别草稿对应的区域版本,防止用户修改区域后仍确认旧计划。warnings用来保存需要用户理解的风险和限制,不应只存在于对话文本里。
正式任务的状态可以设计为:
DRAFT → PENDING_CONFIRMATION → CONFIRMED → DISPATCHING → ACCEPTED → RUNNING → COMPLETED
异常分支包括 REJECTED、FAILED、CANCEL_REQUESTED、CANCELLED 和 UNKNOWN。其中,ACCEPTED 表示下游已接受任务,不必然表示无人机已经起飞;UNKNOWN 表示系统暂时无法确定执行结果,需要查询下游状态或进行对账。
不要把所有状态都塞进模型的对话上下文。权威状态应该持久化在业务数据库中。
6.3 建议的数据表
| 表名 | 核心字段 | 用途 |
|---|---|---|
copilot_request | request_id、conversation_id、user_id、goal、status | 记录一次 Copilot 请求 |
copilot_task_draft | draft_id、request_id、device_id、route_version、region_hash、version、status | 保存待确认计划 |
flight_task | task_id、draft_id、status、idempotency_key、external_task_id | 保存正式任务与下游关联 |
copilot_tool_call | call_id、request_id、tool_name、arguments_hash、result_status | 记录工具调用与审计信息 |
task_event | event_id、task_id、event_type、event_time、payload_ref | 记录任务状态事件 |
knowledge_document | document_id、version、source、status、object_key | 管理知识文档版本与来源 |
媒体文件放在 MinIO,数据库保存对象键、摘要和关联信息。向量索引放在 Milvus,但应保留能够追溯原始文档、版本和访问权限的标识。
对于任务下发,建议在数据库事务中更新任务状态并写入 Outbox 事件,再由独立发布器投递到 RocketMQ。消费者处理时记录事件 ID 或业务幂等键。对于下游是否已接收的未知结果,需要主动查询或对账,不能因为重试就直接再次下发。
7异常、安全与边界条件
面试官会通过异常场景判断你是否真正考虑过系统上线后的行为。
| 场景 | 处理方式 | 不能做的事 |
|---|---|---|
| 模型输出缺少区域或时间 | 追问用户,保留请求状态 | 自行猜测关键参数 |
| 设备查询超时 | 限次重试,返回明确的待处理或失败状态 | 把缓存中的旧状态当成实时状态 |
| 空域检查失败 | 阻止进入可确认状态,提示具体原因 | 让模型自行宣布可以起飞 |
| 航线规划失败 | 记录失败原因,允许受控修改后重试 | 自动绕过约束生成替代航线 |
| 用户重复确认 | 使用幂等键、版本校验和数据库约束 | 因为接口被调用两次就创建两条任务 |
| RocketMQ 重复投递 | 消费端幂等,记录事件处理结果 | 假设消息只会投递一次 |
| 下发超时但结果未知 | 标记待核实,查询下游任务状态 | 直接重复下发可能重复执行的命令 |
| 飞行中设备离线 | 进入异常处理流程,依据飞控和平台规则处置 | 让模型直接控制飞行器恢复连接 |
| RAG 检索不到依据 | 明确说明缺少资料,转人工确认 | 编造操作规程或告警依据 |
| 用户越权访问 | 在每个业务接口重新鉴权 | 只在前端隐藏按钮 |
还要说明三个容易被忽略的边界。
模型输出不是可信输入。 工具参数即使符合 JSON Schema,也必须经过领域校验。模型可能生成不存在的设备 ID、错误的时间范围或不合理的区域坐标。
人工确认不是永久授权。 用户确认的是一个具体版本的任务草稿。如果设备状态、空域条件或航线版本发生关键变化,服务端需要重新检查,必要时要求重新确认。
取消请求不等于任务已经停止。 已经进入下游系统的飞行任务,可能无法通过取消 HTTP 请求立即终止。系统需要记录取消请求、等待下游确认,并根据实际执行状态更新任务。
安全治理还要覆盖提示词注入、知识文档污染、越权工具调用、敏感数据泄漏和审计信息不完整。知识库内容只能作为参考资料,不能通过文档指令改变工具权限或安全规则。
8测试与验证
项目是否可用,不能只通过几次对话演示来判断。测试应从模型能力一直覆盖到真实业务状态变化。
| 测试层级 | 主要验证内容 | 示例 |
|---|---|---|
| 单元测试 | 意图解析结果、参数校验、状态机转换 | 缺少执行时间时是否拒绝生成可执行草稿 |
| 工具集成测试 | 工具入参、权限、返回值和错误映射 | 空域服务超时时是否阻止确认 |
| RAG 评测 | 召回、引用正确性、版本过滤和拒答 | 检索到旧版规程时是否排除 |
| Agent 评测 | 工具选择、调用顺序、无效参数和终止条件 | 设备不可用时是否继续错误地规划航线 |
| 业务集成测试 | 草稿、确认、下发和任务状态是否一致 | 重复确认是否产生重复任务 |
| 异步可靠性测试 | 消息重投、消费失败、积压和对账 | 同一告警重复到达时是否重复处置 |
| 安全测试 | 越权、提示词注入、未确认执行和数据隔离 | 模型要求调用未授权工具时是否被拦截 |
| 运行测试 | 延迟、超时、资源占用和故障恢复 | 模型服务不可用时,既有任务是否仍可正常运行 |
怎么评估 AI 链路
建议建立固定评测集,每条用例包含用户输入、预期结构化意图、允许调用的工具、关键约束、参考知识和预期终态。
评测时至少区分三种结果:
- 模型结果正确: 是否正确理解目标、提取参数并给出有依据的解释。
- 工具执行正确: 是否选择了正确工具,参数是否有效,是否处理了工具失败。
- 业务结果正确: 是否遵守权限、确认和状态规则,任务是否进入预期状态。
这三种结果不能互相替代。模型答对了,不代表任务执行成功;工具返回成功,也不代表最终业务状态正确。
运行阶段可以采集 request_id、trace_id、tool_call_id、模型名称、提示词版本、检索文档版本、任务 ID、延迟和错误类型。日志要避免直接记录不必要的敏感信息。
对于涉及飞行安全的功能,测试环境应使用模拟设备或经过授权的测试设备。未经安全评审,不应通过真实起飞来验证模型生成的未知指令。
当前没有实测结果,因此不能填写虚构的准确率、任务成功率、响应时间或成本下降比例。正式项目汇报时,应以评测报告、测试记录和运行监控中的真实数据为准。
9面试表达与追问
怎么区分业务问题、技术方案和实现细节
面试时可以用同一件事讲三个层次。
- 业务问题: 用户要巡检一片区域,却需要自己查询设备、判断空域、规划航线和下发任务。
- 技术方案: 用 Copilot 将用户目标转成结构化任务,通过业务工具执行查询和规划,通过人工确认和状态机约束任务下发。
- 实现细节:
CopilotOrchestrator组织工具调用,AirspaceService检查空域,RoutePlanningService生成航线,FlightTaskService负责确认和下发;PostgreSQL 保存业务状态,RocketMQ 传递异步事件。
不要按照开发时间顺序讲“我先写了接口,然后接入模型,再加了数据库”。这属于开发流水账。
要按照因果关系讲:“因为用户需要跨模块完成任务,所以增加编排层;因为模型输出不可信,所以保留业务校验;因为任务持续时间长,所以将任务生命周期与对话请求分开;因为消息可能重复,所以增加幂等和对账。”
现场画图的步骤
第一步:先画边界
画出用户、Copilot、既有无人机平台、设备与外部服务。标清楚哪些能力是原有平台提供的,哪些是本次新增的。
第二步:再画主链路
从用户输入开始,画到意图解析、工具调用、任务草稿、人工确认、任务下发、遥测告警和报告。只保留能解释业务闭环的核心组件。
第三步:补异常路径
增加模型超时、空域不允许、设备离线、消息重复、下发结果未知等分支。说明每种异常由哪个组件负责,以及如何恢复。
画图时不要一开始就把 PostgreSQL、Redis、Milvus、MinIO 等全部堆上去。先让面试官看懂业务流程,再把需要解释的技术组件放到对应层。
追问一:如果只能介绍一个技术难点,你会讲什么?
建议讲“如何把模型生成的任务计划变成安全、可追踪的业务执行”。
它能同时体现 AI 应用设计和传统后端工程能力:模型负责理解与编排,领域服务负责校验,人工确认负责关键授权,状态机负责任务生命周期,幂等与对账负责处理不确定结果。
比单独介绍向量数据库或提示词更能体现完整的系统设计能力。
追问二:怎么证明这不是简单套一个大模型?
看系统是否解决了模型之外的问题:结构化意图、工具权限、业务状态、人工确认、异步事件、执行幂等、RAG 证据和效果评测。
如果只有聊天框和模型接口,那只是模型接入。如果能将自然语言目标转化为受约束的业务操作,并且能追踪执行结果、处理失败和审计操作,才形成了完整的 AI 应用方案。
追问三:这个项目的结果怎么讲?
要区分目标、实现情况和验证结果。
如果只有架构设计,就说已经完成了哪些设计、接口定义、状态建模或原型工作,并明确哪些尚未实现。
如果已经开发完成,就用测试记录说明功能是否通过验证。
如果已经上线,再用真实运行数据说明任务成功率、工具调用失败率、人工介入比例、端到端耗时和异常恢复情况。
不要把“设计了可靠机制”说成“系统已经达到高可靠”,也不要把模型演示成功说成业务闭环已经验证。
整场项目讲解要守住一条主线:用户提出目标,Copilot 组织业务能力,平台控制执行风险,系统留下可以追溯的结果。 讲稿可以缩短,技术细节可以展开,但业务目标、系统边界和事实依据不能改变。