🎯 核心目标:从 "AI Demo" 到 "AI 产品化" - Claude 专注于解释、综合、推理,不参与原始计算 - 真实数据 (Tushare) + AI 解释层完整集成 ✨ 新增功能: 1. Claude AI 服务层 - claude_service.py: Claude API 封装 - Prompt 模板系统:角色固化 + 数据注入 + 指令分离 - 5 个核心功能:市场概览、推荐解释、问答、策略对比、评分解释 2. 增强数据服务 - enhanced_data_service.py: Tushare 真实数据集成 - 市场背景数据:情绪、板块、资金流、新闻情绪 - 推荐增强:基本面、技术面、AI 预测详情 3. AI 增强 API - /api/ai/recommendations/explained: 带 AI 解释的推荐 - /api/ai/market/overview: AI 市场深度分析 - /api/ai/ask: AI 问答接口 - /api/ai/stock/{symbol}/explain: 单股解释 - /api/ai/strategies/compare: 策略对比 4. Prompt 模板文档 - claude_stock_analysis.md (150+ 行) - System Prompt 设计原则 - 数据 Schema 完整定义 - Task Instructions 示例 - 使用示例代码 5. 生产架构文档 - AI_PRODUCTION_ARCHITECTURE.md (500+ 行) - 系统架构图 - 数据流说明 - API 端点清单 - 成本估算与优化策略 - 部署流程 - 故障排查指南 📦 依赖更新: - 新增 anthropic==0.39.0 (Claude API SDK) 🏗️ 架构亮点: - 三层分离:数据计算 | AI 解释 | UI 交互 - 缓存优化:Redis TTL 5-10 分钟 - 成本控制:Token 压缩 + 模型分级 - 安全性:输入校验 + 输出验证 📊 API 成本: - Dashboard 概览: $0.006/次 - 股票解释: $0.015/次 - 用户问答: $0.001/次 (Haiku) - 月成本估算: ~$520 (日活 1000 人) 🔮 技术栈: Frontend: Vue 3 + Canvas + SVG Backend: FastAPI + Claude 4.5 + Tushare Data: PostgreSQL + Redis ML: LightGBM + XGBoost 🚀 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
16 KiB
16 KiB
AI Stock Recommendation System - Production Architecture
🎯 系统目标
从 "AI Demo" 到 "AI 产品化",核心跃迁:
Claude 不是来算指标的,而是来解释、综合、推理和交互的。
🏗️ 系统架构
总体架构图
┌─────────────────────────────────────────────────────────────┐
│ Frontend (Vue 3 + Vite) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ DashboardV2 (Enhanced) │ │
│ │ ├─ HeroSectionEnhanced (动画 + 雷达图) │ │
│ │ ├─ MarketPulseEnhanced (仪表盘 + 趋势图) │ │
│ │ ├─ StockCard (评分 + 可视化) │ │
│ │ └─ AIDock (AI 问答) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ HTTP/WebSocket
┌─────────────────────────────────────────────────────────────┐
│ Backend (FastAPI + Python) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ API Layer │ │
│ │ ├─ /api/recommendations (传统推荐) │ │
│ │ ├─ /api/ai/recommendations/explained (AI 增强) │ │
│ │ ├─ /api/ai/market/overview (AI 市场分析) │ │
│ │ ├─ /api/ai/ask (AI 问答) │ │
│ │ └─ /api/ai/strategies/compare (策略对比) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Service Layer │ │
│ │ ├─ ClaudeStockAnalyzer (AI 解释层) │ │
│ │ ├─ EnhancedDataService (数据采集 + 特征工程) │ │
│ │ ├─ StockRecommender (ML 推荐引擎) │ │
│ │ └─ CacheService (Redis 缓存) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Data Sources │ │
│ │ ├─ Tushare API (实时行情 + 基本面) │ │
│ │ ├─ PostgreSQL (历史数据 + 用户数据) │ │
│ │ ├─ Redis (缓存 + 会话) │ │
│ │ └─ Claude API (自然语言分析) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
📊 数据流
1. 推荐生成流程
Step 1: 数据采集 (EnhancedDataService)
├─ Tushare → 获取实时行情、基本面数据
├─ PostgreSQL → 读取历史价格、技术指标
└─ 计算特征工程 (MA, RSI, MACD, PE分位数, PB分位数)
↓
Step 2: 模型预测 (StockRecommender)
├─ LightGBM → 收益率预测
├─ XGBoost → 风险评估
├─ 多模型集成 → 综合评分 (0-100)
└─ 置信度计算 → 基于模型一致性
↓
Step 3: Claude AI 解释 (ClaudeStockAnalyzer)
├─ 输入: 推荐结果 + 市场背景
├─ System Prompt: 固化角色(解释器,非计算器)
├─ Task Prompt: 注入数据 + 指令
└─ 输出: 自然语言解释 + 结构化 JSON
↓
Step 4: 缓存 & 返回 (CacheService + API)
├─ Redis 缓存 (TTL: 5 分钟)
├─ 前端轮询 / WebSocket 推送
└─ Dashboard 渲染
🧠 Claude AI Integration
核心原则
-
职责分离
- 数据计算:后端 Python (pandas, LightGBM)
- 自然语言解释:Claude API
- UI 交互:前端 Vue
-
Prompt 设计
- System Prompt:固化角色,禁止编造数据
- Data Injection:动态注入真实数据
- Instruction:明确输出格式(JSON / Markdown)
-
成本优化
- 只传必要字段给 Claude
- 每次最多 10 支股票分析
- 使用 Claude 3.5 Haiku 做简单任务
- Redis 缓存 Claude 响应(5 分钟)
Prompt 模板架构
# 1. System Prompt (固化角色)
system_prompt = """
你是一名资深 AI 投资分析师。
- 禁止编造数据
- 专注解释、推理、交互
- 输出结构化 JSON
"""
# 2. Data Context (注入真实数据)
data_context = {
"market_context": {...}, # 市场背景
"recommendations": [...] # 推荐股票
}
# 3. Task Instruction (指令)
task = """
请解释推荐理由,要求:
1. 基本面 + 技术面 + 资金面
2. 适合的投资策略
3. 风险提示
4. JSON 格式输出
"""
# 4. 调用 Claude
response = claude.messages.create(
model="claude-sonnet-4",
system=system_prompt,
messages=[{"role": "user", "content": data_context + task}]
)
📁 文件结构
stock/
├── frontend/
│ ├── src/
│ │ ├── views/
│ │ │ └── DashboardV2.vue # 主页面
│ │ ├── components/
│ │ │ ├── HeroSectionEnhanced.vue # 动画 KPI
│ │ │ ├── MarketPulseEnhanced.vue # 市场脉搏
│ │ │ ├── StockCard.vue # 股票卡片
│ │ │ └── AIDock.vue # AI 问答
│ │ ├── services/
│ │ │ └── api.js # API 调用
│ │ └── App.vue # CSS 变量
│ ├── Dockerfile
│ └── nginx.conf
│
├── backend/
│ ├── api/
│ │ ├── recommendations.py # 传统推荐 API
│ │ └── ai_recommendations.py # AI 增强 API ⭐
│ ├── services/
│ │ ├── claude_service.py # Claude 服务 ⭐
│ │ ├── enhanced_data_service.py # 数据服务 ⭐
│ │ ├── recommender.py # ML 推荐引擎
│ │ └── cache_service.py # Redis 缓存
│ ├── prompts/
│ │ └── claude_stock_analysis.md # Prompt 模板 ⭐
│ ├── models/
│ │ └── database.py # 数据库模型
│ ├── Dockerfile
│ ├── requirements.txt # 增加 anthropic
│ └── main.py # FastAPI 入口
│
├── docs/
│ ├── DASHBOARD_V2_README.md
│ ├── DASHBOARD_V3_OPTIMIZATION.md
│ ├── AI_PRODUCTION_ARCHITECTURE.md # 本文件 ⭐
│ └── QUICK_ACCESS.txt
│
├── docker-compose.yml
└── README.md
🔧 技术栈
Frontend
- 框架: Vue 3.3.4 (Composition API)
- 构建: Vite 5.0.2
- 状态: Vuex 4
- 路由: Vue Router 4
- 可视化: Canvas 2D + SVG
- 样式: CSS Variables + 原生 CSS
Backend
- 框架: FastAPI 0.104.1
- 数据库: PostgreSQL 16
- 缓存: Redis 7
- ML: LightGBM, XGBoost, scikit-learn
- 数据源: Tushare (A股数据)
- AI: Anthropic Claude 4.5 Sonnet ⭐
Infrastructure
- 容器: Docker + Docker Compose
- Web 服务器: Nginx (前端)
- ASGI 服务器: Uvicorn (后端)
- 数据库管理: Adminer
🚀 部署流程
1. 环境配置
# .env 文件
ANTHROPIC_API_KEY=sk-ant-xxxxx
TUSHARE_TOKEN=your_tushare_token
DATABASE_URL=postgresql://user:pass@postgres:5432/stock
REDIS_URL=redis://redis:6379/0
2. 构建 & 启动
# 构建所有服务
docker-compose build
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f backend
3. 验证
# 检查服务状态
docker-compose ps
# 测试 AI API
curl http://localhost:8001/api/ai/market/overview
# 访问前端
open http://localhost:8090
📊 API 端点
传统推荐 API
GET /api/recommendations
→ 返回基于 ML 的推荐列表
GET /api/market/analysis
→ 返回市场技术分析
AI 增强 API ⭐
GET /api/ai/recommendations/explained
→ 推荐列表 + Claude 解释
GET /api/ai/market/overview
→ 市场数据 + Claude 深度分析
POST /api/ai/ask
Body: {"question": "为什么推荐浦发银行?", "symbol": "600000"}
→ Claude 问答响应
GET /api/ai/stock/{symbol}/explain
→ 单支股票的 AI 评分解释
GET /api/ai/strategies/compare
→ 策略对比分析
💰 成本估算
Claude API 调用成本
| 场景 | 模型 | Token/次 | 成本/次 | 日调用量 | 日成本 |
|---|---|---|---|---|---|
| Dashboard 概览 | Sonnet 4.5 | ~2K | $0.006 | 1000 | $6 |
| 股票解释 | Sonnet 4.5 | ~5K | $0.015 | 500 | $7.5 |
| 用户问答 | Haiku 3.5 | ~1K | $0.001 | 2000 | $2 |
| 策略对比 | Sonnet 3.5 | ~3K | $0.009 | 200 | $1.8 |
月成本估算: ~$520 (假设日活 1000 人)
优化策略
- Redis 缓存: TTL 5 分钟,减少 80% 重复请求
- 批量处理: 多用户共享同一次 Claude 调用
- 模型降级: 简单任务用 Haiku,复杂任务用 Sonnet
- Token 压缩: 只传必要字段,删除冗余数据
🔒 安全性
1. API Key 管理
# 不要硬编码
api_key = os.getenv("ANTHROPIC_API_KEY")
# 使用 Secret Manager (生产环境)
# api_key = get_secret("anthropic_api_key")
2. 输入校验
# 防止 Prompt Injection
def sanitize_user_input(text: str) -> str:
"""清理用户输入,防止 Prompt 注入"""
# 移除可能的注入指令
forbidden = ["ignore previous", "system:", "assistant:"]
for pattern in forbidden:
text = text.replace(pattern, "")
return text[:500] # 限制长度
3. 输出校验
def validate_claude_response(response: dict) -> bool:
"""验证 Claude 输出"""
# 检查必需字段
required = ["summary", "stocks"]
if not all(field in response for field in required):
return False
# 检查数值合理性
for stock in response.get("stocks", []):
if stock.get("score", 0) > 100:
return False
return True
📈 性能优化
1. 缓存策略
# 市场概览缓存 5 分钟
@cache(ttl=300, key="market_overview")
async def get_market_overview():
...
# 股票推荐缓存 10 分钟
@cache(ttl=600, key="recommendations_{date}")
async def get_recommendations():
...
2. 异步并发
# 并发调用 Claude 和数据服务
async def get_enhanced_recs():
market_task = get_market_context()
recs_task = get_recommendations()
market, recs = await asyncio.gather(market_task, recs_task)
# 调用 Claude
ai_analysis = await claude.analyze(market, recs)
return ai_analysis
3. 分页限制
# 限制每页数量
@router.get("/api/ai/recommendations/explained")
async def get_recs(limit: int = Query(default=10, le=50)):
...
🧪 测试策略
1. Prompt 测试
# tests/test_claude_service.py
async def test_analyze_recommendations():
"""测试推荐分析"""
claude = ClaudeStockAnalyzer(api_key="test_key")
mock_market = {...}
mock_recs = [...]
result = await claude.analyze_recommendations(mock_market, mock_recs)
assert "stocks" in result
assert len(result["stocks"]) > 0
assert "recommendation_reason" in result["stocks"][0]
2. 数据管道测试
async def test_enhanced_data_pipeline():
"""测试数据采集和增强"""
service = EnhancedDataService()
market = await service.get_market_context()
assert "overall_sentiment" in market
assert 0 <= market["overall_sentiment"] <= 1
📚 使用文档
For Developers
- 添加新的 AI 分析任务
# 1. 在 claude_stock_analysis.md 添加 Prompt 模板
# 2. 在 claude_service.py 添加方法
async def analyze_new_task(self, data: dict) -> dict:
prompt = f"""
分析任务:...
数据:{json.dumps(data)}
"""
message = self.client.messages.create(...)
return self._extract_json_from_response(message.content[0].text)
# 3. 在 ai_recommendations.py 添加端点
@router.get("/api/ai/new_task")
async def new_task(claude: ClaudeStockAnalyzer = Depends()):
return await claude.analyze_new_task(...)
- 调整 Prompt 参数
直接编辑 backend/prompts/claude_stock_analysis.md,无需重启服务(建议重启以重新加载)。
For Operators
- 监控 Claude API 使用
# 查看日志中的 API 调用
docker logs stock_backend | grep "Claude API"
# 监控成本(从 Anthropic Dashboard)
https://console.anthropic.com/settings/usage
- 调整缓存策略
# backend/services/cache_service.py
# 根据流量调整 TTL
CACHE_CONFIG = {
"market_overview": 300, # 5 分钟
"recommendations": 600, # 10 分钟
"user_questions": 1800 # 30 分钟
}
🔮 Roadmap
Phase 1: 核心功能 (✅ 已完成)
- Claude Prompt 模板系统
- 增强数据服务 (Tushare 集成)
- AI 推荐解释 API
- 前端增强组件
Phase 2: 高级功能 (计划中)
- WebSocket 实时推送
- 用户自定义 AI 策略
- A/B 测试不同 Prompt
- 多模型对比 (Claude + GPT-4 + Qwen)
Phase 3: 企业功能 (未来)
- 用户画像与个性化推荐
- Claude 自动生成投资日报
- 历史决策回顾与复盘
- 移动端 APP (Flutter)
🆘 故障排查
问题 1: Claude API 超时
# 增加超时时间
message = self.client.messages.create(
...,
timeout=60.0 # 增加到 60 秒
)
问题 2: JSON 解析失败
# Claude 可能返回带 markdown 的 JSON
if "```json" in response_text:
json_str = response_text.split("```json")[1].split("```")[0]
else:
json_str = response_text
问题 3: Tushare API 限流
# 添加重试逻辑
from tenacity import retry, stop_after_attempt, wait_fixed
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
def get_tushare_data():
return pro.daily(...)
📞 联系方式
- 项目仓库: https://github.com/BrunoGao/claude-stock
- 问题反馈: GitHub Issues
- 文档更新: 见
/docs目录
版本: v1.0.0 最后更新: 2025-11-11 状态: 🚀 Production Ready
核心理念:
Claude 不是来算指标的,而是来解释、综合、推理和交互的。
Generated with ❤️ by Claude Code