目录 · 第 01 章4 卷 12 章
第 01 章 · 卷一 先搞懂整个项目
项目全景与业务设计
平台已有的五块能力、一线真正的卡点、Copilot 的定位与不做什么。
项目是一个面向林业巡检、应急消防、园区安防的无人机实战平台。平台已有设备接入、航线规划、任务下发、遥测回传和告警处置能力。现在需要增加 Copilot 智能助手。
使用 Java 21、Spring Boot 3、Spring AI、Spring AI Alibaba、PostgreSQL、Redis、RocketMQ、Milvus、MinIO、Vue 3、Cesium 和 SSE,构建从自然语言任务描述到任务草稿、人工确认、飞行监控和报告生成的完整链路。
暂无,本文只做方案设计。文中的接口、类名、数据表和流程属于后续实现的设计建议,不代表已上线或已实测。
1要解决的问题
这个项目要解决的核心问题是:让用户用自然语言描述作业目标,由 Copilot 调用现有业务能力,生成可以审核和执行的无人机任务。
传统无人机平台并不缺功能。设备能接入,航线能规划,任务能下发,飞行数据能回传,异常能告警。问题在于,用户要完成一件实际工作,需要自己理解每个模块,再按照正确顺序操作。
例如,林业巡检人员提出一个需求:“今天把这片林区巡一遍,重点检查消防通道。”
这个需求很简单,但系统执行起来并不简单。用户需要确认区域,找到可用设备,检查设备状态,确认空域限制,规划航线,设置任务参数,检查任务内容,再提交执行。无人机起飞后,还要关注遥测数据和视觉告警。任务结束后,还要整理巡检结果。
这些操作分散在不同的业务模块中。熟悉系统的人员知道先做什么、后做什么,也知道出现异常时去哪里处理。新手却可能不知道应该从哪个页面开始,更难判断各个环节的结果是否满足执行条件。
因此,问题不是再增加一个聊天窗口,也不是重新开发一套无人机业务系统。
真正要做的是把已有能力组织起来,让用户从“自己操作多个模块”转变为“描述目标、审核方案、处理异常”。
Copilot 的价值就在这里:把人的业务意图转成系统能够理解、检查和执行的业务动作,同时保留必要的安全检查和人工决策。
2在整个系统中的位置
2.1 原有业务闭环
原有平台已经具备无人机作业所需的主要业务能力。每个模块解决不同的问题。
| 业务模块 | 解决的问题 | 典型输入与输出 |
|---|---|---|
| 设备管理 | 知道有哪些无人机、设备是否可用 | 设备列表、在线状态、电量、载荷能力 |
| 航线规划 | 确定无人机怎么飞 | 作业区域、航线参数、航点和航线方案 |
| 任务管理 | 把作业方案变成可执行任务 | 任务配置、任务状态、执行记录 |
| 遥测管理 | 知道无人机飞行过程中发生了什么 | 位置、高度、速度、电量、飞行状态 |
| 告警处置 | 发现异常并组织处理 | 告警事件、告警等级、处置记录 |
这些模块共同组成业务闭环:
设备提供作业能力,航线定义飞行路径,任务组织执行过程,遥测反映实时状态,告警处理异常。任务结束后,平台根据执行记录和采集结果形成作业报告。
Copilot 不需要重写这套闭环。它应该调用已有的业务接口,复用原来的设备、航线、任务和告警规则。
2.2 Copilot 与传统业务模块的关系
可以把整个系统分成三层。
- 交互层: 用户在 Vue 3 + Cesium 三维地图上圈选区域,通过对话描述任务目标。
- 智能编排层: Copilot 理解用户意图,拆解任务步骤,调用业务工具,检查返回结果,并生成任务草稿。
- 业务执行层: 原有业务模块负责设备查询、航线规划、任务管理、遥测处理和告警处置。
Copilot 是位于现有业务系统之上的编排层,不是另一个独立的无人机平台。
例如,用户说“巡检这片区域”,Copilot 可以决定需要先查设备,再检查空域约束,接着调用航线规划能力,生成任务草稿。但它不能凭语言模型的判断,直接认定某架无人机可以安全起飞。
这里有一个重要区别:
AI 负责理解目标和组织调用,业务系统负责执行确定的规则,用户负责确认关键操作。
如果原有航线服务已经提供规划接口,Copilot 就调用这个接口,而不是让大模型自行计算一条航线。模型可以提出参数,不能代替专业的航线规划算法。
如果任务系统已有状态机,Copilot 也应该遵守原有状态流转,而不是自己维护一套与业务系统不一致的执行状态。
这样设计既能复用已有系统,也能把 AI 的不确定性限制在合适的范围内。
3总体设计
本章的目标架构如下。图中展示的是业务调用关系,不代表所有模块必须部署为独立服务。
- 用户在三维地图圈选区域并描述作业目标
- 交互层Vue 3 + Cesium 传递区域和自然语言
- Copilot入口接收请求并创建本次编排会话
- 意图理解提取作业目标、区域、时间和约束
- 业务工具调用按顺序查询设备、检查空域、规划航线
- 结果校验检查返回结果是否完整且满足业务规则
- 任务草稿汇总设备、航线和执行参数供用户审核
- 人工确认用户检查方案并明确确认提交
- 任务执行复用原有任务服务下发任务
- 飞行监控接收遥测与视觉告警并更新任务状态
- 异常处置生成建议并调用受权限控制的处置能力
- 报告生成汇总执行记录、遥测和告警结果
整个流程可以分为三个阶段。
执行前:从目标到任务草稿。 Copilot 理解用户要求,查询必要信息,调用业务工具生成候选方案。业务系统返回的设备状态、空域检查结果和航线规划结果,是判断方案能否继续的依据。
执行中:从遥测到异常处理。 原有平台继续负责飞行任务和遥测处理。Copilot 根据事件提供状态解释和处置建议。需要执行具体操作时,必须检查权限和操作条件。
执行后:从执行记录到报告。 Copilot 汇总已有业务数据,形成便于阅读的作业报告。报告中的飞行轨迹、任务结果和告警信息必须来自实际记录,不能让模型补造数据。
系统边界与非目标
Copilot 的职责是业务编排,不是接管所有无人机能力。
- 不做飞控。 不直接控制电机、姿态、航向或底层飞行控制回路。
- 不做空域审批。 可以查询空域限制或已有审批结果,但不能自行授予飞行许可。
- 不替人拍板起飞。 可以生成任务草稿、展示检查结果,但不能把模型的判断当作起飞授权。
- 不替代原有业务模块。 设备状态以设备服务为准,任务状态以任务系统为准,告警记录以告警服务为准。
- 不保证所有自然语言请求都能执行。 信息缺失、条件冲突或权限不足时,应该追问、拒绝继续或转交人工处理。
这条边界直接决定了后续架构:大模型不能成为业务事实的唯一来源,也不能绕过任务系统直接触发高风险操作。
4完整执行链路
以“今天巡一遍这块区域的消防通道”为例,完整旅程如下。
步骤一:圈选区域,描述目标
用户在 Cesium 地图上圈选林区或园区范围,输入作业目标。前端把区域坐标、对话内容和会话标识提交给 Copilot。
AI 介入前:用户需要自己进入不同页面寻找功能。AI 介入后:用户从作业目标开始表达。
步骤二:补全任务信息,检查执行条件
Copilot 提取区域、作业内容和时间要求。如果关键参数缺失,就向用户追问。信息足够后,依次查询设备、空域约束和航线规划能力。
AI 介入前:用户手动查询并判断。AI 介入后:Copilot 按业务规则组织查询,但不伪造查询结果。
步骤三:生成任务草稿,等待确认
Copilot 汇总候选设备、航线、任务参数和检查结果,交给原有任务系统校验。用户查看方案,确认后才提交任务。
AI 介入前:用户自己填写和核对参数。AI 介入后:系统准备草稿,用户保留审核权。
步骤四:执行任务,处理异常
原有任务系统负责下发任务,平台持续接收遥测和视觉告警。Copilot 解释异常、关联相关记录并给出处置建议;涉及实际操作时,继续执行权限和安全检查。
AI 介入前:用户在监控页面查看状态,再切换告警页面处理。AI 介入后:可以通过统一入口了解情况,但底层监控和处置规则不变。
步骤五:生成巡检报告
Copilot 汇总任务执行结果、飞行记录和告警处置记录,形成报告草稿。缺少的数据明确标记,不能凭空补全。
AI 介入前:用户需要自己查记录、整理结论。AI 介入后:系统负责汇总和组织文字,事实仍由业务记录提供。
这条链路中,AI 不应该从头到尾自由发挥。每一步都要有明确输入、明确输出和失败处理方式。
例如,设备查询失败时,不能继续假设设备可用;空域检查没有返回有效结果时,不能把它解释为“空域安全”;航线规划失败时,不能凭空生成一条看似合理的航线。
同样,用户确认任务草稿不代表所有安全条件永久有效。真正提交任务时,业务系统还需要重新检查关键条件,避免设备状态或执行条件在确认后发生变化。
5技术选型与原理
本章只说明技术在系统中的职责。具体组件如何配置、调用和部署,需要在后续章节展开。
| 方案 | 优点 | 局限 | 本项目的选择 |
|---|---|---|---|
| 人工操作多个页面 | 规则清楚,风险容易控制 | 操作步骤多,依赖熟练人员 | 保留为兜底方式 |
| 固定工作流 | 执行顺序稳定,容易审计 | 临时需求和分支处理需要预先设计 | 用于关键业务流程和安全门禁 |
| 大模型直接生成全部操作 | 交互灵活,接入简单 | 容易遗漏约束,难以保证参数和动作正确 | 不作为执行架构 |
| 大模型 + 受控业务工具 | 能理解自然语言,复用现有能力 | 需要处理工具权限、结果校验和异常恢复 | 作为 Copilot 的目标设计 |
选择 Spring AI 与 Spring AI Alibaba,是为了在 Java 技术栈中接入模型能力、组织工具调用,并为后续的上下文管理和检索能力留出空间。具体采用哪些模型、工具调用方式和编排机制,应根据部署环境和实际验证结果确定。
其他组件承担各自明确的职责:
- Spring Boot 3、Java 21: 承载 Copilot 服务、业务接口和权限校验。
- PostgreSQL: 保存会话、任务草稿、操作记录等需要持久化的业务数据。
- Redis: 支持会话状态、短期缓存等场景,不能把缓存当作唯一业务记录。
- RocketMQ: 传递异步任务事件、遥测摘要或告警事件,具体事件范围按实际吞吐和可靠性要求确定。
- Milvus: 支持对业务手册、设备说明等非结构化知识进行向量检索,不代替实时设备查询。
- MinIO: 保存巡检图片、报告附件等对象文件。
- Vue 3 + Cesium: 提供对话入口、三维区域选择和任务方案展示。
- SSE: 向前端持续推送对话进度、工具执行状态和任务事件。SSE 本身不负责执行业务动作。
这里要区分两种数据来源。设备是否在线、电量是多少、任务当前处于什么状态,应该查询业务系统或其可信数据接口。设备手册怎么解释、某类告警通常有哪些排查方法,可以使用知识检索。不能因为知识库里有一条旧记录,就认定设备当前处于某种状态。
6关键数据结构与代码
本章先确定核心对象及其职责。以下为目标设计中的 Java 接口示例,不是已验证的完整实现。
6.1 核心对象
建议把一次 Copilot 请求与真正的无人机任务分开。
CopilotRequest:用户输入的目标、区域和会话信息。TaskDraft:候选设备、航线方案、任务参数和校验结果。Mission:原有任务系统中的正式任务。ToolResult:业务工具调用的结果、错误码和必要的来源信息。
TaskDraft 不等于 Mission。草稿允许修改;正式任务必须经过业务校验和授权提交。
public record CopilotRequest(
String conversationId,
String objective,
GeoArea area
) {}
public record GeoArea(
String coordinateSystem,
List<GeoPoint> points
) {}
public record GeoPoint(
double longitude,
double latitude
) {}
public record TaskDraft(
String draftId,
String objective,
String deviceId,
String routeId,
Map<String, Object> parameters,
List<String> validationErrors,
DraftStatus status
) {}
public enum DraftStatus {
CREATED,
VALIDATING,
READY_FOR_REVIEW,
CONFIRMED,
REJECTED,
EXPIRED
}正式实现还应校验坐标系、区域是否合法、参数是否符合业务约束。状态枚举只是草稿状态示例,正式任务状态应继续遵守原有任务系统的状态机。
6.2 编排接口
Copilot 不直接实现设备查询和航线计算,而是通过业务能力接口调用现有服务。
public interface DeviceServiceClient {
List<DeviceCandidate> findAvailableDevices(
GeoArea area,
Instant plannedStartTime
);
}
public interface AirspaceServiceClient {
AirspaceCheckResult check(
GeoArea area,
Instant plannedStartTime
);
}
public interface RouteServiceClient {
RoutePlan plan(
GeoArea area,
String deviceId,
Map<String, Object> parameters
);
}
public interface MissionServiceClient {
MissionDraftResult createDraft(TaskDraft draft);
Mission submitAfterConfirmation(
String draftId,
String operatorId
);
}Instant 表示明确的时间点,具体时区展示由业务规则决定。接口中的类型是建议定义,接入现有平台时应以真实服务契约为准。
编排服务可以按照以下逻辑工作:
public TaskDraft prepare(CopilotRequest request) {
validateRequest(request);
var devices = deviceClient.findAvailableDevices(
request.area(), resolveStartTime(request)
);
var airspace = airspaceClient.check(
request.area(), resolveStartTime(request)
);
ensurePreconditions(devices, airspace);
var device = selectCandidate(devices);
var route = routeClient.plan(
request.area(), device.id(), defaultParameters()
);
validateRoute(route, device, airspace);
return draftFactory.create(
request, device, route, airspace
);
}这段代码表达的是调用顺序,不是完整生产代码。ensurePreconditions 和 validateRoute 必须使用明确的业务规则,不能仅靠模型判断。
正式提交时,还需要检查当前用户权限、草稿归属、草稿是否过期、是否已经提交,以及关键设备和空域条件是否仍然满足。对于可能重复到达的提交请求,应设计幂等机制,避免重复创建或执行任务。
7异常、安全与边界条件
这个系统最需要防范的,不是模型回答得不够流畅,而是错误结果进入真实飞行流程。
设备不可用。 查询不到设备、设备离线或电量不满足任务要求时,不生成可直接提交的草稿。可以让用户调整时间或区域,但不能假设设备状态正常。
空域结果不明确。 查询失败、数据过期或检查结果存在冲突时,状态应标记为待确认或不可继续。没有查询结果不等于没有限制。
航线规划失败。 记录失败原因,允许调整参数后重试。不能让模型用自然语言描述替代真实航线数据。
模型输出异常。 参数缺失、字段类型错误或工具调用不符合约定时,先做结构校验。校验失败就停止当前步骤,不能直接传给任务服务。
重复提交和状态变化。 草稿应有明确的状态、有效期和版本信息。用户确认后,服务端仍需校验当前状态,防止旧草稿被重复提交。
权限和提示词注入。 用户在对话中要求“跳过空域检查”或“直接起飞”,不能改变系统的安全规则。模型也不能自行扩大用户权限。工具层必须独立执行鉴权。
飞行中异常。 告警的严重程度和处置条件由业务规则决定。模型可以解释告警并提出建议,但涉及返航、降落或其他飞行动作时,必须走已有的受控业务接口及其安全检查,不能绕过飞控和授权机制。
所有关键动作都应留下可追踪记录,包括操作者、请求标识、草稿版本、工具调用结果、确认时间和任务提交结果。模型生成的解释可以辅助审计,但不能替代真实操作记录。
8测试与验证
当前没有实测结果。本章可以先建立验证清单,后续在真实接口和测试环境中逐项执行。
| 验证场景 | 测试方法 | 预期结果 |
|---|---|---|
| 正常巡检 | 提交合法区域和完整目标 | 按顺序查询设备、检查空域、规划航线并生成草稿 |
| 信息缺失 | 不提供区域或必要参数 | 追问用户,不进入任务提交阶段 |
| 没有可用设备 | 模拟设备服务返回空列表 | 明确提示无法生成可执行方案 |
| 空域检查失败 | 模拟接口超时或结果过期 | 停止后续执行,不把失败解释为通过 |
| 航线规划失败 | 模拟规划服务返回错误 | 不生成可提交的有效草稿 |
| 未经确认提交 | 直接调用任务提交接口 | 服务端拒绝未授权或未确认的请求 |
| 重复提交 | 重放相同的提交请求 | 不产生重复任务或重复执行 |
| 模型输出错误 | 返回缺字段或非法参数 | 结构校验失败,停止后续调用 |
| 遥测与告警异常 | 模拟事件延迟、重复或乱序 | 状态更新遵循事件处理规则,并保留异常记录 |
| 报告数据缺失 | 缺少部分遥测或告警记录 | 明确标记数据缺失,不编造结果 |
测试不能只检查模型有没有给出正确答案,还要检查业务服务有没有被正确调用、失败时有没有停止、未经授权的动作有没有被拦截。
需要特别验证一个场景:模型已经生成任务草稿,但设备随后离线。此时即使用户点击确认,服务端也应该重新校验设备状态,而不是直接提交任务。
9面试表达与追问
问题一:为什么要在无人机平台上增加 Copilot?
参考回答:
原有平台已经有设备、航线、任务、遥测和告警能力,缺的不是业务功能,而是把这些功能串成一次完整作业的能力。
一线人员需要在多个页面之间切换,还要知道每一步应该调用哪个模块。熟练人员可以完成,新手的使用门槛比较高。
所以我设计 Copilot 作为目标到动作的编排层。用户描述作业目标后,它调用现有业务接口,生成任务草稿,再由用户确认。这样既复用了已有系统,也没有把关键业务规则交给大模型。
问题二:为什么不让大模型直接控制无人机?
参考回答:
因为自然语言理解和安全执行是两类问题。
大模型适合理解用户意图、组织工具调用和解释告警,但不能保证每次输出都满足飞行约束。设备状态、空域限制和航线是否合法,都必须由可信的业务服务和专业规则判断。
所以模型只负责提出和组织动作,任务系统负责校验和执行,关键操作保留权限控制与人工确认。飞控仍然由原有飞控系统负责。
问题三:Copilot 和传统工作流有什么区别?
参考回答:
固定工作流适合步骤明确、规则稳定的流程。例如,任务提交必须经过权限检查和参数校验,这些步骤不应该交给模型自由决定。
Copilot 解决的是用户目标不固定的问题。用户可能说巡检消防通道,也可能要求检查林区异常。系统需要先理解目标,再根据情况选择查询设备、检查约束和规划航线等工具。
我的设计不是用 Agent 替代所有工作流,而是让 Copilot 负责理解和编排,让确定性工作流负责关键执行步骤。这样既保留自然语言交互的灵活性,也能控制真实业务操作的风险。