Files
Neo-ZQYY/docs/prd/Neo_Specs/NS2-ai-prompt-refinement.md

17 KiB
Raw Blame History

NS2AI Prompt 细化 — ai-prompt-refinement

优先级NS1 完成后立即执行Prompt 细化是 AI 功能闭环的关键) 预估工作量:中等 前置条件P5-A 已完成AI 骨架就绪、NS1 已完成(后端 API 数据结构确定) 参考基准:docs/prd/specs/P5-miniapp-ai-integration.mdP5-B 阶段定义)


一、背景与目标

P5-A 阶段已交付 AI 集成管道:百炼封装、缓存 API、SSE 框架、应用 2/8 完整实现、应用 1/3/4/5/6/7 的触发机制和调用骨架。但应用 1/3/4/5/6/7 的 build_prompt() 函数仍为占位骨架,核心数据字段(consumption_recordsservice_historyobjective_data 等)标记为 TODO。

本 SPEC 目标:将 6 个应用的 Prompt 拼接函数从骨架升级为完整实现,使 AI 应用能基于真实数据生成有价值的分析结果。

当前骨架状态

应用 文件 骨架状态 待细化字段
应用 1 app1_chat.py 页面上下文文本化工具留接口 page_contextscreen_content 各页面文本化
应用 3 app3_clue.py build_prompt() 占位 consumption_recordsDWD+DWS 订单明细全维度)
应用 4 app4_analysis.py build_prompt() 占位 service_historyassistant_info
应用 5 app5_tactics.py build_prompt() 占位 service_historyassistant_info(同应用 4
应用 6 app6_note.py build_prompt() 占位 consumption_data(同应用 3 的 main_data
应用 7 app7_customer.py build_prompt() 占位 objective_data(同应用 3 的 main_data

二、技术架构

2.1 数据获取层(新建共享模块)

Prompt 细化的核心是从数据库获取真实数据并格式化为 AI 可读的 JSON。多个应用共享相同的数据获取逻辑应抽取为共享模块

apps/backend/app/ai/
├── data_fetchers/              🆕 新建
│   ├── __init__.py
│   ├── member_data.py          # 客户数据获取(消费记录、会员卡、余额等)
│   ├── assistant_data.py       # 助教数据获取(基本信息、服务历史)
│   ├── service_history.py      # 服务记录获取(助教-客户维度)
│   └── page_context.py         # 页面上下文文本化(应用 1 专用)
├── apps/
│   ├── app1_chat.py            🔧 补充页面文本化调用
│   ├── app3_clue.py            🔧 补充 consumption_records 拼接
│   ├── app4_analysis.py        🔧 补充 service_history + assistant_info
│   ├── app5_tactics.py         🔧 补充 service_history + assistant_info
│   ├── app6_note.py            🔧 补充 consumption_data
│   └── app7_customer.py        🔧 补充 objective_data

2.2 数据获取函数设计

member_data.py — 客户数据获取(应用 3/6/7 共用)

async def fetch_member_consumption_data(
    site_id: int, member_id: int, months: int = 3
) -> dict:
    """获取客户近 N 个月消费数据DWD+DWS 全维度)。

    返回结构对应 P5 spec 中 main_data
    - consumption_records: 台桌结账 + 商城订单明细列表
    - member_cards: 会员卡明细
    - card_balance_total: 储值卡余额合计
    - stored_value_balance_total: 储值余额合计
    - expected_visit_date: 预计到店日期
    - days_since_last_visit: 距上次到店天数
    """

数据源(全部通过 FDW

  • fdw_etl.v_dwd_settlement_head + fdw_etl.v_dwd_table_fee_log(台桌结账)
  • fdw_etl.v_dwd_store_goods_sale(商城订单)
  • fdw_etl.v_dwd_recharge_order(充值记录)
  • fdw_etl.v_dim_member_card_account(会员卡明细)
  • fdw_etl.v_dws_member_consumption_summary(消费汇总 + 余额)
  • fdw_etl.v_dws_member_visit_detail(到店明细 → 计算预计到店日期)

⚠️ 金额口径:使用 items_sum= table_charge_money + goods_money + assistant_pd_money + assistant_cx_money + electricity_money禁止 consume_money ⚠️ 会员字段断档DQ-6/DQ-7member_phone/member_name 通过 member_id JOIN dim_member

assistant_data.py — 助教数据获取(应用 4/5 共用)

async def fetch_assistant_info(
    site_id: int, assistant_id: int
) -> dict:
    """获取助教基本信息(花名、级别、工龄等)。"""

async def fetch_service_history(
    site_id: int, assistant_id: int, member_id: int, months: int = 3
) -> list[dict]:
    """获取助教服务该客户的历史记录。"""

数据源:

  • fdw_etl.v_dim_assistant(基本信息)
  • fdw_etl.v_dwd_assistant_service_log(服务记录,按助教+客户筛选)
  • fdw_etl.v_dws_member_assistant_relation_index(关系指数)
  • fdw_etl.v_dws_member_assistant_intimacy(亲密度)

page_context.py — 页面上下文文本化(应用 1 专用)

async def build_page_text(
    source_page: str, context_data: dict, site_id: int
) -> str:
    """将页面数据转换为 AI 可读的结构化文本。

    根据 source_page 类型,从数据库获取对应数据并格式化。
    """

支持的页面类型及数据获取:

source_page 数据获取 文本化内容
task-detail coach_tasks + member + notes + ai_cache 任务信息 + 客户信息 + 备注 + AI 分析
customer-detail member + consumption + clues 客户全信息 + 消费记录 + 维客线索
coach-detail assistant + tasks + notes 助教信息 + 任务统计 + 备注
board-finance finance DWS 汇总 财务数据摘要
board-customer 当前筛选维度 top 列表 客户排名摘要
board-coach 当前筛选维度排名 助教排名摘要
performance salary_calc + daily_detail 绩效数据摘要
my-profile user info + assistant binding 个人信息摘要

2.3 数据库连接模式

  • 所有 FDW 查询通过 get_etl_readonly_connection(site_id)fdw_etl.* 视图
  • 业务库查询通过 get_connection()
  • 查询前必须 SET LOCAL app.current_site_idRLS 隔离)

三、各应用 Prompt 细化详细设计

3.1 应用 3客户数据维客线索分析

build_prompt() 需要拼接的完整 JSON 结构(参考 P5 spec

{
  "current_time": "2026-03-08 14:30:25",
  "member_nickname": "客户昵称",
  "main_data": {
    "consumption_records": [
      {
        "settle_date": "2026-03-05",
        "settle_type": 1,
        "items_sum": 280.00,
        "table_charge_money": 180.00,
        "assistant_pd_money": 80.00,
        "assistant_cx_money": 0,
        "goods_money": 20.00,
        "room_name": "VIP-3",
        "duration_minutes": 120,
        "assistant_names": ["张助教"]
      }
    ],
    "member_cards": [
      {"card_type": "金卡", "balance": 1500.00, "gift_balance": 200.00}
    ],
    "card_balance_total": 1700.00,
    "stored_value_balance_total": 1700.00,
    "expected_visit_date": "2026-03-10",
    "days_since_last_visit": 15
  },
  "reference": {
    "app6_clues": [...],
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": [...]},
      {"generated_at": "2026-02-15", "clues": [...]}
    ]
  }
}

实现要点:

  • consumption_recordsv_dwd_settlement_head + v_dwd_table_fee_log 获取settle_type IN (1,3)
  • 金额字段逐项拆分table_charge_money / assistant_pd_money / assistant_cx_money / goods_money不使用 consume_money
  • expected_visit_datev_dws_member_visit_detail 的到店间隔推算
  • reference 从 ai_cache 获取 app6 + app8 最近 2 套历史

3.2 应用 4关系分析/任务建议

build_prompt() 需要拼接的完整 JSON 结构:

{
  "current_time": "2026-03-08 14:30:25",
  "assistant_info": {
    "nickname": "张助教",
    "level": "高级",
    "hire_date": "2024-06-01",
    "tenure_months": 21,
    "monthly_customers": 45,
    "performance_tier": "A档"
  },
  "service_history": [
    {
      "service_date": "2026-03-01",
      "duration_minutes": 90,
      "items_sum": 250.00,
      "room_name": "VIP-3",
      "is_pd": true
    }
  ],
  "task_assignment_basis": "优先召回",
  "customer_data": {
    "system_data": { /* 同应用 3  main_data */ },
    "notes": [
      {"recorded_by": "张助教", "content": "客户喜欢打斯诺克", "created_at": "2026-02-28"}
    ]
  },
  "reference": {
    "app8_current": {...},
    "app8_history": [...]
  }
}

实现要点:

  • assistant_infov_dim_assistant + v_dws_assistant_salary_calc 获取
  • service_historyv_dwd_assistant_service_log 按助教+客户筛选
  • customer_data.system_data 复用 member_data.fetch_member_consumption_data()
  • customer_data.notesbiz.notes 获取该客户的全部备注
  • reference 从 ai_cache 获取 app8 最新 + 最近 2 套历史

3.3 应用 5话术参考

结构与应用 4 基本一致,额外增加 task_suggestion 字段(应用 4 的返回结果)。

实现要点:

  • 复用应用 4 的 assistant_info + service_history + customer_data 获取逻辑
  • task_suggestion 从应用 4 的 run() 返回值传入(调用链:应用 4 → 应用 5

3.4 应用 6备注分析

{
  "current_time": "2026-03-08 14:30:25",
  "current_note": {
    "content": "客户说下周要带朋友来打球",
    "recorded_by": "张助教",
    "created_at": "2026-03-08 14:25:00"
  },
  "reference": {
    "member_nickname": "王先生",
    "consumption_data": { /* 同应用 3  main_data */ },
    "all_notes": [...],
    "app3_clues": [...],
    "app8_history": [...]
  }
}

实现要点:

  • current_note 从触发上下文获取(备注提交事件传入)
  • consumption_data 复用 member_data.fetch_member_consumption_data()
  • all_notesbiz.notes 获取所有助教对该客户的全部备注
  • reference 从 ai_cache 获取 app3 + app8 历史

3.5 应用 7客户分析

{
  "current_time": "2026-03-08 14:30:25",
  "member_id": 12345,
  "member_nickname": "王先生",
  "objective_data": { /* 同应用 3  main_data */ },
  "subjective_data": {
    "notes": [
      {"recorded_by": "张助教", "content": "...", "created_at": "..."}
    ]
  },
  "reference": {
    "app8_current": {...},
    "app8_history": [...]
  }
}

实现要点:

  • objective_data 复用 member_data.fetch_member_consumption_data()
  • subjective_data.notesbiz.notes 获取全部备注,标注创建者
  • 主观信息需在 Prompt 中标注【来源XXX请甄别信息真实性】
  • reference 从 ai_cache 获取 app8 最新 + 最近 2 套历史

3.6 应用 1页面上下文文本化

应用 1 的 _build_page_context()_build_source_context() 需要根据 source_page 类型,调用对应的数据获取函数并格式化为文本。

实现要点:

  • 每个页面类型对应一个文本化函数
  • 文本化输出为结构化中文描述(非 JSON便于 AI 理解
  • 数据量控制:每个页面上下文不超过 2000 字符,避免 token 浪费
  • 敏感信息脱敏:不传入 member_phone 等断档字段

四、数据库审查

4.1 数据获取涉及的表

数据获取函数 涉及表 连接方式
fetch_member_consumption_data v_dwd_settlement_head, v_dwd_table_fee_log, v_dwd_store_goods_sale, v_dwd_recharge_order, v_dim_member_card_account, v_dws_member_consumption_summary, v_dws_member_visit_detail FDW
fetch_assistant_info v_dim_assistant, v_dws_assistant_salary_calc FDW
fetch_service_history v_dwd_assistant_service_log, v_dws_member_assistant_relation_index, v_dws_member_assistant_intimacy FDW
build_page_text 以上全部 + biz.coach_tasks, biz.notes, biz.ai_cache, public.member_retention_clue FDW + 业务库

4.2 无需新建表

本 SPEC 不需要新建数据库表。所有数据获取基于 NS1 已建立的 FDW 映射和 P4/P5-A 已建立的业务表。

4.3 性能考虑

  • fetch_member_consumption_data 涉及 7 张 FDW 表查询,建议:
    • 消费记录限制最近 3 个月WHERE settle_date >= NOW() - INTERVAL '3 months'
    • 单次查询最多返回 100 条记录
    • 考虑使用 NS1 中建议的 biz.task_detail_cache 缓存聚合结果
  • 页面文本化(应用 1需要实时获取数据建议设置 5 秒查询超时

五、调用链与数据流

5.1 消费事件链

新结算单到达
  → 应用 3.build_prompt(member_data) → 百炼 API → ai_cache
    → 应用 8.run() → member_retention_clue
      → 应用 7.build_prompt(member_data + notes) → 百炼 API → ai_cache
      → 应用 4.build_prompt(assistant_data + member_data) → 百炼 API → ai_cache
        → 应用 5.build_prompt(app4_result) → 百炼 API → ai_cache

5.2 备注提交事件链

备注提交
  → 应用 6.build_prompt(note + member_data) → 百炼 API → ai_cache
    → 应用 8.run() → member_retention_clue

5.3 应用 1 对话流

用户点击 AI 入口
  → 前端传入 source_page + context_data
  → 后端 build_page_text(source_page, context_data)
  → 拼接为首条 user message
  → SSE 流式调用百炼 API

六、参考文档

文档 路径 用途
P5 AI 集成 spec docs/prd/specs/P5-miniapp-ai-integration.md Prompt JSON 结构定义、调用链时序
API 契约 docs/miniprogram-dev/API-contract.md 接口响应格式(决定数据结构)
DWD-DOC 标杆 docs/reports/DWD-DOC/ 金额口径、字段语义权威参考
AI 应用骨架代码 apps/backend/app/ai/apps/app*.py 当前骨架实现
百炼客户端 apps/backend/app/ai/bailian_client.py API 调用封装
缓存服务 apps/backend/app/ai/cache_service.py ai_cache 读写
NS1 接口设计 docs/prd/Neo_Specs/NS1-xcx-backend-api.md 后端数据结构参考

七、预审查清单SPEC 启动前确认)

7.1 数据结构

  1. 消费记录字段范围consumption_records 中每条记录需要包含哪些字段是否需要包含折扣信息discount_manual/discount_other是否需要包含支付方式明细balance_pay/cash_pay/online_pay
  2. 服务记录字段范围service_history 中每条记录需要包含哪些字段是否需要包含台桌类型room_category和客户评价
  3. 备注内容截断all_notes 中每条备注是否需要全文传入?长备注是否截断?截断长度?
  4. 会员卡明细粒度member_cards 是否需要包含卡号、开卡日期、有效期等详细信息,还是只需要卡类型和余额?

7.2 Prompt 优化

  1. Token 预算:每个应用的首条 Prompt 的 token 上限是多少?百炼 API 的单次请求 token 限制?
  2. 数据时间窗口:消费记录默认取近 3 个月,是否需要可配置?不同应用是否需要不同时间窗口?
  3. 空数据处理:当客户无消费记录/无备注/无服务历史时Prompt 如何处理?是否需要特殊提示词?

7.3 页面文本化(应用 1

  1. 文本化格式:页面上下文是输出为结构化中文文本还是 JSONAI 对哪种格式理解更好?
  2. 数据量控制:每个页面上下文的字符上限?是否需要根据页面类型动态调整?
  3. 实时性要求:应用 1 的页面上下文是否需要实时获取最新数据?还是可以使用缓存(如 task_detail_cache

7.4 性能与安全

  1. FDW 查询并发多个数据获取函数是否可以并发执行asyncio.gatherFDW 连接池是否支持?
  2. 数据脱敏:传入百炼 API 的数据中哪些字段需要脱敏member_phone 已断档不传,还有其他敏感字段吗?
  3. 错误降级:某个数据获取函数失败时(如 FDW 超时),是否跳过该部分继续生成 Prompt还是整体失败

八、任务清单草案SPEC 细化后调整)

Batch A共享数据获取层

  • T1创建 data_fetchers/member_data.py(客户消费数据获取,应用 3/6/7 共用)
  • T2创建 data_fetchers/assistant_data.py(助教信息 + 服务历史获取,应用 4/5 共用)
  • T3创建 data_fetchers/page_context.py(页面上下文文本化框架,应用 1 专用)

Batch BPrompt 拼接实现

  • T4完善 app3_clue.pybuild_prompt()(客户消费数据 → 维客线索分析)
  • T5完善 app4_analysis.pybuild_prompt()(助教+客户数据 → 关系分析)
  • T6完善 app5_tactics.pybuild_prompt()(复用应用 4 数据 + task_suggestion
  • T7完善 app6_note.pybuild_prompt()(备注+客户数据 → 备注分析)
  • T8完善 app7_customer.pybuild_prompt()(客户全量数据 → 运营策略)

Batch C应用 1 页面文本化 + 联调

  • T9实现各页面类型的文本化函数task-detail/customer-detail/board-*/performance 等)
  • T10补充 app1_chat.py_build_page_context() 调用文本化函数
  • T11端到端联调触发事件 → Prompt 拼接 → 百炼调用 → 缓存写入 → 前端展示)