62 lines
2.6 KiB
Python
62 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from collections.abc import Iterator
|
|
from typing import Any
|
|
|
|
from backend.llm import transport as llm_transport
|
|
|
|
|
|
class ReviewAssistantError(RuntimeError):
|
|
pass
|
|
|
|
|
|
def stream_review_assistant(
|
|
context: dict[str, Any],
|
|
question: str,
|
|
history: list[dict[str, str]],
|
|
api_key: str,
|
|
base_url: str,
|
|
model: str,
|
|
timeout: int = 120,
|
|
) -> Iterator[str]:
|
|
if not api_key or not model:
|
|
raise ReviewAssistantError("智能解读服务尚未配置。")
|
|
messages = [{"role": "system", "content": _system_prompt(context)}]
|
|
messages.extend(history[-12:])
|
|
messages.append({"role": "user", "content": question})
|
|
try:
|
|
yield from llm_transport.stream_chat_completion(
|
|
api_key=api_key,
|
|
base_url=base_url,
|
|
model=model,
|
|
messages=messages,
|
|
timeout=timeout,
|
|
user_agent="XiaobaiReviewWeb/1.0",
|
|
)
|
|
except llm_transport.OpenAIEmptyResponseError as exc:
|
|
raise ReviewAssistantError("智能解读未返回有效内容。") from exc
|
|
except llm_transport.OpenAIHTTPError as exc:
|
|
raise ReviewAssistantError(f"智能解读服务暂不可用({exc.code})。") from exc
|
|
except llm_transport.OpenAITransportError as exc:
|
|
raise ReviewAssistantError("智能解读连接中断,请稍后重试。") from exc
|
|
|
|
|
|
def _system_prompt(context: dict[str, Any]) -> str:
|
|
context_json = json.dumps(context, ensure_ascii=False, separators=(",", ":"))
|
|
return f"""
|
|
你是“小白复盘”的统一复盘助手。你负责把网页中已经存在的市场统计、策略跟踪、提醒、复盘笔记和手工交易日志连接起来,帮助用户复盘和形成下一步观察计划。
|
|
|
|
最高优先级规则:
|
|
1. 只能使用下方“网页复盘数据”,数据缺失就明确说明,不得补造行情、交易或胜率。
|
|
2. 不自动下单,不声称已执行任何操作,不修改策略、提醒、笔记或交易日志。
|
|
3. 不承诺收益,不给无条件买卖指令。建议必须写成条件、失效条件和风险边界。
|
|
4. 区分市场事实、用户记录和你的推断。引用数字时写明数据日期。
|
|
5. 优先结合用户自己的策略跟踪与交易日志寻找可验证的重复模式;样本不足时明确标注。
|
|
6. 使用中文,先直接回答,再给数据依据和下一步观察。避免空泛口号,不展示模型、接口或内部工程信息。
|
|
7. 控制在 800 个中文字符以内,除非用户明确要求展开。
|
|
|
|
网页复盘数据:
|
|
{context_json}
|
|
""".strip()
|