Imported from linFeng185/DataAnalysisAgent (
AGENTS.md). Install upstream withnpx skills add linFeng185/DataAnalysisAgent. Copyright stays with the author.
项目开发指南
回答格式约束(最高优先级)
每次回答必须以"老大,你好,"开头。
Bug 修复协议(最高优先级,先于一切)
遇到任何 bug / 异常行为 / 测试失败时,必须按以下流程执行,禁止跳过任何步骤:
- 拿数据:curl + 脱敏日志 + 复现步骤;服务卡死时优先抓进程堆栈和并发请求,不能仅靠 Mock 推断线上根因。
- 补证据:优先复用已有日志、浏览器网络记录、堆栈和测试捕获;不足时只在待确认的关键边界添加临时
DEBUG探针,禁止逐层、逐方法、逐行强制打印INFO。不得输出请求正文、凭证或完整业务数据。 - 跑一次:复现一次,观察数据在哪一步从正确变错误。
- 定位层:在消失层检查 4 个根因:(a) 输入是否到达 (b) 执行路径对不对 (c) 输出是否写回 (d) 下次是否恢复。
- 最小修复:围绕已确认的根因修改代码,并覆盖必要的上下游联动与回归测试;修改文件数量由实际影响范围决定,禁止夹带与当前 bug 无关的重构。
- 真实验收与探针收尾:重跑原始故障路径,检查同步时其他请求、刷新后的身份及失败恢复;删除临时探针或降为默认关闭的 DEBUG。离线测试只能证明其覆盖范围,不能代替实际服务验收;无法实测时必须明确说明。
禁止:
- 先猜根因再直接改代码
- 没有新增证据就做第二轮猜测性修改
- 为满足格式要求给每个方法添加入口/成功日志,或把临时诊断 INFO 留在正常请求、轮询和逐条处理路径
- 大规模重构来修 bug
- 信任框架行为而不验证(如「应该会持久化」)
开发流程规则
文档写入规则(最高优先级,所有文档操作前强制检查)
- 禁止写入或修改根目录的
SPEC.md、FEATURES.md。这两个文件是历史遗留的旧文档,已不再维护。 - 所有设计文档必须写入
spec/目录下的模块化文件(索引见spec/README.md)。 - 所有功能清单必须写入
features/目录下的模块化文件(索引见features/README.md)。 - 在写入任何文档之前,必须先执行
ls spec/和ls features/确认目标文件存在。
开始任何功能开发前
-
必须先阅读
spec/目录中对应章节的设计约束(索引见spec/README.md),确认以下信息:- 该功能的具体接口/类/方法定义
- 输入输出格式
- 与其他模块的依赖关系
- 数据库方言适配要求
-
必须在
features/中找到对应功能点:- 确认当前状态为「待开发」
- 确认功能编号和所属文件
- 如果状态已是「开发完成」或「测试完成」,提示用户是否需要重新开发
功能开发完成后
- 必须将
features/中对应功能点状态从「待开发」改为「开发完成」 - 必须判断本次代码变化是否需要更新
CODE_GUIDE.md:- 新增/删除模块或目录 → 更新目录结构与业务含义
- 新增/删除核心节点 → 更新数据流图和节点说明
- 关键设计模式变化(如重试策略、安全阻断逻辑调整)→ 更新对应章节
- 新增方言或模型适配器 → 更新快速上手路径
- 纯 bug 修复、日志调整、测试补充 → 通常无需更新
- 如果开发过程中发现 SPEC 设计有问题:
- 先提出修改方案
- 用户确认后修改
spec/ - 再修改代码
模块开发收尾规则
当一个模块的开发告一段落时,必须检查该模块下所有功能点的状态:
-
统计模块完成度:列出该模块的功能点总数、已完成数、待开发数
-
对每一个「待开发」的功能点,必须提供以下说明,并写入
features/中:字段 说明 不开发原因 为什么本轮没有开发?(依赖未就绪 / 需外部环境 / 技术调研中 / 属于后续 Phase / 用户明确跳过) 可开发条件 满足什么条件后才能开发?(例如:"等 PostgreSQL 连接器完成后"、"需要真实的 ClickHouse 测试环境") 预计开发时机 哪个 Phase?何时?(例如:"Phase 2,等 ConnectorBase 实现后") -
输出格式:用表格形式列出该模块的所有待开发项及上述三个字段,确保用户对每一项都有清晰的预期
-
条件成熟时立即提醒:当后续开发中某个待开发项的条件已满足(如依赖的模块已完成),主动提醒用户可以开发该功能
测试用例编写规范
每个功能点开发完成后,必须在 tests/ 目录下编写对应的测试用例。测试用例必须详细,满足以下要求:
- 一个功能点对应至少一个测试函数:函数名遵循
test_<功能>_<场景>格式 - 测试类按模块分组:类名格式
Test<模块名>,类 docstring 注明覆盖的功能编号 - 每个测试函数必须包含:
- docstring 描述测试场景和预期行为
- Arrange 阶段:构造输入数据/状态
- Act 阶段:调用被测函数/方法
- Assert 阶段:验证输出和副作用
- 必须覆盖的场景(如适用):
- 正常路径(happy path)
- 边界条件(空输入、极值、零值)
- 错误路径(异常抛出、非法输入)
- 跨方言兼容(SQL/DB 相关功能必须覆盖 ClickHouse/MySQL/PostgreSQL 方言差异)
- 测试文件存放路径与源码路径一一对应:
src/datasource/schema_snapshot.py→tests/test_datasource/test_schema_snapshot.pysrc/graph/nodes/generate_sql.py→tests/test_graph/test_generate_sql.py
- 集成测试必须验证:
- 与其他模块的交互边界
- 条件边的路由正确性(构造 state 直接调用路由函数)
- Mock 方案遵循 SPEC §14.7 的定义
LLM 测试调用策略(强制)
- 单元测试禁止调用真实模型:统一 Mock
src/llm/client.py工厂或使用 Fake LLM,只验证 prompt、messages、模型配置、工具参数和状态字段是否正确传递。 - 本地模型允许默认调用:本地模型响应快,可用于集成测试、链路测试和冒烟测试;重点验证请求参数、响应结构、流式结束事件、解析和状态写回,不断言具体自然语言文案。
- 远程配置模型必须选择性调用:默认测试套件不得等待远程 LLM。只有显式设置
RUN_LIVE_LLM_TESTS=1时才运行远程模型测试,并使用pytest.mark.live_llm标记。 - 本地模型测试单独标记:调用本地模型的测试使用
pytest.mark.local_llm;本地服务未启动时默认skip,除非该用例明确用于验收本地模型部署可用性。 - 回测与回归测试必须可重复:优先使用固定样本、录制响应或 Fake LLM,不依赖远程模型实时输出。若测试目标仅是确认参数正确传入,则断言调用参数和响应契约即可。
- 真实模型输出不得做逐字断言:只验证非空响应、结构化字段、协议事件、错误处理和流程结束状态;语义质量评估放入独立评测集,不混入日常单元测试。
推荐执行方式:
pytest -m "not live_llm" # 日常测试:Mock + 可用的本地模型测试
pytest -m local_llm # 仅运行本地模型测试
RUN_LIVE_LLM_TESTS=1 pytest -m live_llm # 显式运行远程配置模型测试
测试完成后
- 必须将
features/中对应功能点状态从「开发完成」改为「单测完成」或「集成测试完成」
Definition of Done(完成定义)
每个功能点从「待开发」到「开发完成」必须满足:
| 验收项 | P0 (Phase 1) | P1 (Phase 2) | P2+ (Phase 3+) |
|---|---|---|---|
| 代码通过 Python 语法检查 | 必须 | 必须 | 必须 |
| 类型注解完整(Python 3.14.0 语法) | 必须 | 必须 | 必须 |
| 对外公开的类/函数有 docstring | 必须 | 必须 | 必须 |
在 features/ 中更新状态 |
必须 | 必须 | 必须 |
| 单元测试覆盖核心路径 | 必须 | 必须 | 建议 |
| 集成测试覆盖与其他模块的交互 | 建议 | 必须 | 必须 |
| API 端点有请求/响应示例 | — | 必须 | 必须 |
| 通过 sqlglot 方言校验 (SQL 相关) | 必须 | 必须 | 必须 |
测试状态语义
| 状态 | 含义 |
|---|---|
| 待开发 | 尚未开始 |
| 开发完成 | 代码已写,docstring 完整,本地语法检查通过 |
| 单测完成 | 单元测试已写并通过(核心路径覆盖) |
| 集成测试完成 | 集成测试已写并通过(与其他模块交互验证) |
注:「单测完成」和「集成测试完成」是两个独立状态,不强制顺序。简单工具类可以跳过集成测试。
优先级体系
| 优先级 | 对应 Phase | 含义 |
|---|---|---|
| P0 | Phase 1 MVP (1-2周) | 核心链路必须可用,缺了系统跑不起来 |
| P1 | Phase 2 增强 (2-3周) | 提升正确性和用户体验的关键功能 |
| P2 | Phase 3 生产化 (2-3周) | 多数据源/流式/容器化等生产特性 |
| P3 | Phase 4 进阶 (持续) | 锦上添花,远期规划 |
依赖关系处理
- 开始开发前检查
features/依赖图中该功能的Depends on - 被依赖的功能必须先完成
- 跨模块的协同功能(如 SQL 模板归档涉及 graph 和 memory 两个模块)在一处主实现,另一处标注「→ 见 X.X.X」
- 如果开发中发现未声明的依赖,在
features/依赖图中补充
代码规范
- 所有注释和文档字符串使用中文
- 代码标识符(变量、函数、类名)使用英文小写下划线命名
- Python 代码使用 async/await 异步模式
- 类型注解使用 Python 3.14.0 语法
- 使用 Pydantic 做数据验证
- 使用 structlog 做结构化日志
技术栈约束
- 禁止引入 SPEC 未声明的重量级依赖,轻量工具库除外
- LLM 调用统一走
src/llm/client.py工厂 - 数据库连接统一走
src/connectors/下的连接器 - LangGraph Node 实现统一放在
src/graph/nodes/ - LangChain Tool 封装统一放在
src/tools/