DSAWiki
06系统 · 开发

代码地图:从哪里开始读

给想改代码的你一条不迷路的路线:入口、分层、关键文件、调试技巧与测试策略。

约 5 分钟 开发者 第 06 章 · 系统

你不需要读完 657 个 Python 文件。真正高效的读法是:先锁定一条调用链,沿着它读三四个文件,建立「手感」,再按需要横向扩展。这一章给你地图、路线和工具箱。

先选目标,再选路线

想改报告文案 → 读 Prompt;想加数据源 → 读 data_provider/;想换模型 → 先读配置,不读代码;想理解结论为什么被降级 → 读守卫。不同目标的最短路径完全不同。

仓库地图:每个目录为什么存在

daily_stock_analysis/
├── main.py                  # 命令行总入口:参数、模式分派、交易日过滤
├── server.py / webui.py     # FastAPI 启动入口
├── src/
│   ├── core/               # 编排:pipeline、交易日历、回测、ETF 轮动、配置管理
│   ├── services/           # 业务服务:分析、历史、持仓、告警、选股、任务队列…
│   ├── analyzer.py         # LLM 分析器:Prompt、调用、解析、守卫(5700+ 行,大半是 Prompt)
│   ├── stock_analyzer.py   # 技术指标与趋势评分
│   ├── market_analyzer.py  # 大盘复盘
│   ├── search_service.py   # 新闻/情报检索
│   ├── storage.py          # SQLite / SQLAlchemy:32 张表与迁移
│   ├── notification.py     # 通知服务:路由、降噪、分片
│   ├── notification_sender/# 各渠道发送器
│   ├── config.py           # 环境变量 → Config(近 4000 行)
│   ├── llm/                # 模型后端抽象、LiteLLM、用量归一
│   ├── agent/              # Agent 循环、工具、多智能体、策略路由
│   ├── schemas/            # Pydantic/数据结构与决策刻度
│   └── repositories/       # 数据访问薄封装
├── data_provider/          # 14 个数据源适配器 + 路由/熔断
├── strategies/             # 15 个 YAML 策略(自然语言,无需写代码)
├── api/                    # FastAPI 路由(约 131 个端点)
├── bot/                    # 命令分发、飞书/钉钉 Stream 接入
├── apps/dsa-web/           # React + Vite 前端
├── templates/              # Jinja2 报告模板(可选渲染引擎)
├── docker/                 # Dockerfile / compose
├── scripts/                # CI、环境检查、索引生成、测试脚本
├── tests/                  # 300+ 测试文件
└── docs/                   # 项目文档(配置、部署、专题契约)

目录边界本身就是一种架构约束:后端能力放 src/、data_provider/、api/、bot/;前端只改 apps/dsa-web/;部署相关放 scripts/、.github/workflows/、docker/。跨边界改动通常意味着设计需要再想一遍。

推荐阅读路线:五次点击建立手感

1
从 main.py 的 main() 开始

只看它如何解析参数、判断模式、调用 run_full_analysis()。暂时跳过具体实现。目标是知道「一个命令如何变成一次任务」。

2
跳进 pipeline.analyze_stock()

这是单股分析的主函数。按顺序标出:取实时行情、取日线、算趋势、搜新闻、拼上下文、调 LLM、跑守卫、落库。先读函数调用顺序,不读每个 helper 的实现。

3
读 stock_analyzer.py 的评分

找到趋势/乖离/量能/支撑/MACD/RSI 的分值分配,理解「技术分」如何构成。这是全系统最确定、最容易验证的一部分。

4
读 analyzer.py 的 Prompt 与解析

不必逐字读完 2000 行 Prompt。先看系统提示词的五段结构、用户消息如何拼、JSON 如何校验、失败如何回退。再看守卫函数。

5
读 data_provider/base.py 的路由

理解 DataFetcherManager 的市场过滤、优先级、熔断与错误汇总。之后你看任何适配器都会很快。

关键文件速查

你想理解 / 修改先看这里备注
命令行参数与模式main.pyparse_arguments() 与 main()
单股分析顺序src/core/pipeline.pyanalyze_stock(),约 434 行起
批量并发与汇总src/core/pipeline.pyrun(),线程池默认 3
技术指标与评分src/stock_analyzer.pyMA / MACD / RSI / 乖离 / 量能
Prompt 与 JSON 契约src/analyzer.py系统提示词、_format_prompt、_parse_response
LLM 后端与回退src/llm/generation_backend.py、litellm_backend.py
数据源路由data_provider/base.py市场过滤、优先级、熔断
数据库表与迁移src/storage.py自愈式 _ensure_* 迁移
报告与推送src/notification.py、src/formatters.py各渠道格式差异
Web APIapi/v1/router.py15 个路由模块
Agent 循环src/agent/runner.py工具调用、预算、超时
策略定义strategies/*.yaml自然语言 + 元数据

调试工具箱:先定位,再改代码

命令行

python main.py --stocks 600519 --debug      # 详细日志,最快定位
python main.py --dry-run                     # 只取数,不调 LLM
python main.py --no-notify                   # 不推送,避免打扰
python main.py --workers 1                   # 单线程复现并发问题
python main.py --check-notify                # 检查通知渠道配置
python main.py --backtest --backtest-code 600519 --backtest-days 30

日志与诊断

  • 日志默认写入 logs/,同时输出到终端;--debug 会打开更详细的第三方库与 Prompt 记录。
  • Web 的「运行诊断」会展示入口、数据源、分析引擎、产物四段链路,适合排查「哪一段没跑」。
  • 单次任务可通过 GET /api/v1/analysis/tasks/{id}/flow 读取结构化诊断,不必翻整份日志。
  • 数据源问题优先看数据中心的「能力 / 质量 / 警告」,而不是猜。

测试

# 离线测试(CI 默认排除网络标记)
python -m pytest -m "not network"

# 仓库的验证入口
./scripts/ci_gate.sh

# 只做语法检查(改动小、依赖装不全时的最低要求)
python -m py_compile path/to/changed.py

后端约有 300 个测试文件、数千个测试函数,按 unit / integration / network 标记;CI 分 3 片跑离线测试,另有 Docker 构建与前端 lint/build/Playwright。前端本地可执行 npm run test(Vitest),但 CI 并不运行 Vitest——这是一个真实的覆盖缺口,改前端逻辑时要自己补跑。

五个常见改造,从哪下手

换模型 / 加供应商

多数情况只改环境变量:LITELLM_MODEL、LLM_CHANNELS 或 LITELLM_CONFIG。需要多 key 负载均衡时再读 litellm_backend.py。

加一个数据源

继承 BaseFetcher,实现 _fetch_raw_data 与 _normalize_data,声明市场能力,注册到管理器,补离线测试与质量状态。

加一个策略

在 strategies/ 新建 YAML,写清适用场景、条件、加减分与工具依赖。不需要 Python 代码,重启后自动加载。

改报告 / 提示词

文案在系统提示词与模板里;结构在 JSON 契约里;渲染在 templates/ 或通知格式化层。改 Prompt 要同步检查字段校验。

加通知渠道

实现 sender,声明长度/格式/图片能力,接入路由与降噪,补「单渠道失败不影响其他渠道」的测试。

改 Web 页面

apps/dsa-web/src/pages/ + src/api/;注意后端响应统一转 camelCase,认证走 Cookie 与 401 跳转。

贡献前,先读 AGENTS.md

仓库对协作质量有明确要求,摘要如下(以 AGENTS.md 为准):

  • 不擅自提交:未经确认不执行 git commit / tag / push;commit message 用英文,不加 Co-Authored-By。
  • 边界与复用:遵循目录职责,优先复用现有模块,不新增平行实现。
  • 文档同步:新增配置要更新 .env.example 和文档;用户可见行为变化要更新 docs/CHANGELOG.md。
  • UI 证据:改报告格式或 Web 界面,PR 需附截图(长期文档示意图除外)。
  • 验证:按改动面跑 ci_gate.sh、前端 lint/build,或至少语法检查,并说明未验证项。
  • AI 资产:改 AGENTS.md / CLAUDE.md / 指令文件后运行 python scripts/check_ai_assets.py。

文档可能滞后,代码是最终事实

仓库里存在少量文档漂移(例如文档提到过的某个美股源,代码里并没有对应适配器)。读实现时以代码和工作流为准,发现不一致可以在 PR 里顺手修正文档。

源码与文档锚点