Files
Crawl_demo/backend/app/services/ai_insight.py
2026-03-18 18:57:58 +08:00

74 lines
2.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.
from __future__ import annotations
from typing import Any
import httpx
from ..settings import settings
def _rule_based_summary(query: str, retrieved: list[dict[str, Any]]) -> dict[str, Any]:
top = retrieved[:3]
bullets = []
for r in top:
pid = r.get("product_id") or r.get("id") or "-"
title = r.get("title") or ""
follow = r.get("follow_score")
life = r.get("lifecycle")
bullets.append(f"- {pid} {title}(跟卖指数={follow} 生命周期={life}")
return {
"mode": "rules_only",
"query": query,
"retrieved": retrieved,
"answer": "基于当前向量库/指标的规则摘要:\n" + "\n".join(bullets),
}
def generate_insight(query: str, product_id: str | None, top_k: int) -> dict[str, Any]:
"""
这里先做“可运行的最小闭环”:
- 向量检索(尚未实现时返回空)
- 有 OPENAI_API_KEY 则调用 LLM输出结构化建议
- 否则返回规则引擎摘要
"""
# TODO: 接入向量库检索Milvus/Azure 等)。先保留协议,保证前端可用。
retrieved: list[dict[str, Any]] = []
if not settings.openai_api_key:
return _rule_based_summary(query, retrieved)
prompt = f"""你是电商数据分析与选品决策助手。
用户问题:{query}
请输出一个“发现爆款 -> 数据验证 -> 决策跟卖”的闭环建议,包含:
1) 结论摘要3-5条
2) 数据证据(引用关键指标:销量/增速/竞争/生命周期)
3) 风险点与反例至少3条
4) 可执行动作(选品、备货、投流、供应链)
如果没有足够数据,请明确说明缺口,并给出最小补充数据清单。
"""
headers = {"Authorization": f"Bearer {settings.openai_api_key}"}
payload = {
"model": settings.openai_model,
"input": prompt,
}
try:
with httpx.Client(timeout=30.0) as client:
r = client.post("https://api.openai.com/v1/responses", headers=headers, json=payload)
r.raise_for_status()
data = r.json()
text = ""
for item in data.get("output", []):
for c in item.get("content", []):
if c.get("type") in ("output_text", "text"):
text += c.get("text", "")
return {"mode": "llm", "query": query, "retrieved": retrieved, "answer": text.strip()}
except Exception as e:
out = _rule_based_summary(query, retrieved)
out["mode"] = "rules_fallback"
out["error"] = str(e)
return out