链载Ai

标题: 别再把 Prompt 写死在代码里了:如何构建动态模板库? [打印本页]

作者: 链载Ai    时间: 3 天前
标题: 别再把 Prompt 写死在代码里了:如何构建动态模板库?

做 AI 应用开发,你是不是经常写出这样的代码:

# 这是一个悲伤的故事
response=client.chat.completions.create(
messages=[
{"role":"user","content":f"请把这段话翻译成{target_lang},风格要{style}一些:{user_input}"}
]
)

这就是所谓的“硬编码(Hard-coding)”。

在 Demo 阶段,这没问题。
但当你的项目膨胀到几千行代码,拥有 50 个不同的功能点时,这种散落在各个.py文件角落里的f-string,就是一场维护灾难

业务说:“所有的翻译都要加一句‘保持原意’。” —— 你得去代码里搜一遍,改 10 个地方。
不小心删掉了一个{},上线直接报错。
你想做 A/B 测试,对比两个 Prompt 的效果,发现要改动核心逻辑代码。

Prompt 不是字符串,Prompt 是代码逻辑的一部分。
我们需要用软件工程的思维来治理它。

今天,我们来聊聊如何从零构建一个Python f-string 风格的动态模板库,让你的 Prompt 管理井井有条。

01 为什么要“模板化”?

模板化(Templating)的核心价值在于“解耦(Decoupling)”。

我们要把Prompt 的内容(What)代码的逻辑(How)彻底分开。

一个优秀的 Prompt 库应该具备三个特征:

1
集中管理:所有的 Prompt 都在一个文件夹或文件里,像 API 接口文档一样清晰。
2
参数校验:缺参数?多参数?在调用 LLM 扣费之前,程序就该报错。
3
动态复用:同样一段“安全过滤规则”,应该能被 10 个不同的 Agent 复用,而不是复制粘贴 10 次。

02 基础版:封装 PromptTemplate 类

虽然 LangChain 提供了现成的PromptTemplate,但它太重了。其实我们自己写一个轻量级的类,只需要 10 行代码。

我们利用 Python 强大的string.Formatter或简单的f-string逻辑。

实战代码:

# prompt_lib.py

classPromptTemplate:
def__init__(self,template_str:str,input_variables:list):
self.template_str=template_str
self.input_variables=input_variables

defformat(self,**kwargs):
# 1. 校验参数:确保所有需要的变量都传进来了
missing_vars=[varforvarinself.input_variablesifvarnotinkwargs]
ifmissing_vars:
raiseValueError(f"缺少必要参数:{missing_vars}")

# 2. 生成最终 Prompt
returnself.template_str.format(**kwargs)

# = 定义你的模板 =
TRANSLATE_PROMPT=PromptTemplate(
template_str="你是一个精通{source_lang}和{target_lang}的翻译官。请翻译:{text}",
input_variables=["source_lang","target_lang","text"]
)

在业务代码中调用:

# main.py
fromprompt_libimportTRANSLATE_PROMPT

# 调用起来非常清晰,且自带参数检查
final_prompt=TRANSLATE_PROMPT.format(
source_lang="中文",
target_lang="英文",
text="你好,世界"
)
print(final_prompt)

这看起来简单,但它带来了一个巨大的好处:你的 IDE 甚至可以利用 Type Hinting 提示你需要传什么参数。

03 进阶版:组件化(Partials)与复用

Prompt 开发中最痛的点是“重复”。
比如,你所有的 Agent 都需要遵守一套“企业安全红线”。你不想在每个 Prompt 里都写这 500 字。

这时候,我们需要引入“组件化”思维(在 LangChain 中叫PartialPrompt)。

我们可以把 Prompt 拆分为Base Template(基座)Variable Template(变量)

实战逻辑:

# 1. 定义公共组件
SAFETY_INSTRUCTION="""
【安全规范】
1. 严禁讨论政治敏感话题。
2. 严禁输出个人隐私数据。
"""

# 2. 定义业务 Prompt
CODE_GENERATION_STR="""
{safety_rules}

你是一个 Python 专家。请帮我写一个函数:{user_req}
"""

# 3. 预填(柯里化)
# 我们在应用初始化时,就先把安全规范填进去
safe_code_prompt=PromptTemplate(
template_str=CODE_GENERATION_STR,
input_variables=["safety_rules","user_req"]
)

# 业务代码调用时,只需要传 user_req,不需要关心 safety_rules
final_prompt=safe_code_prompt.format(
safety_rules=SAFETY_INSTRUCTION,# 这里可以自动注入
user_req="写个爬虫"
)

通过这种方式,一旦老板说要修改“安全规范”,你只需要改SAFETY_INSTRUCTION这一个变量,全公司所有的 Agent 都会自动生效。

04 终极版:使用 YAML/JSON 做配置化管理

当 Prompt 变得非常长(几千字)时,放在 Python 代码里会显得很乱。
最佳实践是将 Prompt 抽离为独立的YAMLJSON文件。

目录结构建议:

/project_root
/prompts
/chat
customer_service.yaml
tech_support.yaml
/agent
data_analyst.yaml
common.yaml (公共组件)

customer_service.yaml 内容:

_type:prompt
input_variables:["user_name","query"]
template:|
你是一个客服。
当前用户:{user_name}

请回答:{query}

在代码中,写一个加载器(Loader)去读取这些文件。这样做的好处是:Prompt 的修改不需要重新部署代码(甚至可以在后台配置中心热更新)。

05 产品视角的思考:Prompt 也是资产

对于技术团队来说,建立 Prompt Template 库不仅仅是为了代码整洁,更是为了资产沉淀

版本控制(Versioning):你可以有v1_sales_promptv2_sales_prompt,通过 A/B 测试看哪个转化率高。
团队协作:资深的 Prompt 工程师负责维护 YAML 文件,初级后端工程师只负责写 Python 代码调用format(),互不干扰。

写在最后

不要让你的 Prompt 成为“魔法字符串(Magic Strings)”。

它们是这个 AI 时代最重要的源代码。
给它们穿上 Class 的外衣,加上 Type 的约束,放进 YAML 的保险箱。

当你把 Prompt 当作代码来管理,而不是当作文本来处理时,你的 AI 应用才算真正具备了“企业级”的健壮性。






欢迎光临 链载Ai (http://www.lianzai.com/) Powered by Discuz! X3.5