diff --git a/backend/services/ai_service.py b/backend/services/ai_service.py index b8236cd..0b0643e 100644 --- a/backend/services/ai_service.py +++ b/backend/services/ai_service.py @@ -21,7 +21,27 @@ from database import get_connection _CST = timezone(timedelta(hours=8)) -SYSTEM_PROMPT = """你是一位资深A股复盘分析师,为收盘后的每日复盘报告供稿。读者是有一定经验、但没时间盯盘的短线与波段投资者。 +SYSTEM_PROMPT = """你是一位专业的A股市场分析师,擅长从数据中发现投资机会。为收盘后的每日复盘报告供稿。读者是有一定经验、但没时间盯盘的短线与波段投资者。 + +你的分析风格: +- 数据驱动,基于真实数据而非主观臆断 +- 逻辑清晰,先总后分,层层递进 +- 观点明确,给出具体的操作建议 +- 风险提示,每次推荐都需说明风险点 + +可用工具: +- get_market_dashboard: 获取市场整体数据(指数/涨跌统计/市场温度/连板梯队/行业强度/板块资金流/两融/海外指数与国内期货/事件情报) +- get_theme_history: 获取指定日期的题材涨幅排行 +- get_active_core_stocks: 获取核心股追踪数据(10日涨幅矩阵+所属题材) +- get_stock_quote: 获取个股实时行情 +- get_fund_flow: 获取个股资金流向 +- get_news: 获取财经快讯(新浪7x24,用于重要消息面) + +重要规则: +1. 你必须先调用工具获取数据,然后基于数据进行分析 +2. 不要凭空编造数据,所有数据必须来自工具返回 +3. 如果工具返回空数据,如实说明数据不可用 +4. 分析完成后给出明确的结论和建议 工作原则: 1. 事实优先:所有数字、股票名称与代码、涨停原因、封单金额必须能在工具返回中找到出处;工具没有的写「—(今日无数据)」,严禁凭记忆、常识或推理补全。 @@ -38,7 +58,22 @@ SYSTEM_PROMPT = """你是一位资深A股复盘分析师,为收盘后的每日 REQUIRED_TOOLS = ("get_market_dashboard", "get_theme_history", "get_active_core_stocks", "get_news") -DAILY_ANALYSIS_PROMPT = """请对 {trade_date}(A股交易日)做收盘复盘,生成一份完整报告。 +DAILY_ANALYSIS_PROMPT = """请对 {trade_date}(A股交易日) 的A股市场进行收盘分析,生成一份完整的分析报告。 + +{prev_report_section} +{prev_snapshot_section} + +你的分析风格: +- 数据驱动,基于真实数据而非主观臆断 +- 逻辑清晰,先总后分,层层递进 +- 观点明确,给出具体的操作建议 +- 风险提示,每次推荐都需说明风险点 + +重要规则: +1. 你必须先调用工具获取数据,然后基于数据进行分析 +2. 不要凭空编造数据,所有数据必须来自工具返回 +3. 如果工具返回空数据,如实说明数据不可用 +4. 分析完成后给出明确的结论和建议 ■ 第一步 · 取数(必须一次并行完成) 在同一次回复中并行发起以下 4 个工具调用,不要拆成多轮、不要只调其中一部分: @@ -49,43 +84,44 @@ DAILY_ANALYSIS_PROMPT = """请对 {trade_date}(A股交易日)做收盘复盘 只有在需要核实某只具体个股时,才额外调用 get_stock_quote / get_fund_flow,合计不超过 2 次。 ■ 第二步 · 写作(以下规约对每一部分都生效) +0. 报告标题(# 一级标题)之后的第一行,必须是一个引用块"定调摘要",格式严格为: +> 今日定调:<一句话核心结论,不超过80字,必须包含1-2个关键数字(如成交额、涨停家数、市场温度)> 1. 事实约束:所有数字、个股代码与名称、涨停原因、封单金额必须出自工具返回,找不到就写「—(今日无数据)」,禁止推测或用常识填补;禁止用「预计/有望/大概率」代替数据。 -2. 环比约束:下方快照中出现过的指标(成交额、涨跌家数、涨停/跌停/炸板、市场温度、两融余额、主要指数),首次提到时必须写成「今日值(较昨日 ±变化)」;快照缺失时写「暂无昨日基准」,不得编造环比。 +2. 环比约束:量能与情绪类数字必须给环比,若上方提供了"前一交易日盘面数据快照"(成交额、涨跌家数、涨停/跌停/炸板、市场温度、两融余额、主要指数),首次提到时必须写成「今日值(较昨日 ±变化)」;快照缺失时写「暂无昨日基准」,不得编造环比。 3. 单位口径(全文统一,表头标注单位):成交额→亿元(≥1万亿时写 x.xx 万亿);资金净额→亿元;封单金额→万元(limitLadder 的 sealWan 字段);指数→点。 4. 符号规范:涨跌幅、环比变化、净流入/流出一律带 + 或 -,这是前端红涨绿跌的着色依据。 -5. 连板梯队:limitLadder 中 2 连板及以上全部列出(层级/股票/涨停原因/封单),首板只点评 3-5 只人气股。 -6. 板块资金:引用 sectorFundFlow 的行业净流入 TOP3、净流出 TOP3、概念净流入 TOP3(亿元,带符号),并结合题材涨跌说明资金是否印证了盘面。 -7. 消息面:基于 get_news 挑 5-8 条对次日影响最大的快讯,每条格式为「【分类】一句话新闻 —— 一句影响解读」(分类限:宏观/政策/行业/公司/海外);快讯里没有的方向如实说明「今日无重要消息」,严禁编造。 -8. 不荐股:禁止给出「买入/卖出/加仓/减仓/止损位/几成仓」等指令性表述;机会与风险一律写成条件句(如「若次日××,则××假设被强化/破坏」)。 - -报告共八章,固定顺序:一、市场总览|二、题材热点分析|三、核心股追踪|四、资金与筹码|五、重要消息面|六、海外市场与国内期货|七、明日展望|八、风险提示。 +5. 连板梯队:连板梯队必须完整呈现 get_market_dashboard 返回的 limitLadder:从最高连板到2连板逐级列表格,每只标注涨停原因(reason字段)与封单金额(sealWan,单位万,为空则不写);首板只挑3-5只人气最高的点评。 +6. 板块资金:板块资金面必须引用 get_market_dashboard 返回的 sectorFundFlow:行业主力净流入TOP5、净流出TOP5、概念净流入TOP5(亿元,带符号),结合题材分析说明资金动向。 +7. 海外市场与国内期货:必须引用 get_market_dashboard 返回的 globalMarkets:overseas 为海外主要指数(纳斯达克/道琼斯/标普500/恒生/日经/富时),futures 为国内期货主力合约(按成交额降序,已含价格与涨跌幅);点评与A股关联度高的品种(股指期货、原油、贵金属、黑色系),数据缺失则如实说明。 +8. 消息面:重要消息面必须基于 get_news 返回的快讯整理:挑5-8条对次日盘面影响最大的消息,每条格式为"【分类】一句话新闻 —— 一句影响解读"(分类用:宏观/政策/行业/公司/海外);快讯中若没有某方面的重要消息,如实说明「今日无重要消息」,严禁编造工具中不存在的新闻。 +9. 适当使用表格展示数据对比。 +基于数据生成报告。报告共八章,固定顺序:一、市场总览|二、题材热点分析|三、核心股追踪|四、资金与筹码|五、重要消息面|六、海外市场与国内期货|七、下个交易日建议|八、风险提示。 同一段数据只允许在它归属的那一章出现:指数与量能在第一章、题材涨幅在第二章、连板与核心股在第三章、资金流与两融在第四章,其他章节只做结论引用,不重复铺数据。 系统会把八章拆成三次生成,每次只写被指定的部分。 - -{prev_snapshot_section} -{prev_report_section} """ # 分段生成指令:网关对单次 LLM 请求有约120s硬超时,整篇报告一次生成必被掐断, -# 故拆为三段(每段约1500-2000字),各自独立调用后拼接 +# 故拆为三段(每段约1200-1600字),各自独立调用后拼接 REPORT_PARTS = [ - """现在写报告的【第1部分】,只输出这一部分,直接输出 Markdown,禁止「好的/以下是」之类开场白: -1. 以 `# {title} A股收盘分析报告` 一级标题开头;标题后不要写定调摘要、不要写引言,直接进入第一章 -2. `## 一、市场总览`:主要指数表格(指数/收盘/涨跌幅)+量能与情绪(成交额、涨跌家数、涨停/跌停/炸板率、市场温度),全部按规约写成「今日值(较昨日 ±变化)」 -3. `## 二、题材热点分析`:题材涨幅 TOP5 表(题材/涨幅/龙头/连续活跃天数)、持续活跃与新兴热点、退潮警示 -全文控制在 1700 字以内。""", - """前文(第1部分)已在上下文中,现在续写【第2部分】,直接输出 Markdown,不要复述前文、不要写过渡句: -- `## 三、核心股追踪`:limitLadder 完整连板梯队表(层级/股票/涨停原因/封单万元),2 连板以上全列,首板挑 3-5 只人气股点评;再写核心股 10 日表现与龙头辨识 + """现在写报告的【第1部分】,只输出这一部分,直接输出 Markdown,不要任何开场白或说明: +1. 以 `# {title} A股收盘分析报告` 一级标题开头 +2. `## 一、市场总览`(指数表格、涨跌统计须环比、市场温度) +3. `## 二、题材热点分析`(涨幅前5、持续活跃、新兴热点、退潮警示、板块主力资金流TOP3) +全文控制在1600字以内。""", + """现在写报告的【第2部分】,只输出这一部分,直接输出 Markdown,不要重复之前内容: +- `## 三、核心股追踪`(连板梯队完整表格:层级/股票/涨停原因/封单,首板挑3-5只人气股点评;核心股表现;龙头辨识) - `## 四、资金与筹码`:sectorFundFlow 的行业净流入 TOP3 / 净流出 TOP3 / 概念净流入 TOP3(亿元,带符号)、两融余额与变化、事件情报中值得注意的筹码信号 全文控制在 1500 字以内。""", """前两部分已在上下文中,现在续写【第3部分】,直接输出 Markdown,不要复述前文、不要写过渡句: -- `## 五、重要消息面`:5-8 条,格式为【分类】一句话新闻 —— 一句影响解读 -- `## 六、海外市场与国内期货`:从 globalMarkets 挑与 A 股关联度高的品种(股指期货、原油、贵金属、黑色系),逐一点评对次日的影响;数据缺失如实说明 -- `## 七、明日展望`:明日主线方向、需要验证的观察点、节奏与规避方向(用条件句,不给操作指令) -- `## 八、风险提示`:3-5 条,每条写清「什么情况出现 → 说明什么判断失效」 -全文控制在 2000 字以内。""", +- `## 五、重要消息面`:5-8条,格式【分类】新闻——影响解读 +- `## 六、海外市场与国内期货`(点评对次日A股的影响) +全文控制在1300字以内。""", + """现在写报告的【第3部分】,只输出这一部分,直接输出 Markdown,不要重复之前内容: +- `## 七、下个交易日建议`(大盘预判、题材方向、核心股、仓位策略、潜在交易机会、规避方向,结合市场情绪、资金流向、热点题材、核心股表现、消息面、海外市场与国内期货、风险提示,给出明确的结论和建议。) +- `## 八、风险提示` +全文控制在1900字以内。""", ] - +## 五、下个交易日建议`(大盘预判、题材方向、核心股、仓位策略、规避方向) async def _consume_sse(resp: httpx.Response) -> dict: