bidmaster-cli/PROJECT_SPEC.md
sladro e6103c711f refactor: 按照PROJECT_SPEC.md规范重构代码
修复架构和代码规范违规问题:

架构修复:
- 创建internal目录(内部模块,禁止外部import)
- 恢复ARCHITECTURE.md文档
- 移除未定义的utils目录
- 清理临时测试目录

代码规范修复(严格遵循核心哲学):
- 移除所有try-except,让错误立即暴露
- 移除所有防护编程(不返回bool/错误字符串)
- 简化为MVP版本(每个命令组只保留核心功能)
- 移除所有美化输出,使用简单print

功能实现:
- 实现generate命令(只保留task子命令)
- 实现assemble命令(只保留tables子命令)
- 修复bidmaster/__init__.py导出
- 添加缺失的TableGenerator类

文件精简:
- generate.py: 262行 → 66行
- assemble.py: 293行 → 64行
- 移除所有延迟导入和内部import

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-26 20:02:59 +08:00

8.2 KiB
Raw Permalink Blame History

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 核心哲学实施

# 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 统一配置管理

# 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 错误处理规范

# 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 门禁工具链(强制执行)

# .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 命名与类型规范

# 类名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步法

# 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开发规范

# 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 工具开发规范

# 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)}

六、最小可执行骨架

# 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 日志规范

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即止。