Stock Agent AI 模型的选股器实现 [七]

10 - 第八步:深度分析与记忆

普通报告只做「技术+消息+财报+期权 → LLM 综合 → 10 项」;深度模式 会在此基础上再跑「五类深度分析」、做「与上次对比」,并对综合评分做一次 LLM 微调,结果会写入持久化「记忆」供下次对比。本篇讲五类分析是什么、与上次对比怎么实现、以及记忆存在哪里、怎么用。


一、深度模式在整体里的位置

  • 触发 :请求 Report 时传 deep=1,例如 /report?deep=1&limit=5。
  • 流程 :对每只股票不再只调 run_full_analysis,而是调 run_one_ticker_deep_report(ticker),其内部会:
    1. 先跑一次 run_full_analysis,得到「综合评分 + 10 项」的卡片基础。
    2. 再跑 五类深度分析(基本面深度、护城河、同行对比、空头视角、叙事变化),每类由 LangChain 链 + LLM 完成。
    3. 从 memory_store 取出该标的「上次」同类型分析(若有),做 与上次对比(大方向是否一致、近期趋势等)。
    4. 用五段深度摘要的短文 (每段截前约 200 字)再调一次 LLM,对当前综合评分做 微调 (输出「最终评分:N」或「调整:+1/0/-1」),更新卡片上的 score。
    5. 把五类摘要、对比结论、微调后的评分等写回卡片;同时把本次深度结果 写入 memory_store,供下次「与上次对比」用。

若未安装 LangChain 或链执行失败,深度块会显示「深度摘要未生成」或错误信息,但综合评分和普通卡片仍会保留。


二、五类深度分析分别是什么

  1. 基本面深度:收入与增长质量、盈利能力、现金流、商业模式、中长期风险等;基于财报与公司信息,由链里的 LLM 按模板输出。
  2. 护城河 :技术/切换成本/网络效应/规模/品牌等壁垒;Prompt 在 agents/prompts 或 chains/chains 中。
  3. 同行对比:与若干同行在增速、盈利、估值等方面的差异;需要指定 peers(或默认一批),由链拉数据 + LLM 对比。
  4. 空头视角:增长可持续性、替代风险、估值风险、下跌触发点等;Prompt 引导模型从「看空」角度写。
  5. 叙事变化:财报与话术变化、市场叙事是否改变;基于近期信息由 LLM 概括。

每类分析的结果会存进 memory_store (按 ticker + analysis_type),并截取一段写入报告卡片的「深度」区块;同时取每段前约 200 字拼成短文,用于评分微调的那次 LLM 调用。


三、与上次对比怎么实现

  • 数据来源 :chains/memory_store。每次深度分析完成后,会把当次结果 append 到 data/memory/memory_store.jsonl(或环境变量 STOCK_AGENT_MEMORY_DIR 指定目录)。
  • 检索 :按 ticker + analysis_type(如 fundamental_deep、moat、peers 等)从 JSONL 里读最近 N 条(如 2 条),按时间倒序。
  • 对比:把「上次」同类型分析的文本(或摘要)拼进 Prompt,让 LLM 回答「大方向是否一致、近期趋势如何」等,输出写入卡片的「与上次对比(大方向)」「近期对比趋势」等字段。
  • 首次或无历史:若没有该标的该类型的往期记录,对比区块会显示「首次运行或尚无历史记录,再次运行 deep=1 后将显示与上次对比」之类提示。

也就是说:记忆是按「标的 + 分析类型」存的,不是按「用户会话」;对比是「同一只股票、同一类分析、上次 vs 这次」。


四、评分微调(_adjust_score_by_deep)

  • 输入:当前综合评分(1~10)、五类深度分析的摘要(每段截前约 200 字)。
  • Prompt:大意是「根据下面五段深度摘要,对当前评分做微调;只输出一行:要么『最终评分:N』(N 为 1~10 整数),要么『调整:+1 或 0 或 -1』」。
  • 解析:若匹配到「最终评分:N」,则最终分 = clamp(N, 1, 10);若匹配到「调整:±1」,则最终分 = 原分 + 调整量再 clamp。
  • 失败:若 LLM 未返回有效格式或调用异常,则保留原综合评分,不强制改分。

实现位置:agents/report_deep._adjust_score_by_deep;调用方在 run_one_ticker_deep_report 里,在五类深度和对比都跑完后执行。


五、memory_store 存什么、怎么用

  • 存什么 :每行一条 JSON,包含 ticker、analysis_type、content(分析结果全文或序列化后的字符串)、ts(时间戳)。
  • 写入 :由 LangChain 链在完成某类分析后调用 memory_store.save(ticker, analysis_type, content),追加到 JSONL 文件。
  • 读取 :memory_store.retrieve(ticker, analysis_type=None, last_n=2),按 ticker(和可选 analysis_type)取最近 last_n 条,用于「与上次对比」和上下文摘要。
  • 存储目录 :默认 data/memory/;可通过环境变量 STOCK_AGENT_MEMORY_DIR 指定其它目录。

项目没有 用向量库或语义检索,记忆是「按 key(ticker + type)取最近几条」,不是「按相似问题检索」;若要做 RAG,可参考 docs/RAG文档建立与数据来源.md,把历史摘要等再做 embedding 存向量库。


六、小结与代码位置

  • 深度入口 :agents/report_deep.run_one_ticker_deep_report(ticker)
  • 五类链 :chains/chains(如 chain_fundamental_deep、chain_moat、chain_peers、chain_short、chain_narrative 等),可由 chain_full_deep 或类似组合一次跑完;深度分析可配置为并行(DEEP_PARALLEL=1)以缩短耗时。
  • 与上次对比 :chains 里调用 memory_store.retrieve 拿到上次结果,再调 run_comparison 或等价逻辑生成对比文本。
  • 评分微调 :agents/report_deep._adjust_score_by_deep
  • 记忆读写 :chains/memory_store.save、retrieve

下一步:11 - 配置与扩展 ------ 环境变量、模型切换、RAG/OpenClaw 等扩展思路。

11 - 配置与扩展

本篇汇总常用配置方式(环境变量、模型与后端、报告行为),并简要说明如何扩展(RAG、OpenClaw/IM 等),方便按需调参和二次开发。


一、环境变量(常用)

变量 含义 默认
OLLAMA_MODEL Ollama 模型名 qwen2.5:3b
LLM_BACKEND 后端:ollama / deepseek / openai 无 key 时为 ollama
DEEPSEEK_API_KEY DeepSeek API Key ---
OPENAI_API_KEY OpenAI API Key ---
LLM_TEMPERATURE 采样温度,越低输出越稳定 0.3
LLM_MAX_TOKENS 单次回复最大 token 不设
LLM_TIMEOUT 请求超时(秒) 120
DEEP_PARALLEL 深度分析是否并行,0=顺序 1
STOCK_AGENT_MEMORY_DIR 记忆存储目录(JSONL) 项目下 data/memory
  • 本地免费 :不设任何 API Key,默认用 Ollama;需先安装 Ollama 并拉取模型,例如 ollama pull qwen2.5:3b。
  • 换模型 :export OLLAMA_MODEL=qwen2.5:7b 再启动;或设 DEEPSEEK_API_KEY / OPENAI_API_KEY 并设 LLM_BACKEND=deepseek / openai。
  • 调行为 :温度、max_tokens 等在 config/llm_config.py 中可读环境变量,llm.ask_llm 会使用这些默认值。

二、模型与后端(llm.py)

  • Ollama :base_url=http://localhost:11434/v1,无需 API Key;模型名由 OLLAMA_MODEL 控制。
  • DeepSeek :设 DEEPSEEK_API_KEY,base_url=https://api.deepseek.com,常用模型如 deepseek-chat。
  • OpenAI :设 OPENAI_API_KEY,模型如 gpt-4o-mini;若用第三方兼容 API,需在代码里改 base_url。

选择逻辑:优先看 LLM_BACKEND;若未设则根据「已配置的 Key」推断(有 DeepSeek key 且未指定 ollama 则用 DeepSeek,以此类推)。

超时、连接错误、429/401 等会在 llm.py 里转成可读的 RuntimeError 提示(如「请先启动 Ollama」「API 配额不足」等)。


三、报告与 Prompt 可调点

  • 综合 Prompt 的 10 项格式与说明 :在 agents/full_analysis._build_prompt 里,可改角色描述、时间范围描述、以及 10 项的说明文字。
  • 深度分析 Prompt 模板 :在 agents/prompts 与 chains/chains 里,可改各类深度问题的表述。
  • 报告 HTML 与筛选 :report/build_html.py 里可改标题样式、筛选项、排序选项、评分定性映射(_score_interpretation)等。
  • 选股池与代码规范 :config/tickers.py 里可增删静态列表、改 get_report_tickers 逻辑(例如接动态接口)。

四、扩展方向(简要)

  • RAG :把历史报告摘要、新闻摘要、财报解读等做成文档,切块后做 embedding 存向量库(如 Chroma);分析时按「标的/行业/问题」检索 TopK 再拼进 Prompt。思路与数据来源见 docs/RAG文档建立与数据来源.md。
  • OpenClaw / iMessage :通过外部消息(如「帮我跑一份报告发到微信」)触发报告生成或推送;安装与接入步骤见 docs/OpenClaw安装与iMessage(imsg)接入.md、docs/OpenClaw集成说明.md。
  • 更多数据源:研报、公告、宏观数据等需自行对接 API 或爬虫;可在对应 agent(如 news、fundamental)或新建模块中拉取,再拼进 Prompt 或单独展示。
  • 多轮对话记忆 :当前记忆是「按标的+分析类型」的 JSONL,不是「按用户会话」的对话历史;若要「连续问答」形态,可在此基础上加 LangChain 的 ConversationBufferWindowMemory 等,与现有 memory_store 并存。

五、小结

  • 配置 :环境变量控制模型、后端、超时、温度、深度是否并行、记忆目录;config/llm_config 与 llm.py 是入口。
  • 扩展:RAG、OpenClaw、新数据源、对话记忆等都有文档或代码入口可循;按需选一块先做最小可行再迭代。

本系列博客到这里告一段落;若你希望某一块再拆成「更细的步骤」或「带代码片段」,可以指定章节再补一篇。

相关推荐
蜗牛互联网3 分钟前
Python + JSON Schema 实现工单结构化输出与本地复核
java·人工智能·后端
华微软件5 分钟前
华微软件 AI 领域新增一项国家发明专利
人工智能
MoRanzhi120316 分钟前
第 3 篇 · 数据清洗与特征工程:从问题判定到特征构建
python·pandas·数据清洗·特征工程·缺失值处理·异常值检测·特征编码
jimmyleeee28 分钟前
大模型安全之四十五:从数据到输出----GenAI 版权、知识产权与伦理合规实战指南
人工智能·深度学习·安全
loulanyue_30 分钟前
构建实时沉浸式世界模型体验:AI+IP与商业模式重构——读Reactor首席技术官Bryce 2026云栖专场演讲
人工智能·重构
面包狗AI4S30 分钟前
【AI4S】生化环材高可信技术与产业周报(2026-10-03—2026-10-09)
人工智能·深度学习·机器学习·ai
前端大斗师32 分钟前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
刘科领35 分钟前
使用ollama & openweb-ui 本地搭建自己的AI
人工智能·python·ui·ai
专业程序开发源36 分钟前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计
夜雪一千37 分钟前
Python 生成模拟地址数据:Faker之外的备选库
网络·windows·python