Files
DronePlanning/PIPELINE_GUIDE.md
2026-02-26 19:37:55 +08:00

20 KiB
Raw Blame History

DronePlanning 处理 Pipeline 说明

本文档说明当前后端从自然语言输入到计划 JSON 输出的完整处理流程,以及可自定义修改点。

1. 总体流程

入口为 POST /generate_plan,主链路由 GenerationOrchestrator 编排:

flowchart LR
api[main.py /generate_plan] --> gen[py_tree_generator.generate]
gen --> orch[GenerationOrchestrator]
orch --> s1[Stage1 TaskUnderstanding]
orch --> s2[Stage2 ContextBinding]
orch --> s3[Stage3 MacroPlanning]
s3 --> simple{simple?}
simple -->|是| s6[Stage6 Validate]
simple -->|否| s4[Stage4 Middleware]
s4 --> s5[Stage5 MicroFilling]
s5 --> s6
s6 --> out[返回 py_tree JSON]

对应代码:

  • backend_service/src/main.py
  • backend_service/src/py_tree_generator.py
  • backend_service/src/pipeline/orchestrator.py
  • backend_service/src/pipeline/stages.py

1.1 各 Stage 提示词模板一览

Stage 是否调用 LLM System 模板/片段(按组合顺序) User 内容
Stage1 prompts/scene_classifier_prompt.txt 原始 user_prompt
Stage2
Stage3 simplesimple_mode_prompt.txtcomplexmacro_header.txt → 裁剪的 core_nodes.jsontemplate_ground.txt / template_air.txtcommon_rules.txt → 可选 system_extra_examples.txt → 意图标签 user_prompt + 参考知识(地点/模式/规则)
Stage4
Stage5 micro_header.txt → macro_tree JSON → resolved_data JSON → 裁剪的 atomic/nodes_schema.json 固定句:「请直接输出完整的带有 params 参数的 JSON 树结构。」
Stage6

各阶段模板的详细组合顺序与条件见对应小节(如 2.3、3.3、4.3、5.3、6.3、7.3)。

1.2 提示词分配流程图

下图按 Stage 标出各阶段使用的提示词模板及组合关系(仅含涉及 LLM 的 Stage

flowchart TB
  subgraph S1["Stage1 任务理解"]
    direction TB
    P1_sys["system: scene_classifier_prompt.txt"]
    P1_usr["user: user_prompt"]
  end

  subgraph S2["Stage2 上下文绑定"]
    P2["无 LLM / 无提示词"]
  end

  subgraph S3["Stage3 宏观规划"]
    direction TB
    P3a["simple: system = simple_mode_prompt.txt"]
    P3b["complex: system = macro_header → core_nodes → template_ground/air → common_rules → 可选 system_extra_examples → 意图标签"]
    P3_usr["user: user_prompt + 参考知识"]
  end

  subgraph S4["Stage4 中间层解析"]
    P4["无 LLM / 无提示词"]
  end

  subgraph S5["Stage5 微观填参"]
    direction TB
    P5_sys["system: micro_header → macro_tree JSON → resolved_data JSON → atomic/nodes_schema 裁剪"]
    P5_usr["user: 固定句"]
  end

  subgraph S6["Stage6 校验与后处理"]
    P6["无 LLM / 无提示词"]
  end

  S1 --> S2 --> S3
  S3 --> S4 --> S5 --> S6
  • Stage1 / Stage3 / Stage5 会调用 LLM其 System/User 内容由上图对应框内模板或片段组合而成。
  • Stage2 / Stage4 / Stage6 不调用 LLM无提示词分配。

2. Stage1任务理解TaskUnderstanding

功能:

  • 场景分类:simple / scene1 / scene4
  • 意图推断:intent_type
  • 风险标记:risk_flags(例如是否需要人工确认、是否涉及相对方位)

核心代码:

  • backend_service/src/llm/gateway.py::classify_scene()
  • backend_service/src/pipeline/stages.py::_infer_intent_type()
  • backend_service/src/pipeline/stages.py::_extract_risk_flags()
  • 数据契约:backend_service/src/pipeline/contracts.py::TaskUnderstanding

说明:

  • 分类模型可启用 thinkingSTAGE1_ENABLE_THINKING 控制)。
  • 该阶段不依赖节点字典,避免循环依赖。

2.1 输入格式

stage1_task_understanding(user_prompt: str) 仅接受原始用户指令字符串。

示例输入:

{
  "user_prompt": "无人机当前在地面,到广场查找绿色公交车,找到后拍照。"
}

2.2 输出格式TaskUnderstanding

{
  "scene_mode": "scene4",
  "intent_type": "search_and_photo",
  "requires_relative_target": false,
  "entities": {
    "raw_prompt": "无人机当前在地面,到广场查找绿色公交车,找到后拍照。"
  },
  "risk_flags": [],
  "constraints": {}
}

字段说明:

  • scene_mode: simple | scene1 | scene4
  • intent_type: 当前规则推导出的任务意图标签
  • requires_relative_target: 是否检测到相对方位需求
  • entities: 当前为轻量占位(最小包含 raw_prompt
  • risk_flags: 风险标记列表(如 needs_manual_confirmation
  • constraints: 约束占位(当前为空对象)

2.3 本阶段组合的提示词模板

角色 模板文件 路径 说明
system 场景分类 prompts/scene_classifier_prompt.txt 唯一 system 提示词,定义 simple/scene1/scene4 判定规则与示例
user 用户原文 调用方传入的 user_prompt 不做拼接,直接作为 user 消息

组合方式:messages = [ { "role": "system", "content": scene_classifier_prompt }, { "role": "user", "content": user_prompt } ]。分类结果解析为 scene_mode,其余 intent_typerisk_flags 由本阶段规则函数从 user_prompt 推断,不读模板。

3. Stage2上下文绑定ContextBinding

功能:

  • 按场景动态决定检索范围location/pattern/rules
  • 从多知识库并行检索并汇总
  • 相对目标提取(relative_refs
  • 预计算航点(precomputed_waypointsMVP
  • 基于意图与风险推导 required_actions

核心代码:

  • backend_service/src/retrieval/retriever.py::UnifiedRetriever
  • backend_service/src/retrieval/adapters/chroma_adapter.py
  • backend_service/src/llm/tool_runtime.py
  • backend_service/src/pipeline/stages.py::stage2_context_binding()
  • 数据契约:backend_service/src/pipeline/contracts.py::ContextBinding

多知识库策略:

  • 主集合:location_kbpattern_kbrules_kb
  • 兼容集合:drone_docs
  • 若主集合无结果,会尝试从 drone_docs + kb_type 过滤回退查询

3.1 输入格式

该阶段接收:

  • user_prompt: str
  • Stage1 输出 TaskUnderstanding

示例输入:

{
  "user_prompt": "无人机当前在空中去广场南边40米持续监控5分钟发现人就拍照。",
  "understanding": {
    "scene_mode": "scene4",
    "intent_type": "patrol_or_monitor",
    "requires_relative_target": false,
    "risk_flags": [],
    "entities": {"raw_prompt": "无人机当前在空中去广场南边40米持续监控5分钟发现人就拍照。"},
    "constraints": {}
  }
}

3.2 输出格式ContextBinding

{
  "location_context": "地点:广场,坐标(x=120,y=30,z=0)...",
  "pattern_context": "示例:先到达命名地点,再监控,再条件触发拍照...",
  "rules_context": "",
  "citations": {
    "location": ["..."],
    "pattern": ["..."],
    "rules": []
  },
  "resolved_refs": {},
  "precomputed_waypoints": [
    {"x": 160.0, "y": 30.0, "z": 10.0}
  ],
  "relative_refs": [],
  "required_actions": [
    "Sequence",
    "fly_to_waypoint",
    "loiter",
    "object_detect",
    "object_detected",
    "take_photos"
  ]
}

字段说明:

  • *_context: 分知识域拼接后的文本上下文
  • citations: 每个知识域的原始命中文档片段
  • precomputed_waypoints: Stage2 静态可解析时的预计算坐标
  • relative_refs: 相对目标结构化描述
  • required_actions: 后续用于节点裁剪注入的动作白名单

3.3 本阶段组合的提示词模板

本阶段不调用 LLM无提示词模板。仅做检索Location/Pattern/Rules、规则推导required_actionsrelative_refs)、预计算航点。


4. Stage3宏观规划Macro PlanningRound 1

功能:

  • 组装 prompt骨架 + 节点裁剪 + 模板 + 规则 + 检索结果)
  • 调用对应模型生成宏观树(及可选的 parameter_requests
  • 解析模型响应(含 reasoning 提取)

核心代码:

  • backend_service/src/prompting/composer.py::PromptComposer.compose_macro()
  • backend_service/src/llm/gateway.py::generate_json()
  • backend_service/src/pipeline/stages.py::stage3_macro_planning()
  • 数据契约:backend_service/src/pipeline/contracts.py::BTDraft

关键行为:

  • simple 模式与复杂模式使用不同客户端/模型配置Stage3 强制关闭 thinking强制 response_format=json_object;节点定义采用裁剪注入(非全量注入)。

4.1 输入格式Stage3

该阶段接收:

  • user_prompt: str
  • TaskUnderstanding
  • ContextBinding

核心输入(示例):

{
  "scene_mode": "scene4",
  "intent_type": "search_and_photo",
  "required_actions": ["Sequence", "fly_to_waypoint", "rotate_search", "object_detected", "take_photos"],
  "risk_flags": [],
  "context_blocks": {
    "location": "地点:广场...",
    "pattern": "示例:先到达再搜索...",
    "rules": ""
  }
}

4.2 输出格式BTDraft

{
  "system_prompt": "...(裁剪后的系统提示词)...",
  "user_prompt": "原始指令 + 参考知识增强段",
  "allowed_nodes": {
    "actions": ["fly_to_waypoint", "rotate_search", "take_photos"],
    "conditions": ["object_detected"]
  },
  "llm_raw_json": {
    "root": {
      "type": "Sequence",
      "name": "Sequence",
      "children": [
        {"type": "action", "name": "fly_to_waypoint", "params": {"x": 120, "y": 30, "z": 10, "acceptance_radius": 2}},
        {"type": "action", "name": "rotate_search", "params": {"target_class": "bus"}},
        {"type": "condition", "name": "object_detected", "params": {"target_class": "bus"}},
        {"type": "action", "name": "take_photos", "params": {"target_class": "bus", "track_time": 8}}
      ]
    }
  },
  "reasoning_text": null,
  "final_prompt": "=== System Prompt === ... === User Prompt === ..."
}

字段说明:

  • system_prompt/user_prompt: 实际发给模型的提示词
  • allowed_nodes: 节点裁剪结果(用于调试与复盘)
  • llm_raw_json: 模型返回并解析后的原始计划 JSON
  • reasoning_text: 可选推理文本(若模型返回)
  • final_prompt: 完整组合记录(便于离线排查)

4.3 本阶段组合的提示词模板

simple 模式(单轮,直接出最终树):

角色 模板/内容 路径 说明
system 简单模式全文 prompts/simple_mode_prompt.txt 直接作为 system无拼接
user 用户原文 + 参考知识 动态 user_prompt + _build_user_augmentation(context_blocks)

复杂模式scene1/scene4宏观树 Round 1

System 按顺序拼接以下内容(来自 prompting/composer.py::compose_macro()

顺序 模板/内容 路径 说明
1 宏观任务头 prompts/partials/macro_header.txt 任务定义与输出要求
2 节点定义(裁剪后) prompts/partials/core_nodes.json required_actions + risk_flags 裁剪,最多 30 个 action/condition格式化为「## 一、核心节点定义」+ JSON 代码块
3 任务模板(二选一) prompts/partials/template_ground.txtprompts/partials/template_air.txt drone_stateon_ground / in_air决定
4 通用规则 prompts/partials/common_rules.txt 若文件存在则追加
5 额外示例(可选) prompts/partials/system_extra_examples.txt 仅当 intent_type == "generic_mission" 时追加
6 意图标签 代码生成 固定段落:## 任务意图标签\n- intent_type: \{intent_type}``

User 消息:

  • 内容 = user_prompt + 参考知识增强段。
  • 参考知识增强段由 _build_user_augmentation(context_blocks) 生成:若 context_blockslocation / pattern / rules 非空,则按顺序拼接为「【地点知识】…」「【任务模式】…」「【规则知识】…」,整体包在 ---\n参考知识\n…\n--- 中。

5. Stage4中间层解析Middleware Resolution

功能:

  • 读取 Stage3 输出的 parameter_requests
  • 对含 landmark 等实体的请求做位置检索与航点预计算,写入 resolved_data
  • 其他实体透传为 {node}_entities,供 Stage5 使用

核心代码:

  • backend_service/src/pipeline/stages.py::stage4_middleware_resolution()
  • 复用 retriever.retrieve(scopes=["location"])tool_runtime.build_precomputed_waypoint()

5.3 本阶段组合的提示词模板

本阶段不调用 LLM,无提示词模板。仅做依赖解析与数据绑定。


6. Stage5微观参数填空Micro Parameter FillingRound 2

功能:

  • prompts/atomic/nodes_schema.json 按宏观树中用到的节点名裁剪出 atomic_schema
  • 调用 PromptComposer.compose_micro() 组装 Round 2 的 system 提示词
  • 再次调用模型,输出带完整 params 的 JSON 树

核心代码:

  • backend_service/src/prompting/composer.py::compose_micro()
  • backend_service/src/pipeline/stages.py::stage5_micro_filling()

6.3 本阶段组合的提示词模板

角色 模板/内容 路径 说明
system 微观任务头 prompts/partials/micro_header.txt 第一段
system 宏观骨架树 运行时 ## 1. 原宏观骨架树 (macro_tree) + draft.macro_tree 的 JSON
system 确切数据字典 运行时 ## 2. 确切数据字典 (resolved_data) + Stage4 输出的 resolved_data JSON
system 原子节点规范 prompts/atomic/nodes_schema.json(按需裁剪) ## 3. 原子节点规范 (atomic_schema);仅保留宏观树中出现的 action/condition 的 schema
user 固定指令 代码写死 "请直接输出完整的带有 params 参数的 JSON 树结构。"

组合方式system = 上述四段用 \n\n 拼接user = 固定字符串。Round 2 不再注入 RAG 检索块。


7. Stage6校验与后处理ValidateAndPostprocess

功能:

  • JSON Schema 校验simple / complex
  • 注入 plan_idvisualization_urlfinal_prompt
  • 保存推理链与历史记录
  • 在复杂场景下注入 context.relative_refs(及可选 context.resolved_refs

核心代码:

  • backend_service/src/validation/validator.py
  • backend_service/src/validation/schema_provider.py
  • backend_service/src/pipeline/stages.py::stage6_validate_and_postprocess()
  • backend_service/src/py_tree_generator.py::render_visualization()
  • backend_service/src/py_tree_generator.py::_save_history()

7.1 输入格式

该阶段接收:

  • user_prompt: str
  • TaskUnderstanding
  • ContextBinding
  • BTDraft
  • 复杂模式下还有 Stage5 的 final_treesimple 模式下为 draft.llm_raw_json

7.2 输出格式(最终 API 返回)

复杂模式示例:

{
  "root": {
    "type": "Sequence",
    "name": "Sequence",
    "children": [
      {"type": "action", "name": "fly_to_waypoint", "params": {"x": 120, "y": 30, "z": 10, "acceptance_radius": 2}},
      {"type": "action", "name": "rotate_search", "params": {"target_class": "bus"}},
      {"type": "condition", "name": "object_detected", "params": {"target_class": "bus"}},
      {"type": "action", "name": "take_photos", "params": {"target_class": "bus", "track_time": 8}}
    ]
  },
  "context": {
    "relative_refs": [
      {"anchor": "front_building", "relation": "left", "distance_m": 20.0}
    ],
    "resolved_refs": {
      "strategy": "backend_static_resolution",
      "waypoints": [{"x": 120.0, "y": 30.0, "z": 10.0}]
    }
  },
  "plan_id": "6a924d0d-f1a7-4ef1-a9fa-31f73f3115ce",
  "visualization_url": "/static/py_tree.png",
  "final_prompt": "=== System Prompt === ... === User Prompt === ..."
}

simple 模式示例:

{
  "root": {
    "type": "action",
    "name": "move_direction",
    "params": {"direction": "north", "distance": 50}
  },
  "plan_id": "0f0e5e5f-b9a2-4e6f-95f5-c95e9e6280a5",
  "visualization_url": "/static/py_tree.png",
  "final_prompt": "=== System Prompt === ... === User Prompt === ..."
}

字段说明:

  • root: 通过 schema 校验后的行为树根节点
  • context: 仅在复杂模式且命中相对目标时追加
  • plan_id: 每次生成唯一 ID
  • visualization_url: 最新可视化图访问路径
  • final_prompt: 生成时使用的完整提示词记录

7.3 本阶段组合的提示词模板

本阶段不调用 LLM,无提示词模板。仅做校验、注入元数据与写盘。


8. 数据入库RAG Ingestion逻辑

入库脚本:

  • tools/rag/ingest.py

行为:

  • 扫描 tools/rag/knowledge_base/
  • 根据子目录推断 kb_typelocation/pattern/rules
  • 同时写入:
    • drone_docs(兼容)
    • location_kb / pattern_kb / rules_kb(新检索路径)

9. 可自定义修改点(推荐按优先级)

9.1 场景与意图逻辑

可改文件:

  • backend_service/src/pipeline/stages.py

可改内容:

  • _infer_intent_type():扩展意图类别
  • _extract_risk_flags():新增风险规则
  • _derive_required_actions():调整规则推导的动作集合

9.2 Prompt 策略

可改文件:

  • backend_service/src/prompting/composer.py
  • backend_service/src/prompts/prompt_manifest.yaml
  • backend_service/src/prompts/partials/*

可改内容:

  • 骨架片段选择
  • 节点裁剪规则(当前上限 30
  • 示例注入策略(何时注入 extra examples
  • 用户侧检索增强格式

9.3 模型路由与推理参数

可改文件:

  • backend_service/src/llm/gateway.py

可改内容:

  • 分类模型与生成模型分流策略
  • temperaturemax_tokens、重试次数
  • thinking 开关策略Stage1/Stage3

9.4 检索策略

可改文件:

  • backend_service/src/retrieval/retriever.py
  • backend_service/src/retrieval/adapters/chroma_adapter.py
  • tools/rag/ingest.py

可改内容:

  • 检索并发策略与 top_k
  • 回退策略(主集合与兼容集合)
  • kb_type 划分方式
  • 文档切分与 metadata 设计

9.5 相对目标解析

可改文件:

  • backend_service/src/pipeline/stages.py
  • backend_service/src/llm/tool_runtime.py

可改内容:

  • relative_refs 抽取规则
  • 静态解析能力(何时生成 resolved_refs
  • 与 UAV 端协议字段兼容策略

9.6 校验与输出协议

可改文件:

  • backend_service/src/validation/validator.py
  • backend_service/src/validation/schema_provider.py
  • backend_service/src/py_tree_generator.pyschema 来源)

可改内容:

  • simple/complex schema 约束强度
  • 顶层 context 字段的可选校验
  • 失败错误信息与恢复策略

10. 关键环境变量

  • ORIN_IP
  • OPENAI_API_KEY
  • CLASSIFIER_MODEL / SIMPLE_MODEL / COMPLEX_MODEL
  • CLASSIFIER_BASE_URL / SIMPLE_BASE_URL / COMPLEX_BASE_URL
  • STAGE1_ENABLE_THINKING
  • ENABLE_REASONING_CAPTURE
  • REASONING_PREVIEW_LINES

11. 自定义改造建议(实践顺序)

  1. 先改 Stage1 规则推导(低风险,收益快)
  2. 再改 PromptComposer 的裁剪与注入(控制长度与稳定性)
  3. 再改检索策略top_k、回退、metadata
  4. 最后改 schema 与输出协议(需联动执行端)

12. 变更后最小回归清单

每次改造后至少验证:

  1. simple 指令:返回 root.action,且无 children
  2. scene4 指令有复合树结构JSON 可解析
  3. relative 指令:复杂模式下出现 context.relative_refs
  4. /generate_plan 不变更接口字段(兼容外部调用)
  5. python tools/rag/ingest.py 可完成入库(或输出可定位错误)