MonkeyCode做代码生成器:从模板引擎到AI辅助的完整实战
重复代码是程序员的天敌。MonkeyCode不仅能帮你写代码,还能帮你造"写代码的工具"——代码生成器。
代码生成器的价值
程序员的时间分配:
写新代码:30%
写重复代码:40% ← 这里可以优化!
调试代码:30%
代码生成器把40%的重复劳动变成1次模板配置。
场景1:CRUD代码生成器
痛点
每个数据表都要写:Model、Schema、CURD接口、单元测试……全是模板代码。
让MonkeyCode生成CRUD生成器
# generate_crud.py - 命令行工具
import yaml
import jinja2
import os
from pathlib import Path
# ─── 模板引擎 ───
env = jinja2.Environment(
loader=jinja2.FileSystemLoader("templates/"),
trim_blocks=True,
lstrip_blocks=True
)
# ─── 模型定义(YAML)───
"""
# schema/user.yaml
model: User
table: users
fields:
- name: id
type: int
primary_key: true
auto_increment: true
- name: email
type: str
unique: true
nullable: false
- name: nickname
type: str
nullable: true
- name: created_at
type: datetime
default: "now()"
"""
def load_schema(yaml_path: str) -> dict:
with open(yaml_path) as f:
return yaml.safe_load(f)
def generate_model(schema: dict) -> str:
"""生成SQLAlchemy Model"""
template = env.get_template("model.py.j2")
return template.render(schema=schema)
def generate_router(schema: dict) -> str:
"""生成FastAPI Router"""
template = env.get_template("router.py.j2")
return template.render(schema=schema)
def generate_schemas(schema: dict) -> str:
"""生成Pydantic Schema"""
template = env.get_template("schemas.py.j2")
return template.render(schema=schema)
def generate_tests(schema: dict) -> str:
"""生成pytest单元测试"""
template = env.get_template("tests.py.j2")
return template.render(schema=schema)
def generate_all(schema_path: str, output_dir: str):
schema = load_schema(schema_path)
model_name = schema["model"]
base = Path(output_dir) / model_name.lower()
base.mkdir(parents=True, exist_ok=True)
(base / "model.py").write_text(generate_model(schema))
(base / "router.py").write_text(generate_router(schema))
(base / "schemas.py").write_text(generate_schemas(schema))
(base / "tests.py").write_text(generate_tests(schema))
print(f"✅ 生成完成:{base}/")
if __name__ == "__main__":
import sys
generate_all(sys.argv[1], sys.argv[2])
Jinja2模板示例
{# templates/model.py.j2 #}
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class {{ schema.model }}(Base):
__tablename__ = "{{ schema.table }}"
{% for field in schema.fields %}
{{ field.name }} = Column(
{% if field.type == 'int' %}Integer()
{% elif field.type == 'str' %}String()
{% elif field.type == 'datetime' %}DateTime()
{% endif %}
{% if field.primary_key %}, primary_key=True{% endif %}
{% if field.auto_increment %}, autoincrement=True{% endif %}
{% if field.unique %}, unique=True{% endif %}
{% if field.nullable == false %}, nullable=False{% endif %}
)
{% endfor %}
{# templates/router.py.j2 #}
from fastapi import APIRouter, Depends
from pydantic import BaseModel
router = APIRouter(prefix="/{{ schema.table }}")
@router.post("/")
async def create_{{ schema.table | singular }}(data: {{ schema.model }}Create):
# TODO: 实现创建逻辑
return {"id": 1}
@router.get("/")
async def list_{{ schema.table }}(skip: int = 0, limit: int = 100):
# TODO: 实现列表查询
return []
@router.get("/{id}")
async def get_{{ schema.table | singular }}(id: int):
# TODO: 实现单条查询
return {"id": id}
@router.put("/{id}")
async def update_{{ schema.table | singular }}(id: int, data: {{ schema.model }}Update):
# TODO: 实现更新
return {"id": id}
@router.delete("/{id}")
async def delete_{{ schema.table | singular }}(id: int):
# TODO: 实现删除
return {"deleted": True}
使用
python generate_crud.py schema/user.yaml ./app/
# 输出:
# ✅ 生成完成:./app/user/
# ├── model.py
# ├── router.py
# ├── schemas.py
# └── tests.py
场景2:GraphQL代码生成
GraphQL有一堆Boilerplate代码,用graphql-code-generator自动生成:
# codegen.yml
overwrite: true
schema: "http://localhost:8000/graphql"
documents: "src/**/*.graphql"
generates:
src/generated/types.ts:
plugins:
- "typescript"
- "typescript-operations"
- "typescript-react-apollo"
src/generated/api.ts:
plugins:
- "typescript-generator"
运行 npx graphql-codegen,自动生成TypeScript类型定义和API调用代码。
场景3:Protocol Buffers + gRPC
// api/order.proto
syntax = "proto3";
package order.v1;
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (CreateOrderResponse);
rpc GetOrder (GetOrderRequest) returns (GetOrderResponse);
}
message CreateOrderRequest {
string user_id = 1;
repeated OrderItem items = 2;
}
message OrderItem {
string sku = 1;
int32 qty = 2;
}
生成Python代码:
python -m grpc_tools.protoc \
-I. \
--python_out=. \
--grpc_python_out=. \
api/order.proto
场景4:AI辅助代码生成器(Swagger/OpenAPI)
从OpenAPI Spec自动生成SDK:
# 安装openapi-generator
# npm install @openapitools/openapi-generator-cli -g
# 生成Python SDK
openapi-generator-cli generate \
-i http://localhost:8000/openapi.json \
-g python \
-o ./sdk/python \
--additional-properties=packageName=myapi_sdk
# 生成TypeScript SDK
openapi-generator-cli generate \
-i http://localhost:8000/openapi.json \
-g typescript-fetch \
-o ./sdk/ts
场景5:MonkeyCode生成MonkeyCode(元编程)
让AI帮你写代码生成器:
我的项目有20个数据表,每个表都要写:
- SQLAIchemy Model
- Pydantic Schema
- FastAPI CRUD接口
- pytest单元测试
请帮我写一个代码生成器:
1. 输入:YAML格式的表结构定义
2. 输出:上述4个文件
3. 使用Jinja2模板引擎
4. 支持一键生成+单表生成
5. 生成后运行pytest验证
高级技巧:模板继承
{# templates/base_api.py.j2 #}
from fastapi import APIRouter, HTTPException
from typing import List, Optional
router = APIRouter()
{% block list_endpoint %}{% endblock %}
{% block create_endpoint %}{% endblock %}
{% block get_endpoint %}{% endblock %}
{% block update_endpoint %}{% endblock %}
{% block delete_endpoint %}{% endblock %}
{# templates/custom_router.py.j2 #}
{% extends "base_api.py.j2" %}
{% block list_endpoint %}
@router.get("/")
async def list_items():
return []
{% endblock %}
代码生成器的边界
适合生成:
✅ CRUD模板代码
✅ 类型定义(protobuf/GraphQL)
✅ SDK/客户端绑定
✅ 配置文件模板
✅ 单元测试模板
不适合生成:
❌ 复杂业务逻辑(会生成错误逻辑)
❌ 安全敏感代码(加密/认证)
❌ 性能关键路径(需人工优化)
MonkeyCode Prompt模板
用[Python/Go/TypeScript]写一个代码生成器,需求:
1. 输入格式:[YAML/JSON/Protobuf]
2. 生成目标:[CRUD代码/SDK/类型定义]
3. 使用[Jinja2/Go template] 模板引擎
4. 生成文件列表:[列出所有文件]
5. 生成后自动运行测试验证
6. 支持命令行参数:[参数列表]
总结
代码生成器的核心是识别重复模式,抽象为模板。
MonkeyCode能帮你:
- 分析现有代码,识别可模板化的重复模式
- 设计YAML/JSON输入格式
- 编写Jinja2/Go template模板
- 生成完整的代码生成器(含CLI、测试、文档)
记住:代码生成器不是"一次性脚本",而是需要维护的基础设施。模板要清晰、可调试、可覆盖。

浙公网安备 33010602011771号