目录 · 第 01 章4 卷 12 章

第 01 章 · 卷一 先搞懂整个项目

项目全景与业务设计

平台已有的五块能力、一线真正的卡点、Copilot 的定位与不做什么。

约 9 分钟9 节
已知事实

项目是一个面向林业巡检、应急消防、园区安防的无人机实战平台。平台已有设备接入、航线规划、任务下发、遥测回传和告警处置能力。现在需要增加 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总体设计

本章的目标架构如下。图中展示的是业务调用关系,不代表所有模块必须部署为独立服务。

  1. 用户在三维地图圈选区域并描述作业目标
  2. 交互层Vue 3 + Cesium 传递区域和自然语言
  3. Copilot入口接收请求并创建本次编排会话
  4. 意图理解提取作业目标、区域、时间和约束
  5. 业务工具调用按顺序查询设备、检查空域、规划航线
  6. 结果校验检查返回结果是否完整且满足业务规则
  7. 任务草稿汇总设备、航线和执行参数供用户审核
  8. 人工确认用户检查方案并明确确认提交
  9. 任务执行复用原有任务服务下发任务
  10. 飞行监控接收遥测与视觉告警并更新任务状态
  11. 异常处置生成建议并调用受权限控制的处置能力
  12. 报告生成汇总执行记录、遥测和告警结果

整个流程可以分为三个阶段。

执行前:从目标到任务草稿。 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。草稿允许修改;正式任务必须经过业务校验和授权提交。

java
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 不直接实现设备查询和航线计算,而是通过业务能力接口调用现有服务。

java
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 表示明确的时间点,具体时区展示由业务规则决定。接口中的类型是建议定义,接入现有平台时应以真实服务契约为准。

编排服务可以按照以下逻辑工作:

java
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 负责理解和编排,让确定性工作流负责关键执行步骤。这样既保留自然语言交互的灵活性,也能控制真实业务操作的风险。