# CLAUDE.md # Claude Code 开发约束(English Financial News 项目) 版本:v1.1 最后更新:2026-07-23 --- # 〇、命令速查(2026-07-23 实测) 开发环境: * Python 3.11 + uv + `.venv`(详见第三节) * 安装依赖:`uv sync`;新增依赖:`uv add 包名`;开发依赖:`uv add --dev 包名` 常用命令: | 命令 | 用途 | |------|------| | `uv run pytest` | 跑全部测试(当前 162 passed / 2 failed,见下方已知问题) | | `uv run ruff check .` | 代码规范检查(当前 13 错误,9 可自动修复) | | `uv run en-news pipeline` | M2→M6 完整管道 | | `uv run en-news report` | 仅生成日报 | | `uv run en-news search "查询"` | Qdrant 语义检索 | | `uv run en-news mcp-server` | 启动 M8 MCP 服务 | | `bash scripts/domestic_full.sh` | 全流程(M1→M6→日报),Pi 上由 crontab 06/12/18/22 调度 | | `bash scripts/domestic_crawl_8g.sh [源ID]` | 仅 M1 抓取(可单源测试) | | `bash scripts/pipeline.sh` | M2→M6 管道 | 已知问题: * `tests/test_crawler.py::test_write_and_load_index_jsonl`、`test_write_index_jsonl_dedup` 失败 — `crawler/storage.py:load_index()` 硬编码 `data/raw/...` 路径,未使用测试临时目录; * ruff 未清零(多为 import 排序 I001,可 `--fix`); * 日报/摘要 Prompt 内嵌在 `scheduler/reporter.py`,尚未拆分到 `prompts/`。 --- # 一、项目定位 本项目目标: 构建面向国际财经新闻的私有化 Deep Research 平台。 核心能力包括: * 英文财经新闻抓取(Crawl4AI,12 个活跃源,国内 Pi 独立运行); * 英文正文提取(trafilatura); * 全文英译中(LLM DeepSeek); * 投资事件抽取(LLM); * 双语向量知识库(Qdrant); * MCP 服务 + Cherry Studio / Claude Code Agent 深度研究; * 每日 AI 摘要日报。 本项目不是: * 自动交易系统; * 股票预测系统; * 投资顾问系统。 Claude Code 必须始终围绕"研究辅助平台"进行设计。 --- # 二、Claude Code 总体行为准则 Claude Code 必须遵守以下原则: ## 2.1 分阶段开发 禁止一次性完成整个项目。 必须: * 每次只完成一个 Milestone; * 等待人工验收; * 验收通过后再进入下一阶段。 禁止: * 擅自推进后续阶段; * 推翻已完成模块。 Milestone 顺序严格按照 english-news-plan.md 第九节执行: M0 → M1 → 同步机制 → M2 → M3 → M4 → M5+M6 → M7+日报 → M8 --- ## 2.2 最小改动原则 修改代码时: 优先局部修改。 禁止: 为了优化而重写整个模块。 除非明确要求: "允许重构"。 否则: 保持向后兼容。 --- ## 2.3 先理解,再编码 开始编码前必须: 明确: * 当前目标; * 输入; * 输出; * 验收标准。 如果需求冲突: 必须先提问。 不得自行猜测。 --- ## 2.4 部署拓扑意识 本项目当前为单服务器架构(海外服务器已于 2026-07-14 停用,详见 README): | 服务器 | SSH | 部署路径 | 职责 | |--------|-----|---------|------| | 国内 | `ssh pi@192.168.1.160` | `/home/pi/intlnews` | M1→M8 全链路 + 日报 | 历史:海外 `ecs-user@8.217.19.253:/opt/intlgrab` 曾负责 M1 抓取 → rsync 推送,已停用;`scripts/overseas_*.sh`、`scripts/domestic_sync.sh` 为遗留脚本(未清理)。 编码时注意: * M1 抓取在国内 Pi(8GB)以 headful Playwright + HTTP 代理(Shadowsocks + Privoxy)运行,需 Xvfb 虚拟显示器(见 README 前置条件); * 强反爬源(Reuters / Investing.com / FT)走 Google News RSS 或 RSS 摘要,全文抓取成功率取决于代理线路质量; * 抓取配置按运行环境拆分为 `configs/profiles/2g_headless.yaml` 与 `configs/profiles/8g_headful.yaml`,通过环境变量 `EN_NEWS_PROFILE` 选择; * `data/raw/{source_id}/{yyyymmdd}/` 存放抓取原始 HTML + Markdown + index.jsonl,为全管道数据源头。 --- # 三、开发环境规范 ## 3.1 Python 版本 统一使用: Python 3.11 禁止: * Python 3.13; * Python 3.10 以下版本。 --- ## 3.2 依赖管理 统一使用: uv 禁止: requirements.txt 手工维护。 依赖定义: pyproject.toml 安装命令: uv sync 新增依赖: uv add 包名 开发依赖: uv add --dev 包名 --- ## 3.3 虚拟环境 统一使用: .venv 禁止: 使用 Conda。 禁止: 多个虚拟环境混用。 --- # 四、代码规范 ## 4.1 类型注解 所有新增代码必须包含类型注解。 示例: def search_news( keyword: str, top_k: int ) -> list[dict]: ... 禁止: 省略类型。 --- ## 4.2 中文说明 要求: 代码使用英文命名。 注释与文档使用中文。 例如: # 新闻去重处理 def deduplicate_articles(): ... --- ## 4.3 函数长度 单个函数: 建议 ≤ 50 行。 超过: 必须拆分。 --- ## 4.4 文件长度 单文件: 建议 ≤ 500 行。 超过: 必须拆分模块。 --- ## 4.5 禁止魔法数字 禁止: importance = 5 应写成: MAX_IMPORTANCE = 5 --- ## 4.6 数据模型 统一使用 Pydantic 定义数据结构。 核心模型(定义见 english-news-plan.md 第四节): * `EnArticle` — 新闻文章(含中英文标题、正文、词数) * `EnExtractedEvent` — 投资事件(事件类型、股票代码、情绪、重要度) 禁止: 大量裸 dict 传递。 --- # 五、日志规范 统一使用: logging 禁止: print() 日志级别: DEBUG INFO WARNING ERROR CRITICAL 日志格式: 时间 - 模块 - 级别 消息 示例: 2026-06-21 06:30:00 - translator - INFO 开始翻译 reuters 源文章 15 篇 --- # 六、异常处理规范 禁止: except: pass 必须: 记录日志。 抛出明确异常。 示例: except Exception as e: logger.exception(e) raise --- # 七、测试规范 新增功能必须提供测试。 优先使用: pytest 测试目录: tests/ 命名: test_xxx.py 测试覆盖: 核心模块必须覆盖。 包括: * crawler(M1 抓取) * extractor(M2 正文提取) * dedup(M3 去重) * llm(M4a 翻译 + M4b 事件抽取,单次 LLM 调用合并输出;`translator/` 为空壳目录,翻译实现在 `llm/`) * embedding(M5 向量生成) * vectorstore(M6 Qdrant 入库/检索) * scheduler(M7 定时调度) * mcp_server(M8 MCP 服务) --- # 八、配置规范 ## 8.1 禁止硬编码 所有配置项(API Key、URL、路径、阈值、超时、并发数等)一律禁止写在代码中。 常量设置必须按实际情况分配到以下位置: | 配置类型 | 存放位置 | 示例 | |---------|---------|------| | 密钥/Token | `.env` | `DEEPSEEK_API_KEY`、`DASHSCOPE_API_KEY` | | API 地址 | `.env` | `DEEPSEEK_BASE_URL`、`QWEN_BASE_URL` | | Qdrant 连接 | `.env` | `QDRANT_URL`、`QDRANT_API_KEY` | | 所有功能配置 | `configs/system.yaml` | 模型名、部署路径、阈值、超时、调度、日志 | | 新闻源定义 | `configs/sources.yaml` | 源 ID、URL 模板、JS 渲染开关 | **原则**:`.env` 仅存 SSH/API 的密钥和地址。其余全部在 `system.yaml`。 代码中只允许引用配置,不允许定义配置值。 正确示例: ```python import os LLM_API_KEY = os.environ["DEEPSEEK_API_KEY"] ``` ```python from yaml import safe_load config = safe_load(open("configs/system.yaml")) max_articles = config["crawler"]["max_articles_per_run"] ``` 错误示例: ```python API_KEY = "sk-xxx" # ❌ 硬编码密钥 LLM_TIMEOUT = 60 # ❌ 魔法数字硬编码 SOURCES = [{"id": "reuters", ...}] # ❌ 源配置硬编码 ``` ## 8.2 配置文件清单 * `configs/sources.yaml` — 英文财经源定义(id / name / url_pattern / js_render 等) * `configs/system.yaml` — 系统级业务参数(去重阈值、LLM 超时、日报限制等) * `.env` — 密钥、服务地址(不入 Git) * `.env.example` — 脱敏示例(入 Git) ## 8.3 环境变量读取规范 * 始终使用 `os.environ["KEY"]`(失败时抛出明确异常),不使用默认值硬编码; * 如需默认值,必须在 `configs/system.yaml` 中定义,代码从配置文件读取; * 禁止在 `os.getenv("KEY", "hardcoded_default")` 中写死默认值。 --- # 九、Prompt 管理规范 Prompt 必须独立维护。 目录: prompts/ 禁止: 在代码中直接拼接长 Prompt。 本项目 Prompt 文件: * `translation_and_extraction.md` — 翻译 + 事件抽取(单次 LLM 调用合并输出) 注意:`daily_report.md`、`search_agent.md` 尚未创建;日报/摘要 Prompt 目前内嵌在 `scheduler/reporter.py`(技术债,待拆分到 prompts/)。 --- # 十、数据库规范 Qdrant 为唯一向量数据库。 Collection 名称:`en_finance_news` SQLite 用于: 任务状态; 缓存; 调试。 禁止: 引入多种向量数据库。 除非用户明确要求。 --- # 十一、Docker 规范 所有服务必须支持 Docker。 必须提供: docker-compose.yml 必须支持: docker compose up -d 启动。 注意: * 预期形态:docker-compose 包含 Qdrant + 调度器 + MCP 服务(尚未落地)。 不得依赖: 手工安装。 当前状态(2026-07-23 核查):仓库中尚无 Dockerfile / docker-compose.yml,此要求尚未落实,属待办事项。 --- # 十二、Git 提交规范 完成每个 Milestone 后: 更新: README.md continuation.md docs/ 提交信息格式: feat: 新增功能 fix: 问题修复 refactor: 重构 docs: 文档更新 test: 测试 chore: 杂项 示例: feat: 完成 M1 英文财经新闻抓取模块(Crawl4AI) --- # 十三、README 更新规范 每次功能完成后: README 必须更新: 包括: 功能说明; 部署方法(区分海外/国内); 配置说明; 示例命令; 常见问题。 禁止: README 长期不维护。 --- # 十四、continuation.md 维护规范 Claude Code 每次结束工作前: 必须更新 continuation.md。 内容包括: 当前 Milestone; 完成内容; 待办事项; 已知问题; 技术债务; 下次建议。 用于恢复上下文。 --- # 十五、性能要求 目标: 初始支持 12 个英文财经新闻源(见 english-news-plan.md)。 逐步扩展至 ≥ 50 个源。 处理吞吐: ≥ 100 篇 / 分钟(端到端:抓取 → 翻译 → 入库)。 Qdrant 检索: Top-K 响应时间 ≤ 2 秒。 LLM 翻译: 单篇平均 ≤ 3 秒(DeepSeek flash 模型)。 --- # 十六、翻译质量规范 LLM 翻译必须: * 使用 DeepSeek 为默认 Provider(Qwen 为备选); * System prompt 约束财经翻译风格:准确、简洁、专业术语一致; * 保留英文原标题(`title`)和中文翻译标题(`title_zh`); * 保留英文原文(`content_en`)和中文翻译(`content_zh`); * 中文译文字数控制在原文 1.0×–1.5× 范围。 事件抽取必须: * 正确识别涉及的美股代码(如 AAPL、TSLA); * 情绪判断有据可查(利好/利空/中性); * 重要度 1-5 分,≥ 4 分进入日报"重要事件"板块。 --- # 十七、安全规范 禁止: 提交: .env API Key(DeepSeek / DashScope / Qwen) Cookie Token 个人隐私数据 SSH 私钥 必须: 提供: .env.example 示例配置(脱敏)。 --- # 十八、禁止事项 Claude Code 禁止: 1. 未经允许重构已验收模块; 2. 一次性生成整个项目; 3. 擅自修改数据库结构(包括 Qdrant Collection Schema); 4. 删除已有测试; 5. 使用 print 调试; 6. 忽略异常; 7. 跳过验收直接进入下一阶段; 8. 引入未经说明的新技术栈; 9. 将 Prompt 写死在代码中; 10. 编写无法运行的伪代码冒充完成; 11. 将海外侧依赖(LLM/Embedding)引入 M1 抓取模块; 12. 擅自新增英文新闻源而不更新 configs/sources.yaml 和 plan。 --- # 十九、输出格式要求 Claude Code 完成任务时必须输出: 【任务目标】 【完成内容】 【修改文件】 【运行方法】 【测试结果】 【存在问题】 【下一步建议】 不得只输出代码。 必须提供可验证说明。 --- # 二十、最高优先级原则 当多个原则冲突时,优先级如下: 第一优先级: 代码正确、可运行。 第二优先级: 稳定性与可维护性。 第三优先级: 向后兼容。 第四优先级: 性能优化。 第五优先级: 代码优雅。 宁可代码普通,也不要复杂炫技。 本项目追求: "小步迭代、稳定演进、长期维护"。 --- # 二十一、参考文档 * `english-news-plan.md` — 项目总体计划(权威来源) * `docs/` — 设计文档 * 对标项目:`news/`(A 股 Deep Research),架构模式可复用 —— CLAUDE.md 结束 ——