很多开发者用 AI 的方式,其实很浪费。

今天让 ChatGPT 做代码 Review,临时打一段提示词。
明天让 Claude 分析报错,又重新打一段。
后天让 Cursor 帮忙写接口文档,还是现想现写。

最后你会发现:
不是 AI 不好用,是你每次都在重新发明提示词。

这篇文章做一个很小的工具:本地 AI 提示词模板库

它不依赖第三方库,不调用任何 AI API,不上传代码,只是在本地用 Python 管理常用提示词模板。

支持功能:

  • 初始化模板库;
  • 查看已有模板;
  • 查看模板变量;
  • 添加自定义模板;
  • 根据变量生成最终 Prompt;
  • 导出 Markdown 文件;
  • 复制到 ChatGPT、Claude、Cursor、Kiro 等工具里使用。

适合这些场景:

  • 代码 Review;
  • Bug 排查;
  • 接口文档生成;
  • README 生成;
  • 测试用例补充;
  • 技术方案对比;
  • 文章大纲生成;
  • 周报 / 总结模板复用。

工具不大,但很实用。程序员真正需要的往往不是又一个复杂平台,而是少重复打几遍废话。人类写提示词写到 Ctrl+C 都磨损了,属实没必要。


一、最终效果

初始化模板库:

python prompt_bank.py init

查看模板列表:

python prompt_bank.py list

查看某个模板:

python prompt_bank.py show code_review

渲染代码 Review 提示词:

python prompt_bank.py render code_review \
  --var language=Python \
  --var goal=检查这次接口修改是否有异常处理遗漏 \
  --var code="这里粘贴代码或 Git Diff"

导出到 Markdown:

python prompt_bank.py render code_review \
  --var language=Python \
  --var goal=检查这次接口修改是否有异常处理遗漏 \
  --var code="这里粘贴代码或 Git Diff" \
  --out review_prompt.md

生成后的内容就可以复制到 AI 工具里使用。


二、项目结构

新建一个目录:

mkdir ai-prompt-bank
cd ai-prompt-bank

目录结构如下:

ai-prompt-bank/
├── prompt_bank.py
└── prompt_bank.json

其中:

  • prompt_bank.py 是命令行工具;
  • prompt_bank.json 是本地提示词模板库;
  • 不需要安装第三方依赖。

建议 Python 版本:

Python 3.9+

三、完整代码

新建文件:

touch prompt_bank.py

写入下面代码:

import argparse
import json
import re
from pathlib import Path
from typing import Dict, Any


DEFAULT_BANK_FILE = "prompt_bank.json"

DEFAULT_TEMPLATES = {
    "code_review": {
        "title": "代码 Review",
        "tags": ["code", "review", "developer"],
        "content": """你是一名有经验的高级开发工程师,请帮我做一次代码 Review。

编程语言:{{language}}

本次 Review 目标:
{{goal}}

请重点检查:
1. 是否存在明显逻辑错误;
2. 是否遗漏边界条件;
3. 是否存在异常处理不足;
4. 是否有潜在安全风险;
5. 是否有重复代码或过度复杂逻辑;
6. 是否需要补充测试用例;
7. 是否影响已有功能。

请按下面格式输出:

### 总体评价

### 高风险问题

### 中低风险建议

### 建议补充的测试用例

### 可以直接修改的代码建议

下面是需要 Review 的代码或 Git Diff:

```{{language}}
{{code}}
```"""
    },
    "bug_debug": {
        "title": "Bug 排查",
        "tags": ["bug", "debug", "developer"],
        "content": """你是一名有经验的软件工程师,请帮我排查 Bug。

项目背景:
{{background}}

报错信息:
{{error_message}}

相关代码:
```{{language}}
{{code}}

请按下面步骤分析:

  1. 先解释报错可能含义;
  2. 列出最可能的 3 个原因;
  3. 给出排查顺序;
  4. 给出可能的修复方案;
  5. 提醒我还需要补充哪些信息。"""
    },
    "api_doc": {
    "title": "接口文档生成",
    "tags": ["api", "doc", "backend"],
    "content": """你是一名后端工程师,请根据下面的信息生成接口文档。

接口名称:{{api_name}}

接口说明:
{{description}}

请求示例:

{{request_example}}

响应示例:

{{response_example}}

请输出:

  1. 接口用途;
  2. 请求方法和路径;
  3. 请求参数表;
  4. 响应字段表;
  5. 错误码说明;
  6. 调用示例;
  7. 注意事项。"""
    }
    }

def get_bank_path(path: str) -> Path:
return Path(path).resolve()

def load_bank(path: Path) -> Dict[str, Any]:
if not path.exists():
return {}

try:
    content = path.read_text(encoding="utf-8")
    data = json.loads(content)
except json.JSONDecodeError as error:
    raise ValueError(f"模板库 JSON 格式错误:{error}") from error

if not isinstance(data, dict):
    raise ValueError("模板库格式错误,根节点必须是对象。")

return data

def save_bank(path: Path, bank: Dict[str, Any]) -> None:
path.write_text(
json.dumps(bank, ensure_ascii=False, indent=2),
encoding="utf-8"
)

def extract_variables(content: str) -> list[str]:
pattern = r"{{\s*([a-zA-Z_][a-zA-Z0-9_])\s}}"
return sorted(set(re.findall(pattern, content)))

def parse_vars(items: list[str]) -> Dict[str, str]:
result = {}

for item in items:
    if "=" not in item:
        raise ValueError(f"变量格式错误:{item},正确格式应为 key=value")

    key, value = item.split("=", 1)
    key = key.strip()

    if not key:
        raise ValueError(f"变量名不能为空:{item}")

    result[key] = value

return result

def render_content(content: str, values: Dict[str, str]) -> str:
variables = extract_variables(content)
missing = [name for name in variables if name not in values]

if missing:
    raise ValueError(f"缺少变量:{', '.join(missing)}")

def replace(match: re.Match) -> str:
    name = match.group(1).strip()
    return values.get(name, "")

return re.sub(r"\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}", replace, content)

def command_init(args: argparse.Namespace) -> None:
path = get_bank_path(args.file)

if path.exists() and not args.force:
    print(f"模板库已存在:{path}")
    print("如果要覆盖,请添加 --force")
    return

save_bank(path, DEFAULT_TEMPLATES)
print(f"模板库初始化完成:{path}")

def command_list(args: argparse.Namespace) -> None:
path = get_bank_path(args.file)
bank = load_bank(path)

if not bank:
    print("模板库为空,请先执行 init 或 add。")
    return

keyword = args.tag.lower() if args.tag else None

for name, item in bank.items():
    tags = item.get("tags", [])
    title = item.get("title", "")

    if keyword and keyword not in [tag.lower() for tag in tags]:
        continue

    tag_text = ", ".join(tags)
    print(f"- {name}|{title}|{tag_text}")

def command_show(args: argparse.Namespace) -> None:
path = get_bank_path(args.file)
bank = load_bank(path)

template = bank.get(args.name)

if not template:
    print(f"未找到模板:{args.name}")
    return

content = template.get("content", "")
variables = extract_variables(content)

print(f"模板名称:{args.name}")
print(f"标题:{template.get('title', '')}")
print(f"标签:{', '.join(template.get('tags', []))}")
print(f"变量:{', '.join(variables) if variables else '无'}")
print("\n--- 模板内容 ---\n")
print(content)

def command_render(args: argparse.Namespace) -> None:
path = get_bank_path(args.file)
bank = load_bank(path)

template = bank.get(args.name)

if not template:
    print(f"未找到模板:{args.name}")
    return

values = parse_vars(args.var or [])
content = template.get("content", "")
rendered = render_content(content, values)

if args.out:
    out_path = Path(args.out).resolve()
    out_path.write_text(rendered, encoding="utf-8")
    print(f"Prompt 已导出:{out_path}")
else:
    print(rendered)

def command_add(args: argparse.Namespace) -> None:
path = get_bank_path(args.file)
bank = load_bank(path)

if args.name in bank and not args.overwrite:
    print(f"模板已存在:{args.name}")
    print("如果要覆盖,请添加 --overwrite")
    return

content_path = Path(args.content_file).resolve()

if not content_path.exists():
    print(f"模板内容文件不存在:{content_path}")
    return

content = content_path.read_text(encoding="utf-8")
tags = [tag.strip() for tag in args.tags.split(",") if tag.strip()]

bank[args.name] = {
    "title": args.title,
    "tags": tags,
    "content": content
}

save_bank(path, bank)
print(f"模板已添加:{args.name}")

def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="本地 AI 提示词模板库工具"
)

parser.add_argument(
    "--file",
    default=DEFAULT_BANK_FILE,
    help="模板库 JSON 文件路径,默认 prompt_bank.json"
)

subparsers = parser.add_subparsers(
    dest="command",
    required=True
)

init_parser = subparsers.add_parser("init", help="初始化模板库")
init_parser.add_argument("--force", action="store_true", help="覆盖已有模板库")
init_parser.set_defaults(func=command_init)

list_parser = subparsers.add_parser("list", help="查看模板列表")
list_parser.add_argument("--tag", help="按标签筛选")
list_parser.set_defaults(func=command_list)

show_parser = subparsers.add_parser("show", help="查看模板详情")
show_parser.add_argument("name", help="模板名称")
show_parser.set_defaults(func=command_show)

render_parser = subparsers.add_parser("render", help="渲染模板")
render_parser.add_argument("name", help="模板名称")
render_parser.add_argument(
    "--var",
    action="append",
    help="模板变量,格式 key=value,可重复传入"
)
render_parser.add_argument("--out", help="导出文件路径")
render_parser.set_defaults(func=command_render)

add_parser = subparsers.add_parser("add", help="添加模板")
add_parser.add_argument("name", help="模板名称")
add_parser.add_argument("--title", required=True, help="模板标题")
add_parser.add_argument("--tags", default="", help="模板标签,多个用英文逗号分隔")
add_parser.add_argument("--content-file", required=True, help="模板内容文件")
add_parser.add_argument("--overwrite", action="store_true", help="覆盖同名模板")
add_parser.set_defaults(func=command_add)

return parser

def main() -> None:
parser = build_parser()
args = parser.parse_args()

try:
    args.func(args)
except ValueError as error:
    print(f"错误:{error}")

if name == "main":
main()


---

## 四、初始化模板库

执行:

```bash
python prompt_bank.py init

成功后会生成:

prompt_bank.json

里面默认包含 3 个模板:

code_review
bug_debug
api_doc

分别对应:

  • 代码 Review;
  • Bug 排查;
  • 接口文档生成。

查看模板列表:

python prompt_bank.py list

输出示例:

- api_doc|接口文档生成|api, doc, backend
- bug_debug|Bug 排查|bug, debug, developer
- code_review|代码 Review|code, review, developer

五、查看模板变量

比如查看代码 Review 模板:

python prompt_bank.py show code_review

输出里会看到:

变量:code, goal, language

这说明渲染这个模板时,需要传入三个变量:

  • language
  • goal
  • code

如果缺少变量,程序会提示错误。

比如:

python prompt_bank.py render code_review --var language=Python

会提示:

错误:缺少变量:code, goal

这比生成一段半残废 Prompt 要好。程序报错至少诚实,AI 有时候会用一脸自信把坑盖上。


六、渲染一个代码 Review Prompt

执行:

python prompt_bank.py render code_review \
  --var language=Python \
  --var goal=检查参数校验和异常处理是否完整 \
  --var code="def get_user(id): return db.query(id)"

会输出完整 Prompt:

你是一名有经验的高级开发工程师,请帮我做一次代码 Review。

编程语言:Python

本次 Review 目标:
检查参数校验和异常处理是否完整

请重点检查:
1. 是否存在明显逻辑错误;
2. 是否遗漏边界条件;
3. 是否存在异常处理不足;
...

然后你就可以复制到 ChatGPT、Claude、Cursor、Kiro 里使用。


七、导出为 Markdown 文件

如果 Prompt 比较长,建议导出成文件:

python prompt_bank.py render code_review \
  --var language=Python \
  --var goal=检查参数校验和异常处理是否完整 \
  --var code="def get_user(id): return db.query(id)" \
  --out review_prompt.md

生成:

review_prompt.md

这样适合团队共享,也适合放到项目文档里。


八、添加自己的模板

先创建一个模板内容文件:

touch readme_template.md

写入:

你是一名技术文档工程师,请根据下面的信息生成 README。

项目名称:{{project_name}}

项目说明:
{{description}}

技术栈:
{{tech_stack}}

请输出:
1. 项目简介;
2. 安装步骤;
3. 启动命令;
4. 目录结构;
5. 环境变量说明;
6. 常见问题;
7. 后续优化建议。

添加到模板库:

python prompt_bank.py add readme \
  --title README生成 \
  --tags doc,readme,developer \
  --content-file readme_template.md

查看:

python prompt_bank.py show readme

渲染:

python prompt_bank.py render readme \
  --var project_name=ai-prompt-bank \
  --var description=一个本地AI提示词模板库工具 \
  --var tech_stack=Python

这样一个自定义模板就可以重复使用了。


九、为什么要做本地模板库?

很多人用 AI 效率低,不是因为不会提问,而是因为每次都临时提问。

临时提问有几个问题:

  1. 容易漏掉背景;
  2. 输出格式不稳定;
  3. 每次都要重复输入要求;
  4. 团队成员之间难以复用;
  5. 难以沉淀成标准流程。

本地模板库可以解决这些问题。

比如团队里约定:

  • 代码 Review 都用 code_review
  • Bug 排查都用 bug_debug
  • 接口文档都用 api_doc
  • README 都用 readme
  • 测试用例都用 test_case

这样大家给 AI 的上下文和输出要求就更统一。

不要小看这个统一。

很多团队不是不会用 AI,而是每个人都用自己的玄学提示词。最后生成结果千奇百怪,像一场大型赛博民间偏方交流会。


十、可以继续优化的方向

这个脚本只是一个最小可用版本。

后续可以继续加:

1. 支持按关键词搜索

比如:

python prompt_bank.py search review

2. 支持模板分类目录

比如:

templates/
├── code/
├── writing/
├── office/
└── seo/

3. 支持从剪贴板读取代码

这样不用手动写 --var code=xxx

4. 支持读取 Git Diff

结合:

git diff --cached

自动生成代码 Review Prompt。

5. 支持团队共享

prompt_bank.json 放进项目仓库,团队统一维护。

6. 支持敏感词检查

渲染前检查是否包含:

  • token;
  • password;
  • api_key;
  • secret;
  • 公司内部接口;
  • 用户隐私数据。

这一步很重要。

提示词模板可以共享,但敏感信息不能乱传。尤其是公司代码、客户数据、账号信息,不要直接丢给外部 AI 工具。安全问题从来不是“提醒一下”就能解决的,人类最擅长的就是提醒完继续犯。


十一、和 ChatGPT、Claude、Cursor、Kiro 怎么配合?

这个工具本身不绑定任何 AI 平台。

你可以这样用:

ChatGPT

适合通用代码解释、办公总结、文章结构、测试点补充。

Claude

适合长文档、复杂代码、长上下文分析、代码 Review。

Cursor

适合在编辑器里结合项目上下文修改代码。

Kiro

适合围绕需求、规范、任务拆解做工程化辅助。

但不管用哪个工具,核心都是一样的:

把常用提示词模板化。

不要每次都重新输入:

“你是一个资深工程师……”
“请帮我检查代码……”
“请按下面格式输出……”

这些话写一两次叫认真,写一百次叫浪费生命。

如果后续你长期使用 ChatGPT Plus、Claude Pro、Cursor、Kiro、Gemini Advanced、Grok 这类 AI 工具,也可以把 gpt68.com 作为第三方 AI 会员充值平台入口之一去了解。它解决的是订阅充值流程问题,不是替代工具本身。使用前建议看清楚套餐说明、账号要求、到账说明和售后规则。


十二、总结

这篇文章用 Python 做了一个本地 AI 提示词模板库,核心功能包括:

init   初始化模板库
list   查看模板列表
show   查看模板详情和变量
render 渲染模板
add    添加自定义模板

它解决的是一个很具体的问题:

不要每次用 AI 都重新写提示词。

对于开发者来说,把提示词模板化之后,可以更稳定地做代码 Review、Bug 排查、接口文档、README、测试用例和技术方案分析。

AI 工具真正能提高效率的地方,不只是生成答案。

而是把重复流程变成可复用流程。

代码是这样,提示词也是这样。

更多推荐