把火山引擎 LLM 塞进 Flask,我做了个「Prompt 永动机」:输入一句话,秒出 200 行专家级提示词
导语
还在熬夜调 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 张图看懂
解释:前后端 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.py、test_main.py、test_auth.py等独立测试 - ✅ Mock LLM 调用:所有 LLM API 调用已 Mock,CI 不花一分钱
- ✅ 覆盖核心功能:提示词生成、流式输出、用户认证、示例管理全覆盖
测试结果截图:
5 分钟上手(小白也能跑)
-
准备
- Python ≥ 3.8
- 火山引擎 AK/SK(新用户送 30 元额度,够用)在这里插入图片描述
-
一键启动
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,立刻开玩!
-
创建管理员(可选)
python -m app cli create-admin
roadmap(欢迎 PR)
- 接入 OpenAI / Claude 多后端
- 支持「对话历史」版本管理
- 一键导出 Prompt 为图片 / PDF,方便分享
- 微信小程序版,手机也能调
源码地址
GitHub: https://github.com/jaylun123/Prompt-Generator
记得点 ⭐ 不迷路,后续更新第一时间推送!
评论区见
你还想加什么功能?
或者踩过什么 Prompt 坑?
欢迎留言!
更多推荐

所有评论(0)