Files
Neo-ZQYY/apps/backend/app/ai/prompts/app2_finance_prompt.py
2026-03-15 10:15:02 +08:00

146 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""应用 2 财务洞察 Prompt 模板。
构建包含当期和上期收入结构的完整 Prompt供百炼 API 生成财务洞察。
收入字段映射(严格遵守 items_sum 口径):
- table_fee = table_charge_money台费
- assistant_pd = assistant_pd_money陪打费
- assistant_cx = assistant_cx_money超休费
- goods = goods_money商品收入
- recharge = 充值 pay_amount settle_type=5充值收入
禁止使用 consume_money统一使用
items_sum = table_charge_money + goods_money + assistant_pd_money
+ assistant_cx_money + electricity_money
"""
from __future__ import annotations
import json
def build_prompt(context: dict) -> list[dict]:
"""构建 App2 财务洞察 Prompt 消息列表。
Args:
context: 包含以下字段:
- site_id: int门店 ID
- time_dimension: str时间维度编码
- current_data: dict当期数据
- previous_data: dict上期数据
Returns:
messages 列表system + user供 BailianClient.chat_json 调用
"""
site_id = context.get("site_id", 0)
time_dimension = context.get("time_dimension", "")
current_data = context.get("current_data", {})
previous_data = context.get("previous_data", {})
system_content = _build_system_content(
site_id=site_id,
time_dimension=time_dimension,
current_data=current_data,
previous_data=previous_data,
)
user_content = (
f"请根据以上数据,为门店 {site_id} 生成 {_dimension_label(time_dimension)} 的财务洞察分析。"
"以 JSON 格式返回,包含 insights 数组,每项含 seq序号、title标题、body正文"
)
return [
{"role": "system", "content": json.dumps(system_content, ensure_ascii=False)},
{"role": "user", "content": user_content},
]
def _build_system_content(
*,
site_id: int,
time_dimension: str,
current_data: dict,
previous_data: dict,
) -> dict:
"""构建 system prompt JSON 结构。"""
return {
"task": (
"你是台球门店的财务分析 AI 助手。"
"根据提供的当期和上期经营数据,生成结构化的财务洞察。"
"分析维度包括:收入结构变化、各收入项占比、环比趋势、异常波动。"
"输出 JSON 格式:{\"insights\": [{\"seq\": 1, \"title\": \"...\", \"body\": \"...\"}]}"
),
"data": {
"site_id": site_id,
"time_dimension": time_dimension,
"time_dimension_label": _dimension_label(time_dimension),
"current_period": _build_period_data(current_data),
"previous_period": _build_period_data(previous_data),
},
"reference": {
"field_mapping": {
"items_sum": (
"table_charge_money + goods_money + assistant_pd_money"
" + assistant_cx_money + electricity_money"
),
"table_fee": "table_charge_money台费收入",
"assistant_pd": "assistant_pd_money陪打费",
"assistant_cx": "assistant_cx_money超休费",
"goods": "goods_money商品收入",
"recharge": "充值 pay_amountsettle_type=5充值收入",
"electricity": "electricity_money电费当前未启用全为 0",
},
"rules": [
"统一使用 items_sum 口径计算营收总额",
"助教费用必须拆分为 assistant_pd_money陪打和 assistant_cx_money超休",
"支付渠道恒等式balance_amount = recharge_card_amount + gift_card_amount",
"金额单位CNY保留两位小数",
],
},
}
def _build_period_data(data: dict) -> dict:
"""构建单期数据结构,确保字段名遵守 items_sum 口径。"""
return {
# 收入结构items_sum 口径)
"table_charge_money": data.get("table_charge_money", 0),
"goods_money": data.get("goods_money", 0),
"assistant_pd_money": data.get("assistant_pd_money", 0),
"assistant_cx_money": data.get("assistant_cx_money", 0),
"electricity_money": data.get("electricity_money", 0),
# 充值收入
"recharge_income": data.get("recharge_income", 0),
# 储值资产
"balance_pay": data.get("balance_pay", 0),
"recharge_card_pay": data.get("recharge_card_pay", 0),
"gift_card_pay": data.get("gift_card_pay", 0),
# 费用汇总
"discount_amount": data.get("discount_amount", 0),
"adjust_amount": data.get("adjust_amount", 0),
# 平台结算
"platform_settlement_amount": data.get("platform_settlement_amount", 0),
"groupbuy_pay_amount": data.get("groupbuy_pay_amount", 0),
# 汇总
"order_count": data.get("order_count", 0),
"member_count": data.get("member_count", 0),
}
# 时间维度编码 → 中文标签
_DIMENSION_LABELS: dict[str, str] = {
"this_month": "本月",
"last_month": "上月",
"this_week": "本周",
"last_week": "上周",
"last_3_months": "近三个月",
"this_quarter": "本季度",
"last_quarter": "上季度",
"last_6_months": "近六个月",
}
def _dimension_label(dimension: str) -> str:
"""将时间维度编码转为中文标签。"""
return _DIMENSION_LABELS.get(dimension, dimension)