
很多人以为“用大模型分析股票”就是把行情数据贴进对话框然后问一句“现在该买还是该卖”。这个想法不能说错但离一个可用的系统还差得很远。真正的股票分析系统不是一段提示词而是一整套数据管道行情数据从哪里来、清洗成什么结构、大模型以什么方式读取、分析结果如何组织成报告最后还要能定时运行、能部署、能看日志。这篇文章想给你一个明确判断用大模型构建一个专属股票分析系统真正的技术门槛不在于大模型本身而在于 AI 编程落地时的工程化能力。数据获取、存储、模型调用、结果展示、部署维护每一层都有坑。而 FDEFrontend Deployment Engineer / 全流程部署工程实践视角恰好能帮助我们把这些环节串成一个完整闭环。读完本文你会得到一套可直接运行的“数据 大模型 可视化”股票分析系统包含完整的 Python 代码、大模型调用方法和部署步骤。即使你还没有实测过任何大模型 API也可以按照本文的路径先搭出一个能跑的最小系统再逐步替换成你熟悉的数据源和模型。1. 这篇文章真正要解决的问题1.1 大模型分析股票的常见误区先聊一个很常见的场景。很多开发者第一次接触大模型时都会做一个“股票分析助手”把一段 K 线数据贴给模型让模型给出买卖建议。结果往往不尽如人意原因主要有三个。第一大模型没有实时行情能力。市面上绝大多数大模型是基于静态训练数据训练的它的“知识”截止时间有限无法知道今天的收盘价。如果不给模型提供实时数据它只能依靠记忆中的“模糊印象”来回答产生一本正经的胡说八道。第二提示词缺少数据约束。直接把行情表格粘贴进对话框模型并不知道哪些列是开盘价、哪些列是成交量。即使知道也可能在解读时自行发挥。要想让模型输出准确的分析需要用结构化的提示词规定数据字典、分析角色、输出格式还要明确要求模型“只能使用提供的数据不能臆测数据”。第三没有形成系统。单次对话式分析只能得到零散结论无法沉淀历史分析记录也无法每天自动更新。而一个股票分析系统的价值在于每天收盘后自动拉取数据、生成报告、更新可视化看板。这背后是工程化能力不是单纯的大模型提示词能力。1.2 适合谁读不适合谁读这篇文章适合三类读者正在学习 AI 编程想做一个有真实业务场景项目的开发者。有一定 Python 基础想把大模型 API 接入实际应用的工程师。需要为团队搭建内部投研分析工具但又不想从零开始设计架构的产品或研发同学。如果你是想通过这篇文章找到“稳赚不赔的炒股公式”那我建议你直接关掉页面。任何分析系统都只是辅助工具不构成投资建议。本文的重点是把数据处理、模型调用、系统部署的工程链路讲清楚。2. FDE 与 AI 编程为什么这次实战值得做2.1 从“写提示词”到“交付系统”FDE 是近年来 AI 应用领域里出现频率很高的词汇。从实际工作内容看它并不是一个单一的岗位名称而是一种工程能力的集合负责把大模型能力接入业务系统打通数据链路完成前后端逻辑并保障系统可以稳定部署和运行。传统的 AI 应用开发往往聚焦在模型训练和算法调优上。而现在大模型时代大部分应用不需要你重新训练模型更多的工作量在“怎么把模型能力用好”。这时候 FDE 的能力就变得非常重要它要求开发者能够理解模型 API 的调用方式能够处理输入输出格式能够设计可靠的提示词更要把这些能力封装成一个可以被业务使用的服务。AI 编程工具的出现进一步拉低了系统搭建的门槛。过去写一套带前端页面的数据应用需要掌握后端框架、前端框架、数据库操作等多套技能。而现在通过 AI 编程助手和脚手架工具一个熟悉业务逻辑的开发者也可以快速生成可运行的代码。这也是为什么“FDE 工程师”会成为一个热门关键词行业需要的不是会写 prompt 的人而是能通过 AI 编程把应用交付上线的人。2.2 FDE 视角下的关键技术点在股票分析系统这个项目里FDE 视角要求我们关注以下关键技术点模型接入层的抽象设计。不能把具体的模型厂商写死在代码里而应该设计成可配置的接口方便在本地模型、云端 API、开源模型之间切换。数据层的容错处理。股票行情数据源可能限流、断线、字段变化系统必须有重试和降级方案。结果展示层的交互设计。分析报告要直观图表要考虑涨跌颜色、时间范围、指标展示等细节。部署运维的自动化。至少要做到“一条命令启动环境”“环境变量管理密钥”“日志可查看”。这些工作看起来琐碎但正是从“Demo”走向“可用系统”的关键。很多时候一个 AI 应用“能跑”和“能用”是两回事。2.3 为什么用 Python Streamlit 起步技术选型上这个项目最友好的组合是 Python 加 Streamlit。原因如下Python 生态成熟akshare、tushare、pandas、openai 等库都是现成的。Streamlit 只需要写少量代码就能生成可视化页面适合快速搭建数据看板。同一个 Python 环境里可以直接调用大模型 SDK不需要额外搭建前后端服务。当然如果后续需要面向更多用户开放可以把 Streamlit 替换成 FastAPI 后端加 Vue/React 前端。但这是后话我们先跑通最小闭环。3. 方案设计与技术选型3.1 系统分层一个完整的股票分析系统我建议分成五层数据采集层负责从数据源拉取股票历史行情、基础信息。数据存储层将采集到的数据落地到数据库避免重复请求外部接口。分析引擎层调用大模型根据行情数据和预设的分析框架生成分析报告。展示交互层通过 Web 页面展示行情走势、技术指标、分析结论。部署运维层通过 Docker、定时任务、环境变量等方式保证系统可运行、可维护。分层的意义在于每一层都可以独立替换。比如今天用 akshare明天想换 tushare只需要修改数据采集层今天用云端大模型 API明天想切换成本地部署的开源模型只需要修改分析引擎层的客户端配置。3.2 各层选型及理由分层选型建议理由数据采集层akshare / tushare / 自建爬虫akshare 免费接口丰富tushare 更稳定但需要积分本文以 akshare 为例数据存储层SQLite文件型数据库零配置适合个人项目和小型团队分析引擎层OpenAI 兼容 API / 本地部署的 DeepSeek、Qwen 等兼容协议意味着更换模型时只需改 base_url 和 api_key展示交互层Streamlit代码量少支持图表和 Markdown 渲染部署运维层Docker GitHub Actions / 云服务器定时任务环境一致性自动化部署3.3 数据合规与免责说明使用行情数据时需要注意数据源的使用条款。akshare 等开源接口的数据来自公开渠道但部分数据可能受版权保护仅限个人学习研究使用。如果用于商业系统请购买合规的数据服务。另外要强调本文输出的系统只做“分析展示”不自动下单、不提供投资建议。任何基于该系统的决策风险由使用者自行承担。涉及金融场景的安全红线宁可不做也不要越界。4. 环境准备与前置条件4.1 基础环境开始之前你需要准备以下环境Python 3.10 或更高版本建议 3.10兼容性更好。pip 包管理工具。一个能访问外网的数据源akshare 的某些接口需要网络。一个大模型 API Key支持 OpenAI 兼容协议的服务均可。版本说明请以实际安装版本为准本文重点演示通用思路不绑定特定版本号。4.2 安装依赖建议先创建虚拟环境再安装依赖# 创建并激活虚拟环境 python -m venv stock_env source stock_env/bin/activate # Windows 下使用 stock_env\Scripts\activate然后安装核心依赖pip install akshare pandas streamlit openai python-dotenv plotly如果需要使用 tushare 作为备选数据源可以额外安装pip install tushare安装完成后可以用以下命令验证关键依赖是否可用python -c import akshare as ak; print(ak.__version__) python -c import streamlit as st; print(st.__version__)如果 akshare 安装失败通常是因为网络源问题可以切换 pip 镜像源后重试。4.3 配置大模型 API Key在项目根目录创建.env文件用于存放敏感配置touch .env文件内容如下# 大模型 API 配置 LLM_API_KEYyour-api-key-here LLM_BASE_URLhttps://your-llm-service.com/v1 LLM_MODELyour-model-name # 股票数据配置 DEFAULT_STOCK_CODE600519 DEFAULT_STOCK_NAME贵州茅台关于LLM_BASE_URL如果你使用的是国内大模型平台通常平台会提供一个兼容 OpenAI 的接口地址如果你使用本地部署的模型服务如通过 vLLM、Ollama 等工具启动也可以填写本地服务的地址。这里只做通用配置示例具体以你的模型服务商文档为准。注意.env文件一定不要提交到 Git 仓库。建议在.gitignore中添加.env __pycache__/ *.pyc .venv/ venv/5. 核心流程拆解5.1 初始化项目结构我们采用模块化方式组织代码这样每个文件职责单一后续也好扩展。项目结构如下stock_analyzer/ ├── .env ├── .gitignore ├── config.py # 全局配置 ├── data_loader.py # 数据采集与缓存 ├── analyzer.py # 大模型分析逻辑 ├── app.py # Streamlit 界面 └── requirements.txt5.2 数据获取数据获取是整个系统的起点。这里有两个容易踩的坑。第一个坑是重复请求。如果每次打开页面都实时请求数据源接口一方面速度慢另一方面容易被限流。解决方案是加一层本地缓存第一次拉取数据后存入 SQLite后续优先读取本地数据。第二个坑是数据结构不统一。akshare 返回的 DataFrame 列名通常是中文而 tushare 返回的是英文字段。为了后续分析方便我们统一转成英文列名形成标准结构字段含义date交易日期open开盘价close收盘价high最高价low最低价volume成交量amount成交额5.3 数据清洗与存储拿到原始数据后需要做基础清洗日期列转成 datetime 类型并排序。删除全为空值的行。数值列转为 float防止后续计算出错。保存到 SQLite 表stock_daily中。存储逻辑可以简单设计为“先查询该股票在本地已有多少条数据如果数据量太少或日期不是最新再触发增量更新”。这样既能节省外部接口请求次数又能保证数据时效性。5.4 调用大模型生成分析报告这是整个系统里最核心、也最容易出问题的一步。很多人直接写一句“请分析这只股票”得到的报告往往泛泛而谈。想要更专业的输出需要在提示词里做好三件事。第一明确模型角色。给它一个“量化分析师”的角色设定说明任务目标。第二提供结构化数据。把最近一段时间的关键行情数据整理成表格并说明字段含义。第三限定输出格式。要求模型分模块输出包含趋势判断、支撑位与压力位、量价关系、风险提示。同时要求模型基于提供的数据说话不允许编造数据。此外超时处理也很重要。大模型接口调用可能因为网络波动或上下文过长而失败代码里要加 try/except并设置合理超时时间。5.5 报表展示与交互展示层用 Streamlit 完成主要包含三个区域参数区股票代码、日期范围、模型开关。行情区K 线图、成交量图。分析区调用大模型生成的分析报告以 Markdown 形式渲染。Streamlit 的好处是一旦数据更新页面可以自动刷新适合做每日收盘后的分析看板。6. 完整示例代码下面给出一个可以直接运行的完整项目。文件路径与说明如下。6.1 requirements.txtpandas akshare streamlit openai python-dotenv plotly保存到项目根目录后执行pip install -r requirements.txt完成依赖安装。6.2 config.py# 文件路径stock_analyzer/config.py import os from dotenv import load_dotenv load_dotenv() LLM_API_KEY os.getenv(LLM_API_KEY, ) LLM_BASE_URL os.getenv(LLM_BASE_URL, ) LLM_MODEL os.getenv(LLM_MODEL, ) # 默认分析股票 DEFAULT_STOCK_CODE os.getenv(DEFAULT_STOCK_CODE, 600519) DEFAULT_STOCK_NAME os.getenv(DEFAULT_STOCK_NAME, 贵州茅台) # 本地 SQLite 数据库文件 DB_PATH os.path.join(os.path.dirname(__file__), stock_data.db)6.3 data_loader.py# 文件路径stock_analyzer/data_loader.py import sqlite3 import pandas as pd from config import DB_PATH def init_db(): 初始化数据库表结构 conn sqlite3.connect(DB_PATH) conn.execute( CREATE TABLE IF NOT EXISTS stock_daily ( stock_code TEXT, date TEXT, open REAL, close REAL, high REAL, low REAL, volume REAL, amount REAL, PRIMARY KEY (stock_code, date) ) ) conn.commit() conn.close() def fetch_stock_data(stock_code: str, start_date: str, end_date: str) - pd.DataFrame: 从 akshare 获取历史行情数据。 如果 akshare 不可用或接口变更可以替换成 tushare 或读取本地 CSV。 try: import akshare as ak # 注意akshare 接口名称和返回字段可能随版本变化请以实际版本为准。 df ak.stock_zh_a_hist( symbolstock_code, perioddaily, start_datestart_date.replace(-, ), end_dateend_date.replace(-, ), adjustqfq, ) df.rename( columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume, 成交额: amount, }, inplaceTrue, ) df df[[date, open, close, high, low, volume, amount]] return df except Exception as e: print(f[fetch_stock_data] akshare 获取失败: {e}) return pd.DataFrame() def load_from_db(stock_code: str, start_date: str, end_date: str) - pd.DataFrame: 从本地数据库加载数据 conn sqlite3.connect(DB_PATH) query SELECT date, open, close, high, low, volume, amount FROM stock_daily WHERE stock_code ? AND date BETWEEN ? AND ? ORDER BY date df pd.read_sql_query(query, conn, params(stock_code, start_date, end_date)) conn.close() return df def save_to_db(stock_code: str, df: pd.DataFrame): 将数据写入本地数据库存在则更新 if df.empty: return conn sqlite3.connect(DB_PATH) df df.copy() df[stock_code] stock_code df.to_sql(stock_daily, conn, if_existsappend, indexFalse) conn.execute( DELETE FROM stock_daily WHERE rowid NOT IN ( SELECT MIN(rowid) FROM stock_daily GROUP BY stock_code, date ) ) conn.commit() conn.close() def get_stock_data(stock_code: str, start_date: str, end_date: str) - pd.DataFrame: 对外统一数据入口优先读本地库如果本地数据不足再从远端获取。 init_db() local_df load_from_db(stock_code, start_date, end_date) if len(local_df) 30: return local_df remote_df fetch_stock_data(stock_code, start_date, end_date) if remote_df.empty: # 如果远端不可用退回本地数据 return local_df save_to_db(stock_code, remote_df) return remote_df这段代码里有一个实用技巧get_stock_data优先读 SQLite只有当本地数据量不足时才请求外部接口。这样做既提升了页面加载速度也避免高频调用数据源导致限流。6.4 analyzer.py# 文件路径stock_analyzer/analyzer.py import json from openai import OpenAI from config import LLM_API_KEY, LLM_BASE_URL, LLM_MODEL def build_analysis_prompt(stock_name: str, stock_code: str, df) - str: 构建结构化的分析提示词 recent_df df.tail(60) table_md recent_df.to_markdown(indexFalse) prompt f 你是一位拥有 10 年经验的量化分析师。请根据以下 {stock_name}{stock_code}的近期行情数据从技术分析角度给出专业分析报告。 数据说明 - date: 交易日期 - open: 开盘价 - close: 收盘价 - high: 最高价 - low: 最低价 - volume: 成交量 - amount: 成交额 - 数据单位已经统一请直接使用数值分析。 行情数据 {table_md} 要求 1. 只能使用上述数据不得编造或猜测数据。 2. 分以下五个部分输出趋势判断、支撑位与压力位、量价关系、技术指标观察、风险提示。 3. 语言专业、克制不做收益承诺。 4. 最后用三句话总结核心观点。 return prompt def generate_stock_report(stock_name: str, stock_code: str, df) - str: 调用大模型生成分析报告 if not LLM_API_KEY or not LLM_BASE_URL: return 未配置大模型 API Key 或 Base URL请在 .env 文件中补充。 client OpenAI(api_keyLLM_API_KEY, base_urlLLM_BASE_URL) prompt build_analysis_prompt(stock_name, stock_code, df) try: response client.chat.completions.create( modelLLM_MODEL, messages[ {role: system, content: 你是一位严谨的量化分析师只依据给定数据分析。}, {role: user, content: prompt}, ], temperature0.3, max_tokens2000, timeout60, ) return response.choices[0].message.content except Exception as e: return f大模型调用失败{str(e)}这里我把temperature设置成 0.3目的是让模型输出更稳定、更少发散。timeout60可以有效避免接口长时间无响应导致页面卡死。如果你没有使用openai库也可以直接使用requests发送 HTTP 请求逻辑类似。关键是保持base_url和api_key可配置。6.5 app.py# 文件路径stock_analyzer/app.py import streamlit as st import plotly.graph_objects as go from datetime import date, timedelta from config import DEFAULT_STOCK_CODE, DEFAULT_STOCK_NAME from data_loader import get_stock_data from analyzer import generate_stock_report st.set_page_config(page_titleAI 股票分析系统, layoutwide) st.title(AI 股票分析系统) st.caption(本系统仅用于技术研究与学习不构成任何投资建议。) # 侧边栏参数 with st.sidebar: st.header(参数设置) stock_code st.text_input(股票代码, valueDEFAULT_STOCK_CODE) stock_name st.text_input(股票名称, valueDEFAULT_STOCK_NAME) end_date st.date_input(结束日期, valuedate.today()) start_date st.date_input(开始日期, valuedate.today() - timedelta(days180)) run_analysis st.button(生成分析报告) # 数据加载 df get_stock_data(stock_code, start_date.strftime(%Y-%m-%d), end_date.strftime(%Y-%m-%d)) if df.empty: st.warning(未获取到行情数据请检查股票代码或数据源是否可用。) st.stop() st.subheader(行情走势) # K线图 fig go.Figure( data[ go.Candlestick( xdf[date], opendf[open], highdf[high], lowdf[low], closedf[close], nameK线, ) ] ) fig.update_layout( titlef{stock_name}{stock_code}日K线, xaxis_title日期, yaxis_title价格, xaxis_rangeslider_visibleFalse, ) st.plotly_chart(fig, use_container_widthTrue) # 成交量 volume_fig go.Figure( data[ go.Bar( xdf[date], ydf[volume], name成交量, marker_colorrgba(100, 149, 237, 0.6), ) ] ) volume_fig.update_layout(title成交量, xaxis_title日期, yaxis_title成交量) st.plotly_chart(volume_fig, use_container_widthTrue) # 大模型分析 if run_analysis: with st.spinner(大模型正在分析请稍候...): report generate_stock_report(stock_name, stock_code, df) st.subheader(AI 分析报告) st.markdown(report) else: st.info(点击左侧“生成分析报告”按钮调用大模型生成分析。)到这里一个最小可用的股票分析系统就完成了。从数据获取到页面展示大概只有不到 300 行代码。这也正是 AI 编程时代的特点搭建一个业务 Demo 的成本越来越低难的是让它在真实环境里稳定运行。7. 运行结果与效果验证7.1 启动步骤在项目根目录执行streamlit run app.py启动成功后终端会输出类似下面的信息You can now view your Streamlit app in your browser. Local URL: http://localhost:8501 Network URL: http://192.168.1.100:8501打开浏览器访问http://localhost:8501即可看到系统页面。7.2 预期输出页面顶部显示“AI 股票分析系统”标题。K 线图和成交量图正常渲染。点击“生成分析报告”后等待几秒到几十秒页面会展示大模型生成的 Markdown 分析报告。首次运行如果本地数据库为空系统会从 akshare 拉取数据并写入 SQLite之后再次访问时页面加载速度会明显变快。7.3 失败时第一检查点如果运行过程中遇到问题建议按以下顺序排查看终端日志Streamlit 会在终端输出 Python 异常信息这通常是定位问题的第一手材料。检查.env文件是否配置正确尤其是LLM_API_KEY和LLM_BASE_URL。检查网络akshare 数据源依赖网络如果无法访问外部接口可以先用本地 CSV 文件作为数据源。检查依赖版本如果akshare接口返回的列名与预期不符可以打印df.columns查看实际字段。8. 常见问题与排查思路问题现象可能原因排查方式解决方案页面提示“未获取到行情数据”股票代码错误或数据源接口限流查看终端日志确认 akshare 请求是否报错更换正确代码等待接口恢复改用本地 CSV 数据大模型报告一直空白或卡住API Key 配置错误、网络超时、模型名称不支持检查.env配置单独写一个测试脚本调用接口换用服务商提供的示例模型名增加超时时间分析报告内容与行情数据不一致提示词太模糊模型自行发挥检查提示词是否明确“只能使用提供的数据”强化提示词中的数据字典约束K 线图不显示plotly 版本不兼容或日期列格式错误打印df.dtypes检查 date 列类型将日期列转为 datetime 类型并更新 plotly 版本数据库文件占用导致写入失败多个进程同时访问 SQLite查看错误日志中的 database is locked 提示设置连接超时或改用单进程定时任务写入部署到服务器后无法访问页面云服务器安全组未开放端口检查安全规则和防火墙开放 8501 端口或使用反向代理映射域名这里最容易忽略的是“SQLite 被锁”的问题。Streamlit 在多人访问时可能会触发多进程并发写入虽然个人项目很少遇到但一旦遇到就会导致页面报错。如果后续需要支持团队使用建议把存储层换成 PostgreSQL 或 MySQL同时增加数据库连接池。9. 工程化与安全建议9.1 提示词与数据安全大模型提示词本质上是发送给第三方服务的代码。如果你的分析系统里包含敏感数据务必注意数据脱敏。在股票分析场景行情数据本身不敏感但如果你后续扩展了更多业务数据比如持仓、资金账户这些数据不能直接放进提示词而是要先做脱敏处理或者干脆不提供给模型。保护用户隐私和数据安全比分析结果的准确性优先级更高。另外提示词本身也可能被注入。如果用户输入股票名称时包含恶意指令理论上可能影响模型输出。建议对用户输入做基本过滤并让提示词中的指令优先级高于用户输入内容。9.2 API 成本控制大模型 API 是按 token 计费的分析长周期行情时尤其要注意成本。一个实际经验是不要每次打开页面都调用模型而是在用户点击“生成分析报告”时才调用并在前端加缓存。比如把最近一次分析结果保存到 SQLite 或本地文件设置缓存有效期当天不重复生成。这样既能减少 API 费用也能避免频繁调用导致限流。如果你使用本地部署的开源模型虽然没有按 token 计费的问题但要注意 GPU 资源占用。建议把模型服务与分析系统分离开通过 HTTP 接口调用避免模型加载影响 Web 服务性能。9.3 部署与回滚个人开发者部署到云服务器时推荐使用 Docker 保证环境一致性。一个简单的 Dockerfile 可以这样写FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . EXPOSE 8501 CMD [streamlit, run, app.py, --server.port8501, --server.address0.0.0.0]构建并启动docker build -t stock-analyzer . docker run -d --name stock-analyzer -p 8501:8501 --env-file .env stock-analyzer生产环境部署前一定要先在小流量环境验证。如果要更新代码建议先构建新镜像再切换容器保留旧版本方便回滚。金融类应用对稳定性要求更高任何数据源或模型服务的变更都要谨慎。9.4 日志与监控日志是排查问题的第一手信息简单项目至少要做到记录数据采集成功或失败的时间、股票代码。记录大模型调用的状态码、耗时、返回摘要。记录页面访问错误。如果项目规模变大可以把日志接入 ELK 或云日志服务但初期用 Python 的logging模块即可。不要把日志输出到终端后就不管要定期查看及时发现数据源异常或模型服务波动。10. 总结与后续方向至此你已经从零搭建了一个“数据获取 本地存储 大模型分析 可视化展示”的股票分析系统。这套系统的核心价值不是那几句提示词而是数据管道和工程化结构数据能缓存模型能替换页面能交互部署有方案。下一步你可以从以下几个方向继续深入增加定时任务每天收盘后自动更新数据和报告变成无人值守的每日分析系统。扩展多股票对比分析通过 Streamlit 的多选组件实现同行业股票横向比较。接入本地部署的开源模型让整个分析链路完全可控不依赖外部 API。在提示词中引入更多技术指标比如 MACD、RSI、布林带让分析更细化。将关键指标存入数据库并追加历史记录积累一段时间后可以对比模型历史判断与实际走势的偏差。坦白说这只是一个开始。股票分析系统背后涉及的金融知识、数据质量和模型能力每一项都需要长期积累。但作为 AI 编程实战项目它已经够典型有真实数据、有外部 API、有存储设计、有 Web 展示、有部署问题。如果你能把这套系统的每一层都跑通再去做其他 AI 应用会发现很多经验是可以平移的。建议先照着本文代码跑一遍再把数据源换成你熟悉的接口模型换成你常用的服务慢慢沉淀成自己的工具。