🧩 OpenClaw Agent 代码生成器蓝图

代码生成 自动化编程 模板引擎 OpenClaw

世界上有两种程序员——一种手写代码,一种让Agent生成代码。凌晨1点42分,我看着Agent自动生成的第100个API接口,突然明白:代码生成器不是替代程序员,是让程序员从重复劳动中解放出来。

Agent代码生成器是AI辅助编程的核心组件,它能够根据需求描述、API文档、数据模型自动生成高质量代码。本教程提供完整的代码生成器架构蓝图,涵盖模板引擎、代码质量检查、多语言支持等核心模块。

🎯 代码生成器架构

┌─────────────────────────────────────────────────────┐
│            Agent Code Generator System              │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐      │
│  │ 需求解析 │───▶│ 模板引擎 │───▶│ 代码生成 │      │
│  └──────────┘    └──────────┘    └──────────┘      │
│        │                │                │          │
│        ▼                ▼                ▼          │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐      │
│  │ 上下文管理│    │ 代码片段库│    │ 质量检查 │      │
│  └──────────┘    └──────────┘    └──────────┘      │
│                                   │                │
│                                   ▼                │
│                            ┌──────────┐            │
│                            │ 输出格式化│            │
│                            └──────────┘            │
└─────────────────────────────────────────────────────┘

📦 核心模块实现

1. 需求解析器

from dataclasses import dataclass
from typing import List, Dict, Optional
import re

@dataclass
class CodeRequirement:
    """代码需求描述"""
    language: str           # python, javascript, go, etc.
    framework: Optional[str] # flask, react, gin, etc.
    task_type: str         # api, crud, middleware, etc.
    description: str       # 自然语言描述
    inputs: List[Dict]     # 输入参数
    outputs: List[Dict]    # 输出格式
    dependencies: List[str] # 依赖库

class RequirementParser:
    """需求解析器 - 将自然语言转换为结构化需求"""
    
    def parse(self, description: str) -> CodeRequirement:
        """解析自然语言需求"""
        
        # 1. 检测目标语言
        language = self._detect_language(description)
        
        # 2. 检测框架
        framework = self._detect_framework(description, language)
        
        # 3. 识别任务类型
        task_type = self._detect_task_type(description)
        
        # 4. 提取输入输出
        inputs, outputs = self._extract_io(description)
        
        # 5. 推断依赖
        dependencies = self._infer_dependencies(language, framework, task_type)
        
        return CodeRequirement(
            language=language,
            framework=framework,
            task_type=task_type,
            description=description,
            inputs=inputs,
            outputs=outputs,
            dependencies=dependencies
        )
    
    def _detect_language(self, desc: str) -> str:
        """检测编程语言"""
        lang_keywords = {
            "python": ["python", "py", "django", "flask", "fastapi"],
            "javascript": ["javascript", "js", "node", "react", "vue"],
            "go": ["go", "golang", "gin", "echo"],
            "rust": ["rust", "cargo", "tokio"]
        }
        desc_lower = desc.lower()
        for lang, keywords in lang_keywords.items():
            if any(kw in desc_lower for kw in keywords):
                return lang
        return "python"  # 默认
    
    def _detect_task_type(self, desc: str) -> str:
        """检测任务类型"""
        if "api" in desc.lower() or "接口" in desc:
            return "api"
        elif "crud" in desc.lower() or "增删改查" in desc:
            return "crud"
        elif "middleware" in desc.lower() or "中间件" in desc:
            return "middleware"
        else:
            return "function"

2. 模板引擎

from jinja2 import Template, Environment, FileSystemLoader
import os

class CodeTemplateEngine:
    """代码模板引擎"""
    
    def __init__(self, template_dir: str = "templates"):
        self.env = Environment(
            loader=FileSystemLoader(template_dir),
            trim_blocks=True,
            lstrip_blocks=True
        )
        self._register_filters()
    
    def _register_filters(self):
        """注册自定义过滤器"""
        self.env.filters['camel_case'] = lambda s: ''.join(
            word.capitalize() for word in s.split('_')
        )
        self.env.filters['snake_case'] = lambda s: re.sub(
            r'(? str:
        """渲染模板"""
        template = self.env.get_template(template_name)
        return template.render(**context)

# 示例模板:Python Flask API
# templates/python/flask_api.py.j2
"""
from flask import Flask, request, jsonify
from pydantic import BaseModel

app = Flask(__name__)

class {{ input_model }}(BaseModel):
{% for field in inputs %}
    {{ field.name }}: {{ field.type }}
{% endfor %}

@app.route('/{{ endpoint }}', methods=['{{ method }}'])
def {{ function_name }}():
    \"\"\"{{ description }}\"\"\"
    try:
        data = request.get_json()
        validated = {{ input_model }}(**data)
        
        # TODO: 实现业务逻辑
        result = {"status": "success", "data": data}
        
        return jsonify(result), 200
    except Exception as e:
        return jsonify({"error": str(e)}), 400

if __name__ == '__main__':
    app.run(debug=True)
"""

3. 代码质量检查器

import ast
import pylint.lint
from typing import List, Dict

class CodeQualityChecker:
    """代码质量检查器"""
    
    def check(self, code: str, language: str) -> Dict:
        """检查代码质量"""
        if language == "python":
            return self._check_python(code)
        elif language == "javascript":
            return self._check_javascript(code)
        else:
            return {"score": 0, "issues": ["Unsupported language"]}
    
    def _check_python(self, code: str) -> Dict:
        """Python代码检查"""
        issues = []
        score = 100
        
        # 1. 语法检查
        try:
            ast.parse(code)
        except SyntaxError as e:
            issues.append(f"语法错误: {e}")
            score -= 50
        
        # 2. 代码风格检查(简化版)
        lines = code.split('\n')
        for i, line in enumerate(lines, 1):
            if len(line) > 120:
                issues.append(f"第{i}行超过120字符")
                score -= 2
            if line.strip().startswith('except:') or line.strip() == 'except:':
                issues.append(f"第{i}行使用裸except,应指定异常类型")
                score -= 10
        
        # 3. Pylint检查(可选)
        # pylint.lint.Run(['--from-stdin', '--disable=all', '--enable=W,C'], exit=False)
        
        return {
            "score": max(0, score),
            "issues": issues,
            "passed": score >= 80
        }

4. 完整代码生成器

class AgentCodeGenerator:
    """Agent代码生成器 - 完整实现"""
    
    def __init__(self):
        self.parser = RequirementParser()
        self.template_engine = CodeTemplateEngine()
        self.quality_checker = CodeQualityChecker()
    
    async def generate(self, description: str) -> Dict:
        """生成代码"""
        
        # 1. 解析需求
        requirement = self.parser.parse(description)
        print(f"✅ 需求解析完成: {requirement.task_type} in {requirement.language}")
        
        # 2. 选择模板
        template_name = self._select_template(requirement)
        
        # 3. 准备上下文
        context = self._prepare_context(requirement)
        
        # 4. 渲染代码
        code = self.template_engine.render(template_name, context)
        
        # 5. 质量检查
        quality = self.quality_checker.check(code, requirement.language)
        
        # 6. 优化(如果质量不达标)
        if not quality["passed"]:
            print(f"⚠️ 代码质量分数 {quality['score']},尝试优化...")
            code = await self._optimize_code(code, requirement, quality)
        
        return {
            "code": code,
            "language": requirement.language,
            "framework": requirement.framework,
            "quality_score": quality["score"],
            "issues": quality["issues"],
            "dependencies": requirement.dependencies
        }
    
    def _select_template(self, req: CodeRequirement) -> str:
        """选择模板"""
        template_map = {
            ("python", "api"): "python/flask_api.py.j2",
            ("python", "crud"): "python/crud_api.py.j2",
            ("javascript", "api"): "javascript/express_api.js.j2",
            ("go", "api"): "go/gin_api.go.j2"
        }
        return template_map.get(
            (req.language, req.task_type),
            "python/basic_function.py.j2"
        )
    
    def _prepare_context(self, req: CodeRequirement) -> Dict:
        """准备模板上下文"""
        return {
            "function_name": self._generate_function_name(req.description),
            "endpoint": self._extract_endpoint(req.description),
            "method": self._extract_method(req.description),
            "inputs": req.inputs,
            "outputs": req.outputs,
            "description": req.description,
            "input_model": "InputModel",
            "output_model": "OutputModel"
        }

⚙️ 使用示例

async def main():
    generator = AgentCodeGenerator()
    
    # 生成Flask API
    result = await generator.generate(
        "用Python Flask创建一个用户登录API,接收用户名和密码,返回token"
    )
    
    print(f"语言: {result['language']}")
    print(f"质量分数: {result['quality_score']}")
    print(f"代码:\n{result['code']}")
    
    # 保存到文件
    with open(f"generated_api.py", "w") as f:
        f.write(result['code'])
    
    print("✅ 代码已保存到 generated_api.py")

# 输出示例:
# 语言: python
# 质量分数: 92
# 代码:
# from flask import Flask, request, jsonify
# ...
# ✅ 代码已保存到 generated_api.py

🏆 最佳实践

✅ 最佳实践1:模板设计原则

✅ 最佳实践2:质量保障

⚠️ 常见陷阱

🔗 相关链接

凌晨3点,我的代码生成器帮我写完了整个RESTful API。我看着代码,突然觉得:这不就是我想要的「自动化」吗?不是替代我思考,而是替我完成那些我已经想清楚但懒得手写的重复工作。然后我关了电脑,去睡了——毕竟,代码生成器不会失眠,但我会。