
文章目录【90.PythonAI】Prompt Template模板化把Prompt当成代码来管理导入语1 ~ 硬编码Prompt的三大症状2 ~ Jinja2模板基础变量注入2.1 第一个模板2.2 三个立省时间的语法3 ~ 条件分支与循环动态组装3.1 组装流水线4 ~ Prompt版本管理进git跟代码同评审4.1 目录结构可直接照抄4.2 版本号规范4.3 评审与发布5 ~ 多语言Prompt模板5.1 一套逻辑多语言输出5.2 多语言的两个本地化细节6 ~ 模板也要写测试思考 总结结尾【90.PythonAI】Prompt Template模板化把Prompt当成代码来管理文章简介本文系统讲解Prompt模板的工程化管理方案解决Prompt散落在代码字符串、聊天记录里的维护灾难。文章从硬编码Prompt的三大症状切入给出完整的工业化实践Jinja2模板基础变量注入、默认值、过滤器、条件分支与循环按业务场景动态组装Prompt的完整代码、Prompt版本管理模板文件化、进git、版本号规范、与代码同评审同回滚、多语言Prompt模板一套逻辑多语言输出的i18n方案与目录结构设计。文中附模板加载器的Python实现、模板测试的写法、以及可直接照抄的项目目录结构配以Mermaid流程图展示模板从加载、渲染到送审的完整生命周期适合团队内Prompt资产越来越多、急需工程化治理的开发者阅读参考。 个人主页源码骑士❄专栏传送门《Android开发基础》《python基础课程》⭐️热衷从源码视角拆解技术底层原理将复杂架构讲得通俗易懂 源码骑士的简介5年Android Framework系统开发经验曾主导多项系统级性能优化专项技术栈覆盖Android系统全链路Binder/Handler/AMS/WMS/启动流程及Java后端全家桶Spring MyBatis Redis Oracle累计产出原创技术文章100篇文章以流程图为特色被读者评价为看一篇胜过啃一周源码导入语接手一个AI项目全局搜索情感分类的Prompt结果搜出四份一份在utils.py的字符串里一份在某个接口函数的注释里和上一份差两个字一份在测试脚本里还有一份——只活在已经离职的同事的调试笔记本里。线上跑的到底是哪一版没人说得清。这就是把Prompt当字符串而不是当代码的必然下场。你家的业务代码敢这样管理吗不敢。Prompt是决定AI行为的核心资产它值得和代码同等待遇模板化、文件化、版本化、可测试。这篇文章给出完整方案。1 ~ 硬编码Prompt的三大症状症状一散落各处改一处漏三处 同一个逻辑复制了N份优化只改了最常碰的那份 其余副本还在用旧版——线上行为出现人格分裂症状二改动无记录翻车无回滚 有人把请判断改成请分析准确率掉了5个点 谁改的什么时候上一版长什么样全部无从考证 症状三业务逻辑和Prompt死耦合 字符串拼接嵌在函数里运营想调个措辞 必须动代码、走发版——一个逗号等一周药方就一副把Prompt从代码里抽出来变成独立的、带变量的、可版本管理的模板文件。工具用模板引擎里的老朋友——Jinja2。2 ~ Jinja2模板基础变量注入2.1 第一个模板# prompts/emotion_classify.j2你是电商平台的用户反馈分析员。 请将以下用户反馈分类为售前 / 售后 / 物流 / 其他。 {% if strict %}只输出分类标签禁止任何解释。{% else %}输出标签并附一句话理由。{% endif %} 用户反馈{{ feedback }} 分类fromjinja2importEnvironment,FileSystemLoader envEnvironment(loaderFileSystemLoader(prompts))templateenv.get_template(emotion_classify.j2)prompttemplate.render(feedback快递三天了还没动怎么回事,strictTrue,# 变量注入同一个模板两种输出形态)2.2 三个立省时间的语法语法用途示例{{ var }}变量注入{{ feedback }}{{ var | default(值) }}缺省兜底{{ lang | default(中文) }}{%% if %%}/{%% for %%}逻辑控制按条件组装、批量渲染示例模板引擎选型不必纠结Jinja2是Python生态事实标准LangChain的PromptTemplate、LlamaIndex内部也都是它或它的语法子集。学会一套处处通用。3 ~ 条件分支与循环动态组装真实业务的Prompt不是一整块而是按场景拼装的。Jinja2的逻辑控制让模板自己会长出分支# prompts/customer_service.j2你是{{ company }}的客服助手。 {% if user_vip %}对方是VIP客户优先处理、可承诺加急语气更热情。{% endif %} 【服务规则】 {% for rule in rules %} {{ loop.index }}. {{ rule }} {% endfor %} 【可参考的常见问答】 {% for qa in faq_list %} Q: {{ qa.q }} A: {{ qa.a }} {% endfor %} 用户问题{{ question }}promptenv.get_template(customer_service.j2).render(company悦读书店,user_vipTrue,# 开关一拨Prompt长出VIP条款rules[先安抚情绪再解决问题,不编造优惠信息,不确定就引导转人工],faq_listdynamic_faq_retrieval(question),# 接上篇的动态Few-Shotquestion我上周买的书能退吗,)注意这个组合拳的威力规则列表来自配置文件、FAQ来自向量检索、VIP开关来自用户系统——Prompt成了运行时组装的产物而模板始终是那一份。改规则改配置就行模板一个字不用动。3.1 组装流水线效果回归时业务请求进入收集上下文用户等级/业务场景/检索结果选择模板文件按场景路由Jinja2渲染变量注入条件分支循环生成最终Prompt送入模型记录日志: 用了哪个模板哪个版本什么变量可精确复现当时的完整输入流水线最后那个日志环节千万别省记录模板名版本渲染变量线上任何一条AI的奇怪回答你都能一比一复现现场。没有它排查线上问题等于考古。4 ~ Prompt版本管理进git跟代码同评审4.1 目录结构可直接照抄prompts/ ├─ README.md# 模板清单与负责人├─ customer_service/ │ ├─ v1.0.0.j2 │ ├─ v1.1.0.j2# 当前线上版│ └─ CHANGELOG.md# 每版改了什么、为什么、评测分数├─ emotion_classify/ │ ├─ v2.0.0.j2 │ └─ CHANGELOG.md └─ tests/ ├─ test_customer_service.py# 渲染测试效果回归└─ fixtures/# 固定测试输入与期望输出4.2 版本号规范语义化版本直接套用 主版本号结构级变更改角色、改框架——需要全量回归 次版本号条款级增删加一条约束、换一批示例——抽样回归 修订号 措辞微调错别字、语气词——渲染测试通过即可 铁律线上永远加载指定版本号文件禁止最新版式引用 → 回滚把版本号改回去十秒完成4.3 评审与发布Prompt变更的完整流程和代码PR一模一样1. 新建分支修改模板文件版本号12. CHANGELOG写明改了什么、为什么、评测集对比分数3. PR评审业务方看措辞算法看效果双方点头4. 合并后灰度5%流量先跑护栏指标正常再全量5. 出问题版本号回指上一版十秒回滚这套流程看起来重但踩过坑的都懂Prompt的一字之差就是线上行为的千里之差。你值得为每一版Prompt留下为什么这么改的字据——三个月后接手的人往往是你自己会感激这份CHANGELOG。5 ~ 多语言Prompt模板5.1 一套逻辑多语言输出业务出海时最糟的做法是把模板复制五份改语言——逻辑一调整五份同步改到怀疑人生。正确姿势是逻辑与语言分层prompts/i18n/ ├─ base.j2# 逻辑骨架分支、规则结构语言无关├─ zh/ │ └─ strings.j2# 中文文案角色描述、规则措辞、兜底话术├─ en/ │ └─ strings.j2# 英文文案结构镜像内容翻译本地化└─ ja/ └─ strings.j2# base.j2结构在这里文案从语言包注入{%importlang_path~/strings.j2ast%}{{ t.role }} {% if user_vip %}{{ t.vip_clause }}{% endif %} {{ t.rules_header }} {% for rule in rules %}{{ loop.index }}. {{ rule }} {% endfor %}defrender_prompt(scene,lang,**kwargs):envEnvironment(loaderFileSystemLoader(prompts/i18n))templateenv.get_template(base.j2)returntemplate.render(lang_pathlang,**kwargs)5.2 多语言的两个本地化细节细节一翻译 ≠ 本地化亲切但克制在中文语境是一种语气直译成日语可能变成冷淡→ 各语言的措辞由对应语种的同学评审不做机械翻译 细节二输出语言要显式声明 各语言模板末尾统一加一句请始终使用{对应语言}回复→ 防止用户用英文提问时模型叛逃到英文作答6 ~ 模板也要写测试Prompt模板进工程体系最后一环是测试。两类各司其职# 测试一渲染测试快每次CI必跑——保证模板渲染得出来、长得对deftest_vip_clause_injected():promptrender_prompt(service,zh,user_vipTrue,rules[规则A],faq_list[],question测试)assertVIPinprompt# 条件分支生效assert规则Ainprompt# 循环渲染完整assert{%notinprompt# 无语法残留# 测试二效果回归慢发版前跑——保证模板效果没退化deftest_classification_regression():promptenv.get_template(emotion_classify/v1.1.0.j2).render(...)correctsum(call_model(prompt,x)yforx,yinfixtures)assertcorrect/len(fixtures)0.90# 不低于该版本历史基线思考 总结Prompt是资产不是字符串散落各处、改动无记录、与代码死耦合——硬编码三症状的药方是模板化、文件化、版本化。Jinja2是Python生态的事实标准变量注入、默认值、if/for——一套语法在LangChain、LlamaIndex里处处通用。条件分支循环让模板运行时组装规则来自配置、示例来自检索、开关来自业务系统——模板一份形态千面记得记录模板版本变量的现场日志。版本管理照抄代码那套语义化版本号、CHANGELOG写明改因与分数、PR双评审、灰度发布、版本号回指即回滚。多语言要逻辑与文案分层模板要配两类测试渲染测试进CI保底效果回归守住发版红线。到这里Prompt工程的主线——结构、CoT、Few-Shot、System、自动优化、模板化——已经闭环。下一篇聊一个每次调用都在烧钱的话题Prompt的Token效率怎么写才能又省钱、效果又不打折。结尾各位小伙伴本文的内容到这里就全部结束了源码骑士在这里再次感谢您的阅读源码骑士 — Android Framework 全栈开发关注跟博主一起从源码视角深耕底层原理见证每一次成长❤️点赞让优质内容被更多人看见让知识传递更有力量⭐收藏把核心知识点存好在需要时随时查、随时用评论分享你的经验或疑问评论区一起交流避坑一键四连不要忘记给博主一键四连哦️寄语技术之路难免有困惑但同行的人会让前进更有方向结语当Prompt开始住模板文件、有版本号、过评审、带测试它就从聊天的艺术毕业成了真正的软件工程资产。不要忘记给博主一键四连哦