# BidMaster-CLI 项目规范文档 ## 一、项目概述 BidMaster-CLI 是一个AI标书撰写助手项目,通过智能化标书制作流程提升投标效率和中标率。项目采用Python语言开发,遵循"核心需求第一、立即失败、MVP至上"的开发哲学。 ## 二、架构设计规范 ### 2.1 分层架构(禁止逆向引用) ``` ┌─────────────────────────────────────┐ │ CLI Layer (Interface) │ ← 命令行接口 ├─────────────────────────────────────┤ │ Agent Layer (Orchestration) │ ← 业务编排 ├─────────────────────────────────────┤ │ Tools Layer (Infrastructure) │ ← 基础设施 └─────────────────────────────────────┘ ``` ### 2.2 目录结构规范(≤8文件规则) ``` bidmaster-cli/ ├── src/ │ └── bidmaster/ │ ├── internal/ # 内部模块,禁止外部import │ ├── cli/ # 仅暴露命令接口(≤8文件) │ ├── agents/ # Agent逻辑(≤8文件) │ ├── tools/ # 原子工具(≤8文件) │ ├── models/ # 数据模型 │ ├── config/ # 配置中心 │ └── __init__.py # 统一导出接口 ├── templates/ # Word模板 ├── config/ # 配置文件 ├── data/ # 数据存储 └── main.py # 唯一入口 ``` ### 2.3 Python语言映射表 | 通用概念 | Python实现 | BidMaster应用场景 | |---------|-----------|------------------| | 共用组件 | `__init__.py` + `__all__` | tools模块统一导出 | | 配置主题 | `pydantic.BaseSettings` | config/settings.py | | HTTP拦截 | `httpx.Auth` 自定义Transport | OpenAI客户端封装 | | 生命周期 | `contextlib.ExitStack` | 数据库连接管理 | | 错误边界 | 自定义Exception → ErrorCode | BidMasterError体系 | | 依赖注入 | `fastapi.Depends` / 手动注入 | Agent依赖注入 | | 插件链 | 装饰器 + `functools.wraps` | 工具函数增强 | ## 三、核心开发原则 ### 3.1 核心哲学实施 ```python # 1. 核心需求第一 - 不做防护编程 def parse_document(file_path: Path) -> dict: # 直接处理,不做备份 with open(file_path, 'rb') as f: return extract_content(f) # 失败就失败 # 2. 立即失败 - 错误必须暴露 if not api_key: raise ValueError("API_KEY未配置") # 不提供默认值 # 3. MVP至上 - 只实现必要功能 class WordProcessor: def fill_template(self, data: dict): # 只填充,不校验格式、不美化样式 pass ``` ### 3.2 统一配置管理 ```python # config/settings.py - 唯一配置源 from pydantic_settings import BaseSettings class Settings(BaseSettings): # 三层配置:默认值 → 配置文件 → 环境变量 model_name: str = "gpt-4" api_key: str # 必须从环境变量读取 chunk_size: int = 1000 class Config: env_file = ".env" env_prefix = "BIDMASTER_" # 单例模式 settings = Settings() ``` ### 3.3 错误处理规范 ```python # models/exceptions.py class BidMasterError(Exception): """基础异常类""" def __init__(self, code: str, message: str): self.code = code # 错误码 self.message = message super().__init__(f"[{code}] {message}") # 使用示例 class ParserError(BidMasterError): """解析错误""" pass # 立即抛出,不吞没 if not file_path.exists(): raise ParserError("FILE_NOT_FOUND", f"文件不存在: {file_path}") ``` ## 四、代码质量保证 ### 4.1 门禁工具链(强制执行) ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/psf/black hooks: - id: black args: [--line-length=88] - repo: https://github.com/charliermarsh/ruff-pre-commit hooks: - id: ruff args: [--select, "E,F,I,N,UP", --fix] - repo: https://github.com/pre-commit/mirrors-mypy hooks: - id: mypy args: [--strict] ``` ### 4.2 命名与类型规范 ```python # 类名:PascalCase class DocumentParser: pass # 函数/变量:snake_case def generate_content(task_id: str) -> dict[str, Any]: result_data: dict = {} return result_data # 常量:UPPER_CASE(放在文件头部) MAX_TOKENS = 4000 DEFAULT_TEMPERATURE = 0.7 # 私有成员:单下划线前缀 def _internal_helper() -> None: pass # 类型注解:100%覆盖 from typing import Optional, TypedDict class TaskResult(TypedDict): content: str confidence: float metadata: dict[str, Any] ``` ## 五、工作流程规范 ### 5.1 开发流程(6步法) ```bash # 1. 从模板初始化(5分钟启动) cookiecutter templates/module-template/ # 2. 实现核心功能(MVP) # tools/new_tool.py def core_function(input: dict) -> dict: # 最简实现,不做优化 pass # 3. 添加类型注解 def core_function(input: dict[str, str]) -> dict[str, Any]: pass # 4. 编写测试 # tests/test_new_tool.py def test_core_function(): result = core_function({"key": "value"}) assert result is not None # 5. 运行门禁 pre-commit run --all-files # 6. 集成到CLI # cli/commands.py @click.command() def new_command(): """新功能入口""" pass ``` ### 5.2 Agent开发规范 ```python # agents/new_agent.py from typing import Any from pydantic import BaseModel class AgentInput(BaseModel): """输入模型""" task: str context: dict[str, Any] class NewAgent: """单一职责Agent""" def __init__(self, tools: list): self.tools = tools # 依赖注入 async def run(self, input: AgentInput) -> dict: """执行逻辑""" # 1. 解析输入 # 2. 调用工具 # 3. 返回结果 return {"status": "completed"} ``` ### 5.3 工具开发规范 ```python # tools/new_tool.py from pathlib import Path from typing import Optional def process_file( file_path: Path, *, # 强制关键字参数 encoding: str = "utf-8", timeout: Optional[int] = None ) -> dict[str, Any]: """处理文件 Args: file_path: 文件路径 encoding: 编码格式 timeout: 超时时间(秒) Returns: 处理结果字典 Raises: FileNotFoundError: 文件不存在 ValueError: 参数无效 """ if not file_path.exists(): raise FileNotFoundError(f"文件不存在: {file_path}") # 核心逻辑 with open(file_path, encoding=encoding) as f: content = f.read() return {"content": content, "size": len(content)} ``` ## 六、最小可执行骨架 ```python # main.py - 唯一入口 from bidmaster.config import settings from bidmaster.cli import create_app def main(): """启动入口""" # 1. 加载配置 settings.validate() # 2. 初始化依赖 # 3. 启动CLI app = create_app() app() if __name__ == "__main__": main() # bidmaster/__init__.py - 统一导出 __all__ = ["parse", "generate", "assemble"] from .tools.parser import parse from .tools.rag import generate from .tools.table import assemble # bidmaster/config/settings.py - 配置中心 from pydantic_settings import BaseSettings class Settings(BaseSettings): model_name: str = "gpt-4" api_key: str class Config: env_file = ".env" env_prefix = "BIDMASTER_" settings = Settings() ``` ## 七、性能与监控 ### 7.1 性能指标 - 项目初始化:< 3分钟 - 单章节生成:< 60秒 - 内存占用:< 2GB - 向量检索:< 500ms ### 7.2 日志规范 ```python import logging from datetime import datetime # 统一日志格式 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # 性能日志 start = datetime.now() result = process() logger.info(f"处理完成,耗时: {(datetime.now() - start).seconds}秒") ``` --- **一句话总结:让90%的场景只有一条官方路径,代码直接明了,错误立即暴露,功能MVP即止。**