导语

还在熬夜调 Prompt?
复制粘贴大佬模板,结果一跑就崩?
想要结构化输出 JSON,却只会写「请返回一个合法的 json」?

今天给大家安利一款我刚开源的 Prompt Generator——
核心创新:用 LLM 生成 Prompt,通过精心设计的元提示词(Meta-Prompt)指导 AI 写出专业级提示词
流式输出:火山引擎 LLM 原生支持,SSE 实时返回,打字机效果拉满
完整闭环:生成→测试→复制,30 秒从需求到可用 Prompt,自带「一键调试」页面

核心原理:不是简单地把需求扔给 LLM,而是构建了一个「提示词工程师」角色,让 AI 理解如何写 Prompt,再根据你的需求(输出类型、结构、语言)动态生成专业提示词。这就是「用 Prompt 生成 Prompt」的套娃哲学!

先放动图,直观感受!
在这里插入图片描述


细节展示

1. 流式生成:打字机效果太治愈

在这里插入图片描述

2. 一键切换 Raw / Rendered,Markdown 实时预览

在这里插入图片描述

3. 在线调试:测试生成的 Prompt,立刻得到真机回复

在这里插入图片描述

4. 管理员后台:示例库 + 用户管理,秒变 SaaS

在这里插入图片描述
在这里插入图片描述在这里插入图片描述


技术干货拆解(收藏级)

1. 整体架构 = 1 张图看懂

POST /generate

参数校验

匿名

已登录

构建系统提示词

stream=True

流式返回

SSE 格式

text/event-stream

/api/examples

CRUD

浏览器

Flask Blueprint

用户认证

Session 试用计数

用户请求计数

llm.generate_prompt

OpenAI Client

ARK LLM API

示例库

管理员后台

解释:前后端 0 耦合,纯 REST + SSE,后端只用 SQLite,迁到 MySQL 只需改一行 URI。核心是 llm.py 中的提示词生成引擎,通过精心设计的系统提示词指导 LLM 生成高质量提示词。

2. 🎯 核心功能:LLM 优化提示词的技术细节(项目灵魂)

2.1 系统提示词设计:让 AI 理解「如何写 Prompt」

这是整个项目的核心创新点。我们不是简单地把用户需求扔给 LLM,而是构建了一个元提示词(Meta-Prompt),指导 LLM 如何生成专业的提示词。

# llm.py 中的核心逻辑
def generate_prompt(requirement, output_type, structure, fixed_fields, model, language):
    # 1. 语言映射:支持中英文切换
    language_map = {"en": "English", "zh": "Chinese"}
    language_name = language_map.get(language, "English")
    
    # 2. 结构约束:根据用户选择动态生成约束文本
    structure_text = (
        f"请确保提示词要求输出包含以下字段:{', '.join(fixed_fields)}"
        if structure == "fixed" and fixed_fields
        else "提示词可自由组织结构。"
    )
    
    # 3. 输出格式约束:JSON vs 自然语言
    output_format_text = (
        "提示词中要求目标模型输出 JSON 格式内容。"
        if output_type == "json"
        else "提示词中要求目标模型输出自然语言内容。"
    )
    
    # 4. 构建系统提示词(元提示词)
    system_prompt = f'''
你是资深提示词工程师,请根据需求编写 Markdown 格式的提示词,要求用 {language_name}。

# 需求
{requirement}

# 结构
{structure_text}

# 输出格式
{output_format_text}

# 格式要求
生成的提示词本身必须是 Markdown。

# 示例
以下是提示词的示例形态(仅示意,可根据需求调整):
```markdown
# 角色
你是一位使用 {language_name} 的专业助手,擅长提取文档关键信息。

# 输入
<用户上传的文档>

# 输出要求
返回json格式,形如{{"标题":xxx,"内容":xxx,"关键信息":xxx}}。
```
注意只输出结果,不要解释,不需要类似xxx prompt的标题
'''

设计亮点

  • 角色定位:明确告诉 LLM「你是资深提示词工程师」,激活专业能力
  • 结构化输入:用 Markdown 分段组织需求、结构、格式,让 LLM 清晰理解约束
  • 示例引导:提供示例形态,但不强制,给 LLM 发挥空间
  • 语言自适应:根据用户选择动态切换提示词语言,支持国际化

2.2 参数处理:5 个维度精准控制输出

# main_bp.py 中的参数校验与传递
@main_bp.route("/generate", methods=["POST"])
def generate():
    data = request.get_json()
    
    # 参数提取与校验
    requirement = data.get("requirement", "").strip()      # 用户需求(核心)
    output_type = data.get("output_type")                  # json | natural
    structure = data.get("structure")                      # free | fixed
    fixed_fields = data.get("fixed_fields") or []          # 固定字段列表
    model = data.get("model")                              # ARK 模型选择
    language = data.get("language", "en")                  # en | zh
    
    # 调用核心生成函数
    for chunk in generate_prompt(
        requirement, output_type, structure, 
        fixed_fields, model, language
    ):
        yield _format_sse(chunk)

参数组合效果

  • output_type=json + structure=fixed + fixed_fields=["title", "content"]
    → 生成要求输出固定 JSON 结构的提示词
  • output_type=natural + structure=free
    → 生成自由格式的自然语言提示词
  • language=zh
    → 生成中文提示词,适合国内 LLM 使用

2.3 流式输出:实时反馈提升用户体验

# llm.py 中的流式生成实现
def generate_prompt(...) -> Generator[str, None, None]:
    client = _create_client()
    
    # 调用 ARK API,开启流式模式
    stream = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": "Generate the prompt now."}
        ],
        temperature=0.7,  # 平衡创造性和稳定性
        stream=True       # 关键:开启流式输出
    )
    
    # 逐块返回,实现打字机效果
    for chunk in stream:
        if chunk.choices and len(chunk.choices) > 0:
            delta = chunk.choices[0].delta
            if delta and delta.content:
                yield delta.content  # 实时 yield,前端立即显示
# main_bp.py 中的 SSE 格式化
def _format_sse(data: str) -> str:
    """将数据格式化为 SSE 格式,保留换行符"""
    lines = data.replace("\r\n", "\n").split("\n")
    return "".join(f"data: {line}\n" for line in lines) + "\n"

def generate_stream():
    try:
        for chunk in generate_prompt(...):
            yield _format_sse(chunk)  # 每个 chunk 都格式化为 SSE
    except LlmError as e:
        yield _format_sse(str(e))

return Response(
    stream_with_context(generate_stream()),
    mimetype="text/event-stream"  # 关键:SSE MIME 类型
)

技术细节

  • Generator 模式:使用 Python 生成器,内存占用 O(1),支持无限长输出
  • SSE 协议:Server-Sent Events,浏览器原生支持,无需 WebSocket
  • 换行处理_format_sse 函数确保 Markdown 换行正确传输
  • 错误处理:异常也通过 SSE 返回,前端统一处理

2.4 温度参数调优:平衡创造性与稳定性

temperature=0.7  # 经验值:既保证多样性,又避免过度发散

为什么是 0.7?

  • 0.0-0.3:过于保守,生成的提示词模板化严重
  • 0.7-0.9:平衡点,既有创新性,又保持专业性
  • 1.0+:过于随机,可能生成不符合要求的提示词

2.5 实际生成效果对比

输入

  • 需求:帮我写一个提取文档关键信息的提示词
  • 输出类型:json
  • 结构:fixed
  • 固定字段:["标题", "摘要", "关键词"]
  • 语言:zh

生成的提示词(Markdown 格式):

# 角色
你是一位专业的信息提取助手,擅长从文档中提取关键信息。

# 任务
请仔细阅读用户提供的文档,提取以下关键信息。

# 输出要求
请以 JSON 格式返回结果,必须包含以下字段:
- 标题:文档的主要标题
- 摘要:文档的核心内容摘要(100-200字)
- 关键词:文档中的3-5个关键词

# 输出格式
```json
{
  "标题": "...",
  "摘要": "...",
  "关键词": ["...", "...", "..."]
}
```

这就是「用 Prompt 生成 Prompt」的完整流程!

3. 流式输出前端实现:Fetch + ReadableStream 零依赖

前端使用 fetch API 配合 ReadableStream 接收 SSE 流,实现打字机效果:

// static/main.js 节选
fetch('/generate', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        requirement: document.querySelector('#requirement').value,
        output_type: document.querySelector('#output-type').value,
        structure: document.querySelector('#structure').value,
        fixed_fields: document.querySelector('#fixed-fields').value.split(','),
        model: document.querySelector('#model-select').value,
        language: document.querySelector('#language-select').value
    })
})
.then(response => {
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    
    function readStream() {
        return reader.read().then(({ done, value }) => {
            if (done) {
                // 流结束,更新最终显示
                updateDisplay();
                return;
            }
            
            // 解码 chunk 并处理 SSE 格式
            const chunk = decoder.decode(value, { stream: true });
            buffer += chunk;
            
            // SSE 事件以 \n\n 分隔
            const events = buffer.split('\n\n');
            buffer = events.pop();  // 保留最后一个不完整的事件
            
            for (const event of events) {
                const lines = event.split('\n');
                const dataLines = [];
                
                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        dataLines.push(line.slice(6));  // 移除 'data: ' 前缀
                    }
                }
                
                if (dataLines.length > 0) {
                    const content = dataLines.join('\n');
                    rawContent += content;  // 累积内容
                    updateDisplay();        // 实时更新显示
                }
            }
            
            return readStream();  // 继续读取
        });
    }
    
    return readStream();
});

技术优势

  • 零依赖:使用浏览器原生 fetch + ReadableStream,无需第三方库
  • POST 支持fetch 支持 POST 请求,比 EventSource(仅 GET)更灵活
  • 精确控制:手动解析 SSE 格式,可处理多行数据和复杂场景
  • 内存高效:流式处理,内存占用 O(1),支持无限长输出

4. 匿名用户「试用次数」防刷策略

# main_bp.py 中的试用逻辑
if not current_user.is_authenticated:
    if "trial_left" not in session:
        config = get_config()
        session["trial_left"] = config.MAX_TRIAL  # 默认 5 次
    
    if session.get("trial_left", 0) <= 0:
        return jsonify({"msg": "试用次数用完,请先注册"}), 403
    
    session["trial_left"] = session.get("trial_left", 0) - 1
    session.modified = True  # 确保 Session 更新

防刷机制

  • Session 存储:基于 Flask Session(Cookie),简单有效
  • 注册转化:达到上限弹窗引导注册
  • 心理设计:注册后 total_requests 显示 ∞

5. 示例库「一键填充」交互

// static/main.js 节选
function loadExample(id){
  fetch(`/api/examples/${id}`)
    .then(r=>r.json())
    .then(data=>{
      document.querySelector('#requirement').value = data.requirement;
      document.querySelector('#output_type').value = data.output_type;
      document.querySelector('#structure').value = data.structure;
      document.querySelector('#fixed_fields').value = data.fixed_fields || '';
      document.querySelector('#model').value = data.model || '';
      document.querySelector('#language').value = data.language || 'en';
    })
}

设计亮点

  • 数据库驱动:示例存在 SQLite,管理员后台随时热更新
  • 一键填充:点击示例,所有表单字段自动填充,0 秒上手
  • 运营友好:非技术人员也能通过后台管理示例库

6. 测试覆盖率 92%,放心二开

git clone https://github.com/jaylun123/Prompt-Generator
cd Prompt-Generator
conda env create -f environment.yml
conda activate prompt_proj
python run.py          # 拉起服务
python tests/test_all.py  # 3 分钟跑完单测

测试策略

  • 模块化测试test_llm.pytest_main.pytest_auth.py 等独立测试
  • Mock LLM 调用:所有 LLM API 调用已 Mock,CI 不花一分钱
  • 覆盖核心功能:提示词生成、流式输出、用户认证、示例管理全覆盖
    测试结果截图
    在这里插入图片描述

5 分钟上手(小白也能跑)

  1. 准备

    • Python ≥ 3.8
    • 火山引擎 AK/SK(新用户送 30 元额度,够用)在这里插入图片描述
  2. 一键启动

    git clone https://github.com/jaylun123/Prompt-Generator
    cd Prompt-Generator
    cp .env.example .env
    # 填好 ARK_API_KEY & SECRET_KEY
    pip install -r requirements.txt
    python -m app cli create-db
    python -m app cli init-examples   # 9 个官方模板
    python run.py
    

    浏览器打开 http://127.0.0.1:5000,立刻开玩!

  3. 创建管理员(可选)

    python -m app cli create-admin
    

roadmap(欢迎 PR)

  • 接入 OpenAI / Claude 多后端
  • 支持「对话历史」版本管理
  • 一键导出 Prompt 为图片 / PDF,方便分享
  • 微信小程序版,手机也能调

源码地址

GitHub: https://github.com/jaylun123/Prompt-Generator
记得点 ⭐ 不迷路,后续更新第一时间推送!


评论区见

你还想加什么功能?
或者踩过什么 Prompt 坑?
欢迎留言!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐