# Steering Agent 规划文档 > ✅ **状态**: 实施完成 > 📅 **完成时间**: 2026-02-24 ## 1. 项目概述 ### 1.1 定位 **Steering Agent** 是一个项目约束管理Agent,用于: - 从代码库自动提取项目知识(技术栈、规范、模式) - 管理用户定义的项目规则 - 在代码生成前提供上下文约束 - 在代码生成后进行合规性检查 ### 1.2 核心价值 | 价值 | 说明 | |------|------| | **持久的项目知识** | 自动提取并维护项目的技术栈、规范、模式等信息 | | **一致的代码生成** | 确保 AI 生成的代码符合项目既有风格和规范 | | **减少重复解释** | 一次定义规则,所有代码生成自动遵循 | ### 1.3 工作流程 ```mermaid flowchart TB subgraph Extract["知识提取"] A[代码库] --> B[自动分析] B --> C[技术栈信息] B --> D[命名规范] B --> E[目录结构] B --> F[代码模式] end subgraph Define["规则定义"] G[用户输入] --> H[业务规则] G --> I[技术规则] G --> J[安全规则] G --> K[架构规则] end subgraph Merge["知识合并"] C --> L[项目上下文] D --> L E --> L F --> L H --> L I --> L J --> L K --> L end subgraph Use["使用场景"] L --> M[生成前: 提供上下文] L --> N[生成后: 合规检查] end M --> O[specs_agent] M --> P[code_agent] N --> Q[format_police_agent] ``` --- ## 2. 功能设计 ### 2.1 知识提取(自动) 从代码库自动提取以下信息: | 类别 | 提取内容 | 来源 | |------|---------|------| | **技术栈** | 语言、框架、版本 | requirements.txt, package.json, Dockerfile | | **目录结构** | 项目布局、模块划分 | 文件系统扫描 | | **命名规范** | 文件命名、变量命名、函数命名 | 代码文件分析 | | **代码模式** | 常用模式、设计模式 | 代码文件分析 | | **依赖关系** | 内部依赖、外部依赖 | import 语句分析 | | **配置规范** | 环境变量、配置文件格式 | 配置文件分析 | #### 2.1.1 技术栈提取详细设计 **提取来源与方法**: ```python # tech_stack.py - 技术栈提取器 class TechStackExtractor: """技术栈信息提取器""" def extract(self, project_path: str) -> dict: return { "language": self._detect_language(project_path), "framework": self._detect_frameworks(project_path), "dependencies": self._extract_dependencies(project_path), "runtime": self._detect_runtime(project_path) } ``` | 检测项 | 检测方法 | 检测文件 | |--------|---------|---------| | **Python 版本** | 解析 Dockerfile 的 FROM 语句 | `Dockerfile` | | **Python 依赖** | 解析 requirements.txt | `requirements.txt` | | **框架检测** | 检查依赖中的框架关键词 | `requirements.txt` | | **Node.js 版本** | 解析 package.json 的 engines | `package.json` | | **Node.js 依赖** | 解析 dependencies | `package.json` | **框架检测规则**: ```python FRAMEWORK_PATTERNS = { # Python 框架 "fastapi": "FastAPI", "flask": "Flask", "django": "Django", "pydantic-ai": "Pydantic AI", "fastmcp": "FastMCP", "mcp": "MCP", # Node.js 框架 "express": "Express", "next": "Next.js", "react": "React", "vue": "Vue.js" } ``` **输出示例**: ```json { "language": { "name": "Python", "version": "3.12", "source": "Dockerfile" }, "framework": [ {"name": "FastAPI", "version": ">=0.109.0"}, {"name": "Pydantic AI", "version": ">=0.0.14"}, {"name": "FastMCP", "version": ">=0.1.0"} ], "dependencies": { "production": [ "pydantic-ai>=0.0.14", "mcp>=0.9.0", "fastmcp>=0.1.0", "fastapi>=0.109.0", "uvicorn[standard]>=0.27.0", "aiohttp>=3.9.0" ], "development": [] }, "runtime": { "container": "Docker", "base_image": "python:3.12-slim" } } ``` --- #### 2.1.2 目录结构提取详细设计 **提取方法**: ```python # structure.py - 目录结构提取器 class StructureExtractor: """项目结构提取器""" # 忽略的目录和文件 IGNORE_PATTERNS = [ "__pycache__", ".git", ".venv", "node_modules", "*.pyc", "*.pyo", ".DS_Store", "*.egg-info" ] def extract(self, project_path: str) -> dict: return { "root_files": self._get_root_files(project_path), "directories": self._get_directory_tree(project_path), "key_files": self._identify_key_files(project_path), "pattern": self._detect_project_pattern(project_path) } ``` **项目模式检测**: | 模式名称 | 检测条件 | |---------|---------| | `agent_templates` | 存在 `src/server/mcp_server.py` 和 `src/server/api_server.py` | | `fastapi_standard` | 存在 `main.py` 或 `app.py` + FastAPI 依赖 | | `python_package` | 存在 `setup.py` 或 `pyproject.toml` | | `monorepo` | 存在多个独立的子项目目录 | **输出示例**: ```json { "root_files": [ "Dockerfile", "README.md", "requirements.txt", "run_api_server.py" ], "directories": { "src": { "__init__.py": "file", "server": { "__init__.py": "file", "api_server.py": "file", "mcp_server.py": "file" } } }, "key_files": { "entry_point": "run_api_server.py", "mcp_tools": "src/server/mcp_server.py", "api_routes": "src/server/api_server.py", "dependencies": "requirements.txt", "container": "Dockerfile" }, "pattern": { "name": "agent_templates", "description": "基于 Pydantic AI 的 Agent 模板结构", "confidence": 0.95 } } ``` --- #### 2.1.3 命名规范提取详细设计 **提取方法**: ```python # naming.py - 命名规范提取器 import ast import re class NamingExtractor: """命名规范提取器""" def extract(self, project_path: str) -> dict: # 收集所有 Python 文件中的命名 names = self._collect_names(project_path) return { "files": self._analyze_file_naming(project_path), "classes": self._analyze_pattern(names["classes"]), "functions": self._analyze_pattern(names["functions"]), "variables": self._analyze_pattern(names["variables"]), "constants": self._analyze_pattern(names["constants"]) } def _analyze_pattern(self, names: list) -> dict: """分析命名模式""" patterns = { "snake_case": 0, "camelCase": 0, "PascalCase": 0, "UPPER_SNAKE_CASE": 0 } for name in names: if re.match(r'^[a-z][a-z0-9_]*$', name): patterns["snake_case"] += 1 elif re.match(r'^[a-z][a-zA-Z0-9]*$', name): patterns["camelCase"] += 1 elif re.match(r'^[A-Z][a-zA-Z0-9]*$', name): patterns["PascalCase"] += 1 elif re.match(r'^[A-Z][A-Z0-9_]*$', name): patterns["UPPER_SNAKE_CASE"] += 1 # 返回最常用的模式 dominant = max(patterns, key=patterns.get) return { "dominant_pattern": dominant, "distribution": patterns, "consistency": patterns[dominant] / sum(patterns.values()) if sum(patterns.values()) > 0 else 0 } ``` **使用 AST 解析 Python 代码**: ```python def _collect_names(self, project_path: str) -> dict: """使用 AST 收集代码中的命名""" names = { "classes": [], "functions": [], "variables": [], "constants": [] } for py_file in self._find_python_files(project_path): try: with open(py_file, 'r') as f: tree = ast.parse(f.read()) for node in ast.walk(tree): if isinstance(node, ast.ClassDef): names["classes"].append(node.name) elif isinstance(node, ast.FunctionDef): names["functions"].append(node.name) elif isinstance(node, ast.Assign): for target in node.targets: if isinstance(target, ast.Name): # 全大写视为常量 if target.id.isupper(): names["constants"].append(target.id) else: names["variables"].append(target.id) except: continue return names ``` **输出示例**: ```json { "files": { "dominant_pattern": "snake_case", "examples": ["api_server.py", "mcp_server.py", "run_api_server.py"], "consistency": 1.0 }, "classes": { "dominant_pattern": "PascalCase", "distribution": {"PascalCase": 15, "snake_case": 0}, "examples": ["FastMCP", "Agent", "QueryRequest", "QueryResponse"], "consistency": 1.0 }, "functions": { "dominant_pattern": "snake_case", "distribution": {"snake_case": 45, "camelCase": 2}, "examples": ["get_agent", "handle_mcp_request", "verify_api_key"], "consistency": 0.96 }, "variables": { "dominant_pattern": "snake_case", "distribution": {"snake_case": 120, "camelCase": 5}, "consistency": 0.96 }, "constants": { "dominant_pattern": "UPPER_SNAKE_CASE", "examples": ["MODEL_NAME", "SYSTEM_PROMPT", "TOOL_MAP", "TOOL_LIST"], "consistency": 1.0 } } ``` --- #### 2.1.4 代码模式提取详细设计 **提取方法**: ```python # patterns.py - 代码模式提取器 class PatternExtractor: """代码模式提取器""" def extract(self, project_path: str) -> dict: return { "async_usage": self._analyze_async_usage(project_path), "error_handling": self._analyze_error_handling(project_path), "logging": self._analyze_logging(project_path), "imports": self._analyze_import_style(project_path), "docstrings": self._analyze_docstrings(project_path), "type_hints": self._analyze_type_hints(project_path), "common_patterns": self._detect_common_patterns(project_path) } ``` **检测的模式类型**: | 模式类型 | 检测方法 | 输出 | |---------|---------|------| | **异步使用** | 检测 async/await 关键字 | 是否强制异步、异步函数比例 | | **错误处理** | 检测 try-except 模式 | 错误处理风格、是否返回 JSON 错误 | | **日志方式** | 检测 print/logging 使用 | 日志库、日志格式 | | **导入风格** | 分析 import 语句 | 绝对导入/相对导入比例 | | **文档字符串** | 检测 docstring 存在 | docstring 覆盖率、格式风格 | | **类型提示** | 检测类型注解 | 类型提示覆盖率 | **常见模式检测**: ```python COMMON_PATTERNS = { "mcp_tool_pattern": { "description": "MCP 工具定义模式", "signature": "@server.tool()", "return_type": "JSON string" }, "fastapi_endpoint_pattern": { "description": "FastAPI 端点模式", "signature": "@app.get/post/put/delete", "features": ["async", "type hints", "docstring"] }, "pydantic_model_pattern": { "description": "Pydantic 模型模式", "signature": "class XxxModel(BaseModel)", "features": ["Field definitions", "validators"] }, "singleton_agent_pattern": { "description": "Agent 单例模式", "signature": "def get_agent() -> Agent", "purpose": "每次调用创建新 Agent 实例" } } ``` **输出示例**: ```json { "async_usage": { "async_required": true, "async_function_ratio": 0.85, "await_usage": "consistent" }, "error_handling": { "style": "try-except-json-response", "pattern": "返回包含 success/error 字段的 JSON", "example": "return json.dumps({\"success\": False, \"error\": str(e)})" }, "logging": { "method": "print", "format": "emoji_prefix", "examples": ["🚀 启动", "🛑 关闭"] }, "imports": { "style": "absolute", "relative_import_ratio": 0.1, "common_imports": ["json", "os", "typing", "fastapi", "pydantic"] }, "docstrings": { "coverage": 0.78, "style": "google", "required_sections": ["Args", "Returns"] }, "type_hints": { "coverage": 0.92, "return_type_coverage": 0.95, "parameter_type_coverage": 0.90 }, "common_patterns": [ { "name": "mcp_tool_pattern", "occurrences": 7, "files": ["src/server/mcp_server.py"] }, { "name": "fastapi_endpoint_pattern", "occurrences": 12, "files": ["src/server/api_server.py"] } ] } ``` --- #### 2.1.5 配置规范提取详细设计 **提取方法**: ```python # config.py - 配置规范提取器 class ConfigExtractor: """配置规范提取器""" def extract(self, project_path: str) -> dict: return { "env_variables": self._extract_env_variables(project_path), "config_files": self._analyze_config_files(project_path), "secrets_handling": self._analyze_secrets_handling(project_path) } def _extract_env_variables(self, project_path: str) -> list: """从代码中提取使用的环境变量""" env_vars = [] # 匹配 os.getenv() 和 os.environ.get() patterns = [ r"os\.getenv\(['\"](\w+)['\"]", r"os\.environ\.get\(['\"](\w+)['\"]", r"os\.environ\[['\"](\w+)['\"]\]" ] for py_file in self._find_python_files(project_path): content = open(py_file).read() for pattern in patterns: matches = re.findall(pattern, content) env_vars.extend(matches) return list(set(env_vars)) ``` **输出示例**: ```json { "env_variables": [ { "name": "OPENAI_API_KEY", "required": true, "default": null, "description": "OpenAI API Key" }, { "name": "OPENAI_BASE_URL", "required": false, "default": "https://litellm...", "description": "API Base URL" }, { "name": "MODEL_NAME", "required": false, "default": "taiji/gpt-4o-mini", "description": "模型名称" }, { "name": "API_PORT", "required": false, "default": "8000", "description": "服务端口" } ], "config_files": [ { "file": "Dockerfile", "type": "docker", "purpose": "容器配置" }, { "file": "requirements.txt", "type": "python_deps", "purpose": "Python 依赖" } ], "secrets_handling": { "hardcoded_secrets": false, "env_based": true, "pattern": "os.getenv with fallback" } } ``` ### 2.2 规则定义(用户) 用户可定义以下类型的规则: | 规则类型 | 示例 | |---------|------| | **业务规则** | "所有 Agent 必须实现健康检查端点" | | **技术规则** | "必须使用 async/await 进行异步操作" | | **安全规则** | "禁止硬编码 API Key 或密码" | | **架构规则** | "MCP 工具必须定义在 mcp_server.py 中" | | **禁止事项** | "禁止使用 print 进行日志输出" | | **必须遵循** | "所有函数必须有 docstring" | ### 2.3 输出格式 #### 2.3.1 给 AI Agent 的结构化上下文(JSON) ```json { "project_context": { "name": "pingtai_agent", "type": "agent_platform", "tech_stack": { "language": "Python 3.12", "framework": ["FastAPI", "Pydantic AI", "FastMCP"], "dependencies": ["pydantic-ai>=0.0.14", "fastapi>=0.109.0"] }, "structure": { "pattern": "agent_templates", "directories": ["src/", "src/server/"], "key_files": ["mcp_server.py", "api_server.py", "run_api_server.py"] } }, "naming_conventions": { "files": "snake_case", "classes": "PascalCase", "functions": "snake_case", "constants": "UPPER_SNAKE_CASE" }, "code_patterns": { "async_required": true, "error_handling": "try-except with JSON response", "logging": "print statements with emoji prefix" }, "rules": { "must": [ "所有 MCP 工具必须返回 JSON 格式", "所有 API 端点必须有 docstring", "必须实现 /health 健康检查端点" ], "must_not": [ "禁止硬编码 API Key", "禁止使用同步阻塞操作", "禁止在工具函数中直接抛出异常" ], "prefer": [ "优先使用 Pydantic 模型定义请求/响应", "优先使用环境变量配置" ] } } ``` #### 2.3.2 给人类阅读的 Markdown 文档 ```markdown # 项目规范文档: pingtai_agent ## 技术栈 - **语言**: Python 3.12 - **框架**: FastAPI, Pydantic AI, FastMCP - **依赖**: pydantic-ai>=0.0.14, fastapi>=0.109.0 ## 目录结构规范 [agent_name]/ ├── Dockerfile ├── README.md ├── requirements.txt ├── run_api_server.py └── src/server/ ├── api_server.py └── mcp_server.py ## 命名规范 - 文件名: snake_case - 类名: PascalCase - 函数名: snake_case ## 必须遵循的规则 1. 所有 MCP 工具必须返回 JSON 格式 2. 所有 API 端点必须有 docstring ... ## 禁止事项 1. 禁止硬编码 API Key 2. 禁止使用同步阻塞操作 ... ``` --- ## 3. MCP 工具设计 ### 3.1 工具清单 | 工具名称 | 功能 | 阶段 | |---------|------|------| | `extract_project_knowledge` | 从代码库提取项目知识 | 知识提取 | | `add_rule` | 添加用户定义规则 | 规则定义 | | `remove_rule` | 移除规则 | 规则定义 | | `list_rules` | 列出所有规则 | 规则定义 | | `get_context` | 获取完整项目上下文 | 使用 | | `check_compliance` | 检查代码是否符合规则 | 检查 | | `generate_steering_doc` | 生成人类可读的规范文档 | 输出 | ### 3.2 工具详细设计 #### 3.2.1 extract_project_knowledge ```python async def extract_project_knowledge( project_path: str, # 项目路径 include_patterns: Optional[List[str]] = None, # 包含的文件模式 exclude_patterns: Optional[List[str]] = None # 排除的文件模式 ) -> str: """ 从代码库自动提取项目知识。 提取内容: - 技术栈信息(从 requirements.txt, Dockerfile 等) - 目录结构 - 命名规范(分析现有代码) - 代码模式(分析现有代码) Returns: 提取的项目知识(JSON 格式) """ ``` #### 3.2.2 add_rule ```python async def add_rule( rule_type: str, # 规则类型: must/must_not/prefer/security/architecture rule_content: str, # 规则内容 category: Optional[str] = None, # 分类标签 priority: Optional[str] = "normal" # 优先级: high/normal/low ) -> str: """ 添加用户定义的规则。 Returns: 添加结果(JSON 格式) """ ``` #### 3.2.3 get_context ```python async def get_context( output_format: str = "json", # 输出格式: json/markdown include_rules: bool = True, # 是否包含规则 include_patterns: bool = True # 是否包含代码模式 ) -> str: """ 获取完整的项目上下文,用于提供给其他 AI Agent。 Returns: 项目上下文(JSON 或 Markdown 格式) """ ``` #### 3.2.4 check_compliance ```python async def check_compliance( code: str, # 待检查的代码 file_type: Optional[str] = None, # 文件类型 strict_mode: bool = False # 严格模式 ) -> str: """ 检查代码是否符合项目规则。 Returns: 检查结果(JSON 格式),包含: - 是否通过 - 违反的规则列表 - 修改建议 """ ``` #### 3.2.5 generate_steering_doc ```python async def generate_steering_doc( output_format: str = "markdown", # 输出格式 include_examples: bool = True # 是否包含示例 ) -> str: """ 生成人类可读的项目规范文档。 Returns: 规范文档(Markdown 格式) """ ``` --- ## 4. 与其他 Agent 的协作 ### 4.1 协作流程 ```mermaid sequenceDiagram participant User as 用户 participant Steering as Steering Agent participant Specs as Specs Agent participant Code as Code Agent participant Format as Format Police User->>Steering: 1. 提取项目知识 Steering-->>Steering: 分析代码库 Steering-->>User: 返回项目上下文 User->>Steering: 2. 添加自定义规则 Steering-->>User: 规则已添加 User->>Steering: 3. 获取完整上下文 Steering-->>Specs: 提供项目上下文 User->>Specs: 4. 生成需求文档 Specs-->>User: 需求文档(遵循上下文约束) User->>Code: 5. 生成代码 Code-->>Steering: 请求上下文 Steering-->>Code: 提供约束规则 Code-->>User: 生成的代码 User->>Steering: 6. 检查代码合规性 Steering-->>Format: 格式检查 Format-->>Steering: 格式检查结果 Steering-->>User: 合规性报告 ``` ### 4.2 与 specs_agent 配合 - Steering Agent 提供项目上下文给 specs_agent - specs_agent 在生成需求/设计文档时遵循项目约束 - 确保生成的规范符合现有项目风格 ### 4.3 与 format_police_agent 配合 - Steering Agent 调用 format_police 检查输出格式 - format_police 确保所有输出是有效 JSON - Steering Agent 在合规检查中集成格式检查 --- ## 5. 项目结构 ``` steering_agent/ ├── Dockerfile ├── README.md ├── USAGE.md ├── requirements.txt ├── run_api_server.py └── src/ ├── __init__.py └── server/ ├── __init__.py ├── api_server.py # FastAPI + MCP HTTP ├── mcp_server.py # MCP 工具定义 ├── extractors/ # 知识提取器 │ ├── __init__.py │ ├── tech_stack.py # 技术栈提取 │ ├── structure.py # 结构提取 │ ├── naming.py # 命名规范提取 │ └── patterns.py # 代码模式提取 └── rules/ # 规则管理 ├── __init__.py ├── rule_store.py # 规则存储 └── checker.py # 合规检查器 ``` --- ## 6. API 端点设计 | 端点 | 方法 | 描述 | |------|------|------| | `/` | GET | 服务状态 | | `/health` | GET | 健康检查 | | `/mcp` | POST | MCP JSON-RPC | | `/mcp/sse` | GET/POST | MCP SSE 流式 | | `/api/v1/extract` | POST | 提取项目知识 | | `/api/v1/rules` | GET | 列出所有规则 | | `/api/v1/rules` | POST | 添加规则 | | `/api/v1/rules/{id}` | DELETE | 删除规则 | | `/api/v1/context` | GET | 获取项目上下文 | | `/api/v1/check` | POST | 检查代码合规性 | | `/api/v1/doc` | GET | 生成规范文档 | --- ## 7. 使用示例 ### 7.1 提取项目知识 **输入**: ```bash curl -X POST http://localhost:8000/api/v1/extract \ -H "api-key: your-key" \ -d '{"project_path": "/path/to/project"}' ``` **输出**: ```json { "success": true, "knowledge": { "tech_stack": { "language": "Python 3.12", "framework": ["FastAPI", "Pydantic AI"], "dependencies": [...] }, "structure": { "pattern": "agent_templates", "directories": ["src/", "src/server/"] }, "naming": { "files": "snake_case", "classes": "PascalCase" } } } ``` ### 7.2 添加规则 **输入**: ```bash curl -X POST http://localhost:8000/api/v1/rules \ -H "api-key: your-key" \ -d '{ "rule_type": "must", "rule_content": "所有 MCP 工具必须返回 JSON 格式", "category": "output" }' ``` ### 7.3 获取上下文(给 AI Agent) **输入**: ```bash curl http://localhost:8000/api/v1/context?format=json ``` **输出**: 完整的项目上下文 JSON,可直接作为其他 Agent 的 system prompt 补充。 ### 7.4 检查代码合规性 **输入**: ```bash curl -X POST http://localhost:8000/api/v1/check \ -H "api-key: your-key" \ -d '{ "code": "def my_tool():\n print(\"hello\")\n return \"result\"", "file_type": "python" }' ``` **输出**: ```json { "compliant": false, "violations": [ { "rule": "所有 MCP 工具必须返回 JSON 格式", "severity": "error", "suggestion": "使用 json.dumps() 返回 JSON 字符串" }, { "rule": "禁止使用 print 进行日志输出", "severity": "warning", "suggestion": "使用 logging 模块或移除 print" } ] } ``` --- ## 8. 实施计划 ### 8.1 开发任务清单 - [x] 创建项目目录结构 - [x] 实现知识提取器 - [x] 技术栈提取 (tech_stack.py) - [x] 结构提取 (structure.py) - [x] 命名规范提取 (naming.py) - [x] 代码模式提取 (patterns.py) - [x] 配置规范提取 (config.py) - [x] 实现规则管理 - [x] 规则存储 (rule_store.py) - [x] 合规检查器 (checker.py) - [x] 实现 MCP 工具 - [x] extract_project_knowledge - [x] add_rule / remove_rule / list_rules - [x] get_context - [x] check_compliance - [x] generate_steering_doc - [x] 实现 API 端点 - [x] 编写文档 - [ ] 测试验证 --- ## 9. 已确认事项 1. **规则持久化**:仅内存存储 ✅ 2. **项目路径**:仅支持本地路径 ✅ 3. **增量更新**:每次全量提取 ✅ 4. **规则模板**:不提供预设模板 ✅ --- ## 10. 风险与注意事项 1. **代码分析准确性**:自动提取的命名规范和代码模式可能不够准确,需要用户确认 2. **性能考虑**:大型代码库的分析可能耗时较长,需要考虑异步处理 3. **规则冲突**:用户定义的规则可能与提取的规范冲突,需要优先级机制 4. **上下文长度**:完整的项目上下文可能很长,需要考虑 token 限制 --- ## 11. 已创建文件清单 ``` steering_agent/ ├── Dockerfile ✅ ├── README.md ✅ ├── USAGE.md ✅ ├── requirements.txt ✅ ├── run_api_server.py ✅ └── src/ ├── __init__.py ✅ └── server/ ├── __init__.py ✅ ├── api_server.py ✅ ├── mcp_server.py ✅ ├── extractors/ │ ├── __init__.py ✅ │ ├── tech_stack.py ✅ │ ├── structure.py ✅ │ ├── naming.py ✅ │ ├── patterns.py ✅ │ └── config.py ✅ └── rules/ ├── __init__.py ✅ ├── rule_store.py ✅ └── checker.py ✅ ```