software_requirements.md 6.4 KB

智能问答模块软件需求说明书

1. 总体概述

  • 本系统外挂在现有 BI 平台,负责解析仪表板、卡片以及机构(bbk)维度下的问答需求,自动生成 SQL 并在 BI 系统中执行。
  • 系统提供 FastAPI 后端接口,供前端或其他服务发起“问题生成/确认”流程,并将确认后的问答对写入 parquet 文件,用于离线训练或直接答复。
  • 全部服务运行在后台,无前端组件;所有对话上下文均来源于 DuckDB 中的 BI 元数据表及机构配置。

2. 数据结构要求

  1. 卡片-数据集-仪表板映射表:字段 card_id、dashboard_id、dataset_id、dashboard_name、card_name、dataset_name、bbk_id。作为主数据表,保证数据有效。
  2. 卡片信息表:字段 card_id、card_name、card_desc、sql_select、sql_where、sql_groupby 描述卡片的 SQL 形态。
  3. 卡片筛选器信息表:字段 card_id、filter_id、filter_type(F/D)、where_clause、default_value、options 描述可选筛选器与内置过滤条件。
  4. 仪表板信息表:字段 dashboard_id、dashboard_name、dashboard_desc、folder_path 描述仪表板元数据。
  5. 数据集 DDL 表:字段 dataset_id、dataset_ddl,按 HiveSQL 规范存放。

这些结构均存放于 DuckDB,所有查询均基于机构编号(bbk/bbk_id)过滤。

3. 系统架构

  • 接口层app/endpoints 下的 FastAPI generate_qa_pair 接口作为唯一对外入口。
  • 工作流层PipelineManager + Workflow 负责解析配置化节点依赖,并串联 operator。
  • Operator 层generate_qa_pair operator 协调数据读取、prompt 渲染、LLM 调用与结果解析。
  • 支撑模块
    • LLMManager 统一管理不同模型提供方与解析策略。
    • PromptManager 负责 prompt 模板的存储、渲染和复用。
    • ParserManager/parsers 定义 LLM 输出解析策略。
    • DuckDBClient 提供线程安全的数据查询封装。
    • 日志模块 app.log 负责统一输出。
    • 常量模块 app.const 维护目录、阈值等。

模块间关系:接口层调用 WorkflowWorkflow 根据配置调用 operator;operator 内部组合数据访问模块、Prompt/LLM 管理器与解析器。最终结果写入日志目录与 parquet 文件。

4. 模块划分与实现要点

4.1 接口模块(FastAPI)

  • 负责接收 QARequest,校验卡片数量不超过 MAX_INPUT_CARD_IDS
  • bbk_id/dashbord/card_ids/user_request 打包成 input_args 交给 Workflow
  • 返回 QAResponse,包含仪表板、机构、卡片 ID 及问答列表。

4.2 工作流模块

  • PipelineManager:从 config/pipeline_settings.yaml 读取节点定义,生成拓扑顺序。
  • Workflow:按照拓扑依次执行 operator,支持异步/流式输出。
  • 节点之间通过 workflow.result 共享数据,last_node 节点需写入最终结果。

4.3 Operator:generate_qa_pair

  • DuckDBClient 读取仪表板、卡片、筛选器及 DDL 元数据,组装为 DashboardInfo
  • 使用 PromptManager 渲染 generate_qa_pair 或带用户偏好模板。
  • 调用 LLMManager 按节点配置选择模型,获取 JSON 问答列表,并借助 ParserManager 解析。
  • 将过滤条件转换为 WHERE/HAVING 语句,拼接最终 SQL,构造 QAPair
  • 记录 prompt 文本和生成结果日志,并触发 parquet 落盘(后续模块负责)。

4.4 LLM 管理模块

  • LLMManager 为单例,读取 config/llm_settings.yaml
  • 支持多种 provider:默认 echo(回声,便于测试)、http(通过 HTTP 调用自建/第三方 LLM 服务)。
  • 每个模型可指定解析器(如 jsontext),通过 ParserManager 统一管理。
  • 暴露 get_llm_model(model_name),operator 根据 pipeline 配置取用。

4.5 Prompt 管理模块

  • PromptManager 读取 config/prompt_template.yaml 或使用内置默认模板。
  • 模板可存放于 prompts/ 目录或直接配置在 YAML 中,支持变量占位与必填校验。
  • PromptTemplate.ainvoke(context) 异步渲染并返回文本,供 operator 直接写入日志或传给 LLM。

4.6 解析器模块

  • parsers.BaseParser 抽象解析器接口。
  • 内置 JsonParser(去除 Markdown 包裹、解析 JSON)与 TextParser(直接返回文本)。
  • ParserManager 允许通过配置注册自定义解析器或重写默认行为。

4.7 数据访问模块

  • DuckDBClient 封装了线程安全查询方法,支持:
    • fetch_dashboard_cards:根据 dashboard_idcard_idsbbk_id 过滤卡片。
    • fetch_card_definition:获取卡片 SQL 定义。
    • fetch_card_filters:获取筛选器/固化条件。
    • fetch_dashboard_infofetch_dataset_ddl:补全仪表板及数据集信息。
  • 所有查询返回字段-值 dict 列表,以供 Pydantic 模型构造。

4.8 存储与日志

  • 日志目录 app/log,通过 app.log.logger 写入,支持级别控制。
  • Prompt 与问答日志写入 LOG_ROOT/prompts/... 便于审计。
  • 经过人工确认的问题将由后续节点序列化到 parquet,文件路径遵循 DATA_DIR/parquet/{bbk_id}/{dashboard_id}/

5. 业务流程

  1. 用户在 BI 前端选定仪表板、卡片与机构,触发 API。
  2. 接口层调用 Workflowget_dashboard_info 节点(后续实现)使用 DuckDBClient 读取所需元数据。
  3. generate_qa_pair operator 构建 prompt,调用 LLM 生成若干候选问题和过滤条件。
  4. 系统将问答转成 SQL,连同 slot 化问题写入返回体与 parquet,日志记录 prompt 与 SQL。
  5. 后续模块可基于这些问答对执行真实查询或训练问答模型。

6. 非功能需求

  • 性能:单次请求支持最多 3 张卡片(可通过常量调整)。DuckDB 查询需在 1 秒内返回元数据。
  • 扩展性:LLM 与 Prompt 均通过配置驱动,可为不同机构配置不同模型或模板。
  • 可观测性:日志必须包含 request_id、bbk_id、dashboard_id 以便审计。
  • 安全:所有外部 LLM HTTP 调用需支持自定义 Header,用于透传鉴权 token。

7. 开发注意事项

  • 任何变量或字段中包含 bbk/bbk_id 均指机构编号。
  • 当 YAML/模板缺失时,模块会回退到默认模板与 Echo LLM,方便在无外部依赖下开发调试。
  • DuckDB 表结构需与上述字段保持一致,字段命名采用 snake_case。