Initial commit: stock analysis backend and prototype UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-13 02:26:22 +08:00
commit 8de37d5c2d
25 changed files with 4624 additions and 0 deletions

42
backend/llm.py Normal file
View File

@@ -0,0 +1,42 @@
"""大模型客户端OpenAI 兼容接口)。
未配置 LLM_API_KEY 时 enabled() 返回 False调用方应走规则降级。
"""
from __future__ import annotations
import requests
import config
def enabled() -> bool:
return bool(config.LLM_API_KEY)
def chat(messages, temperature: float = 0.5, max_tokens: int = 900) -> str:
"""调用 chat/completions。失败抛异常由上层捕获降级。"""
if not enabled():
raise RuntimeError("LLM 未配置")
url = config.LLM_BASE_URL.rstrip("/") + "/chat/completions"
headers = {"Authorization": f"Bearer {config.LLM_API_KEY}", "Content-Type": "application/json"}
payload = {"model": config.LLM_MODEL, "messages": messages,
"temperature": temperature, "max_tokens": max_tokens, "stream": False}
r = requests.post(url, json=payload, headers=headers, timeout=config.LLM_TIMEOUT)
r.raise_for_status()
data = r.json()
return data["choices"][0]["message"]["content"].strip()
SYSTEM_PROMPT = (
"你是一名专业的A股市场分析师擅长复盘、个股诊断与题材分析。"
"你的结论必须严格基于用户提供的结构化数据,不臆造未提供的数字。"
"语言简洁专业,使用中文。涉及操作建议时必须同时给出风险提示,"
"并说明这不构成投资建议。"
)
def ask(user_content: str, temperature: float = 0.5, max_tokens: int = 900) -> str:
return chat([
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_content},
], temperature=temperature, max_tokens=max_tokens)