Files
DronePlanningV2/docs/项目流程详解.md
2026-03-17 10:51:32 +08:00

12 KiB
Raw Permalink Blame History

无人机行为规划系统 - 项目流程详解


1. 整体架构

flowchart TB
    subgraph Input [输入]
        UserText[用户自然语言指令]
    end

    subgraph Layer1 [Layer 1 - Router]
        Router[意图路由]
        FastPath{Fast-Path?}
    end

    subgraph RAG [RAG 检索]
        MapDB[map_db]
        RuleDB[rule_db]
        FewShotDB[few_shot_db]
        Retriever[RAGRetriever]
    end

    subgraph Layer2 [Layer 2 - Composer]
        Composer[动态组装 Prompt]
    end

    subgraph Layer3 [Layer 3 - Planner]
        Planner[LLM 规划]
        ToolCall[Function Calling]
        MCPCalc[calculate_relative_coordinate]
    end

    subgraph Layer4 [Layer 4 - Execution]
        Parse[parse_json_to_tree]
        Wrap[wrap_and_build_tree]
        Tree[py_trees 行为树]
    end

    UserText --> Router
    Router --> FastPath
    FastPath -->|是| Output1[直接返回原子意图]
    FastPath -->|否| Retriever
    Retriever --> MapDB
    Retriever --> RuleDB
    Retriever --> FewShotDB
    Retriever --> Composer
    Composer --> Planner
    Planner --> ToolCall
    ToolCall --> MCPCalc
    MCPCalc --> Planner
    Planner --> Parse
    Parse --> Wrap
    Wrap --> Tree

2. 数据流与各 Stage 总览

Stage 模块 对应代码 是否调用 RAG 是否调用工具 是否调用 LLM
Layer 1 Router pipeline/router.py
RAG Retriever rag/retriever.py map/rule/few_shot
Layer 2 Composer pipeline/composer.py 否(消费 RAG 结果)
Layer 3 Planner pipeline/planner.py 否(消费 Composer 输出) LLM 调用 mcp
Layer 4 Execution execution/tree_wrapper.py

3. Stage 1Layer 1 - Router意图路由

3.1 职责

  • 对用户自然语言做意图分类和实体抽取
  • 判断是否为 Fast-Path仅原子意图起飞/降落/悬停)
  • 冲突处理:同时含原子+业务意图时,保留业务意图

3.2 对应代码

3.3 是否调用 RAG

。Router 仅依赖 LLM不访问 RAG。

3.4 是否调用工具

。仅调用 LLM 的 chat_completion_json,无 Function Calling。

3.5 提示词组织

System PromptROUTER_SYSTEM_PROMPT

  • 角色:指令意图分类器
  • 意图集合原子意图atomic_takeoff/atomic_land/atomic_hover、业务意图fly_task/search_task/track_task/photo_task/interact_task
  • 实体要求locations、targets、direction、distance
  • 规则相对描述如「广场东边500米」必须拆分为 locations=["广场"], direction="东", distance=500

User Message:用户原始指令。

输出 SchemaROUTER_JSON_SCHEMA

{
  "intents": ["string"],
  "entities": {
    "locations": ["string"],
    "targets": ["string"],
    "direction": "string",
    "distance": number
  }
}

3.6 输出与短路逻辑

  • RouterResult.intents:解析后的意图列表
  • RouterResult.entities:实体字典
  • RouterResult.is_fast_path:若 intents 非空且全部属于 ATOMIC_INTENTS,则为 True,后续 RAG/Composer/Planner/Execution 不执行

4. Stage 2RAG 检索

4.1 职责

  • 根据 Router 的 intentsentitiesuser_text 检索上下文
  • 地图坐标热表优先冷库ChromaDB map_db兜底
  • 规则约束:按 intent 查 rule_db
  • Few-shot 示例:用 user_text 向量检索 few_shot_db
  • 仅提供基准点坐标base_location_coords),不负责相对坐标计算;相对描述由 LLM 通过 mcp 工具计算

4.2 对应代码

4.3 调用的 RAG 库

库名 用途 检索方式
map_db 基准点坐标 metadata 精确匹配 where={"location": base_loc}
rule_db 规则约束 metadata 精确匹配 where={"intent": intent}
few_shot_db Few-shot 示例 向量相似度 query(query_texts=[user_text], n_results=2)

4.4 是否调用工具

。RAG 不调用 mcp_calc仅提供 base_location_coordsrelative_descriptions,坐标计算由 LLM 通过 Function Calling 完成。

4.5 输出结构

{
    "map_context": str,
    "rule_context": str,
    "few_shot_examples": [...],
    "base_location_coords": {loc: {x,y,z}},   # 基准点坐标,不计算相对位置
    "relative_descriptions": [               # 相对描述,供 LLM 调用工具
        {"target": "广场东边500米", "base": "广场", "direction": "东", "distance": 500},
        ...
    ]
}

5. Stage 3Layer 2 - Composer动态组装

5.1 职责

  • 根据 intents 裁剪 node_schema.json,只保留相关 actions
  • 将 RAG 的 base_location_coordsrelative_descriptionsmap_contextrule_contextfew_shot_examples 拼入 System Prompt
  • 生成发给 Planner LLM 的精简 Prompt

5.2 对应代码

5.3 是否调用 RAG

。Composer 不直接调用 RAG只消费 Retriever 返回的 rag_context

5.4 是否调用工具

5.5 提示词组织

Prompt 由以下部分顺序拼接:

  1. 指令_instruction(来自 node_schema
  2. 基准点坐标:若 base_location_coords 非空,输出 ## 基准点坐标 base_location_coordsENU单位米
  3. 可用节点:裁剪后的 schema JSONactions、conditions、control_flow、decorators
  4. RAG 地图上下文rag_context["map_context"]
  5. RAG 规则约束rag_context["rule_context"]
  6. RAG 示例行为树rag_context["few_shot_examples"] 前 2 条
  7. 坐标计算规则:若用户只说绝对地点,可直接使用 base_location_coords若用户说相对位置必须调用 calculate_relative_coordinate禁止心算

5.6 意图到 Actions 映射

INTENT_TO_ACTIONS = {
    "fly_task": ["fly_to_waypoint", "fly_sequence", "move_direction"],
    "search_task": ["search_pattern", "rotate_search"],
    "track_task": ["track_object"],
    "photo_task": ["take_photos"],
    "interact_task": ["report_message", "manual_confirmation"],
}

6. Stage 4Layer 3 - Planner宏观规划

6.1 职责

  • 根据 Composer 的 System Prompt 和用户文本,生成行为树 JSON
  • 支持 Function CallingLLM 可自主调用 calculate_relative_coordinate 计算相对坐标
  • 最多 5 轮 Tool 循环,无工具调用时解析最终 JSON 返回

6.2 对应代码

6.3 是否调用 RAG

。Planner 只消费 Composer 输出的 system_prompt,其中已包含 RAG 上下文。

6.4 是否调用工具

。坐标计算仅由 LLM 负责,通过 OpenAI Function Calling 调用 calculate_relative_coordinatemcp 工具。Planner 执行工具并追加结果到 messages继续下一轮推理。

工具定义CALC_COORDINATE_TOOL

{
  "type": "function",
  "function": {
    "name": "calculate_relative_coordinate",
    "description": "根据基准点坐标和方向、距离,计算目标点的绝对 ENU 坐标...",
    "parameters": {
      "base_x": "number",
      "base_y": "number",
      "direction_str": "string",
      "distance": "number"
    }
  }
}

工具实现src/drone_planning/tools/mcp_calc.py 中的 calculate_relative_coordinate

6.5 提示词组织

  • SystemComposer 生成的完整 Prompt含 schema、坐标、RAG 上下文、工具说明)
  • User:用户原始指令
  • 若 LLM 返回 tool_calls:追加 assistant message + 各 tool 结果,继续调用 chat_completion_with_tools
  • 若 LLM 返回纯文本:解析 JSON 作为行为树

6.6 回退逻辑

  • 若模型不支持 tools使用 chat_completion_json + PLANNER_JSON_SCHEMA 无工具模式
  • 若 JSON 解析失败:使用 chat_completion + response_format={"type": "json_object"}

7. Stage 5Layer 4 - Execution执行包装

7.1 职责

  • 将 Planner 的 JSON 递归解析为 py_trees 对象
  • 根据 Blackboard is_in_air 判断:若在地面,自动在业务树前插入 [SystemCheck -> Takeoff] 子树
  • 输出 ASCII 树结构供展示

7.2 对应代码

7.3 是否调用 RAG

7.4 是否调用工具

7.5 节点映射

JSON type py_trees 实现
Sequence py_trees.composites.Sequence
Selector py_trees.composites.Selector
Parallel py_trees.composites.Parallel
fly_to_waypoint FlyToWaypointAction
其他 action GenericAction

8. 坐标计算流程(仅 LLM 负责)

flowchart LR
    subgraph RAG [RAG 仅提供基准点]
        Router1[Router 抽取 direction+distance]
        Retriever1[Retriever 解析复合地点]
        MapDB1[查 map_db 得基准坐标]
        Composer1[Composer 将 base_location_coords 写入 Prompt]
    end

    subgraph LLM [LLM 调用 mcp 计算]
        Planner1[Planner 收到 Prompt]
        LLM1[LLM 调用 calculate_relative_coordinate]
        Tool1[mcp 工具]
        Result1[工具结果写回 messages]
    end

    Router1 --> Retriever1
    Retriever1 --> MapDB1
    MapDB1 --> Composer1
    Composer1 --> Planner1
    Planner1 --> LLM1
    LLM1 --> Tool1
    Tool1 --> Result1
  • RAG:仅提供 base_location_coords(基准点坐标)和 relative_descriptions(相对描述列表),不调用 mcp_calc
  • LLM:若用户说绝对地点,直接使用 base_location_coords若用户说相对位置必须调用 calculate_relative_coordinate禁止心算

9. RAG 数据格式

9.1 map_db.jsonl

每行一个 JSON字段示例

{"document": "大门位于入口处,坐标 x=0, y=0", "location": "大门", "x": 0, "y": 0, "z": 0}

9.2 rule_db.jsonl

{"document": "起飞必须先做系统检查", "intent": "fly_task", "priority": "high"}

9.3 few_shot_db.jsonl

{"document": "飞到大门然后拍照", "intent": "fly_task", "tree_json": "{\"root\": {...}}"}

10. 环境变量与配置

变量 默认值 说明
LLM_CHAT_BASE_URL http://localhost:8081/v1 Chat API
LLM_EMBEDDING_BASE_URL http://localhost:8090/v1 Embedding APIRAG
ENABLE_THINKING false 模型思考模式
CHROMA_PERSIST_PATH ./data/chroma ChromaDB 存储路径

11. 文件索引

功能 文件路径
Router src/drone_planning/pipeline/router.py
Composer src/drone_planning/pipeline/composer.py
Planner src/drone_planning/pipeline/planner.py
RAG Retriever src/drone_planning/rag/retriever.py
RAG 向量存储 src/drone_planning/rag/vector_store.py
RAG 灌入 src/drone_planning/rag/ingestion.py
坐标计算工具 src/drone_planning/tools/mcp_calc.py
执行包装 src/drone_planning/execution/tree_wrapper.py
节点实现 src/drone_planning/execution/nodes.py
黑板 src/drone_planning/core/blackboard.py
LLM 客户端 src/drone_planning/llm_client/client.py
API 路由 src/drone_planning/api/routes.py
节点 Schema config/node_schema.json
知识库 data/knowledge/*.jsonl