工程实践:模板化 Prompt + 动态上下文拼接 + JSON 强格式约束

📅 2026/7/17 15:25:45
工程实践:模板化 Prompt + 动态上下文拼接 + JSON 强格式约束
目录一、整体业务背景二、第一部分模板化 Prompt 工程实践1. 什么是模板化 Prompt2. 模板分层标准企业通用分层规范模板存储方案工程选型3. 模板变量插值规范避坑要点4. 模板化带来的工程收益三、第二部分动态拼接上下文核心工程难点1. 上下文组成标准拼接顺序权重从低到高2. 多轮对话历史动态拼接方案格式统一规范固定对话结构避免混乱超长上下文截断策略Token 超限必做代码层拼接流程示例伪代码3. 知识库动态拼接避坑点4. 安全防护防 Prompt 注入四、第三部分输出格式约束 —— 固定 JSON 返回工程落地核心1. Prompt 内强制 JSON 约束写法两种方案方案 1简单固定 JSON 模板字段少场景方案 2JSON Schema 标准约束复杂业务推荐2. 解决 LLM 不遵守 JSON 的常见问题兜底 1代码预处理清洗通用兜底 2异常重传机制兜底 3工具层强制校验JSON Schema 校验3. 业务异常统一 JSON 规范4. JSON 约束工程收益五、完整端到端工程示例Python 可运行简化版1. 统一 Prompt 模板2. 动态上下文拼接函数3. JSON 清洗 解析工具4. 调用主流程六、线上生产环境落地优化要点七、三大技术组合核心价值总结一、整体业务背景在企业级 LLM 落地知识库问答、数据抽取、智能工单、代码生成、内容审核中直接写零散 Prompt 会出现三大痛点Prompt 硬编码散落在代码各处改规则要全项目搜字符串维护成本极高用户输入、知识库片段、历史对话、业务参数混杂拼接极易出现注入、上下文越界、格式错乱LLM 自由文本输出后续解析逻辑复杂正则 / 字符串分割容错差极易抛异常。解决方案三层标准化架构模板层固定 Prompt 骨架 动态变量层实时上下文插值 输出约束层强制 JSON 返回二、第一部分模板化 Prompt 工程实践1. 什么是模板化 Prompt把 Prompt 拆分为固定静态模板可替换变量插槽将业务规则、角色设定、任务要求、输出规范统一托管代码只负责传入变量不手写大段文本。 类比前端 Vue/React 模板、SQL 预编译语句核心目的解耦、统一管控、版本可追溯。2. 模板分层标准企业通用分层规范一套标准 Prompt 模板分为 5 段固定顺序不可打乱【角色定义】固定不变描述LLM身份、能力、立场、禁忌 【全局约束】业务通用规则如禁止幻觉、数据来源仅限给定材料、字数限制 【任务指令】当前单次要完成的核心任务 【动态变量插槽】{{user_query}}、{{knowledge_chunks}}、{{history_msg}}、{{biz_params}} 【输出格式强制规则】JSON结构、字段类型、必填项、错误返回规范模板存储方案工程选型轻量项目常量文件Python/Java 枚举统一存放prompt_template.py/PromptTemplate.java所有模板集中管理支持注释、版本标记。 示例 PythonpythonEXTRACT_DATA_TEMPLATE # 角色定义 你是专业数据抽取专家仅根据提供的参考文本提取信息禁止编造不存在内容。 # 全局约束 1. 所有数据必须来源于【参考材料】无对应信息填空字符串 2. 禁止输出解释、思考、多余文字只返回指定JSON # 任务指令 根据用户问题从参考材料中抽取目标字段信息 # 输入变量 用户问题{{query}} 参考材料{{docs}} # 输出格式要求 {{json_schema}} 中大型项目配置中心Nacos/Apollo/Redis模板存入配置中心支持热更新无需重启服务即可修改 Prompt 规则适合运营频繁调优场景客服、审核。 优势区分环境测试 / 生产、灰度下发、操作日志记录谁修改了模板。LLM 平台化项目独立 Prompt 管理后台可视化编辑模板、内置变量校验、在线调试插值效果、绑定模型版本、A/B 测试多套模板。3. 模板变量插值规范避坑要点统一占位符语法使用{{变量名}}和业务文本区分避免和普通括号冲突变量命名规范user_query用户输入、history_context历史对话、knowledge_list检索知识库、biz_config业务参数转义防护动态内容自动转义{{}}、换行符、引号防止变量内容破坏模板结构Prompt 注入防护模板校验机制启动 / 调用前校验模板内所有占位符是否都有入参缺失直接抛参数异常不送入 LLM。4. 模板化带来的工程收益可维护所有业务规则一处修改全服务生效可迭代多套模板并存标准版 / 高精度版 / 低成本版快速切换对比效果可审计模板变更留痕定位输出异常不用翻业务代码可复用抽取、总结、分类等通用模板跨模块复用。三、第二部分动态拼接上下文核心工程难点动态上下文 所有运行时可变输入用户实时提问、向量库召回知识库、多轮对话历史、业务标签、时间参数、用户权限等。 拼接核心目标信息完整、长度可控、顺序规范、防污染、防超限截断。1. 上下文组成标准拼接顺序权重从低到高固定拼接顺序保证 LLM 优先关注最新、最核心信息静态 Prompt 模板角色 / 规则最高优先级放最前业务固定参数用户等级、行业、时间范围检索知识库片段参考资料历史静态数据多轮对话历史按时间从旧→新排序当前用户最新提问放在最后LLM 重点处理2. 多轮对话历史动态拼接方案格式统一规范固定对话结构避免混乱每条历史消息强制结构化【用户】xxx 【助手】xxx示例拼接结果# 历史对话 【用户】充电桩收费标准是什么 【助手】峰时1.2元/度谷时0.5元/度 【用户】谷时时间段 【助手】23:00-次日7:00 # 当前用户问题 【用户】充电一小时多少钱超长上下文截断策略Token 超限必做LLM 有输入 token 上限如 GPT4 128k、通义千问 8k动态拼接必须做窗口滑动滑动窗口策略主流保留最新 N 轮对话丢弃最久远历史优先保留知识库内容次要丢弃老旧对话。摘要压缩策略长文档场景知识库片段过多时先调用小模型对召回文档做摘要压缩 token 再拼接优先级权重截断权重排序当前提问 最新 3 轮对话 知识库 老旧历史超限按权重从低到高删除。代码层拼接流程示例伪代码pythondef build_prompt(query, history, knowledge_chunks, biz_params): # 1. 加载静态模板 template EXTRACT_DATA_TEMPLATE # 2. 拼接知识库统一分段 docs_text \n---\n.join([f文档{i1}{chunk} for i, chunk in enumerate(knowledge_chunks)]) # 3. 拼接对话历史 history_text for msg in history[-5:]: # 滑动窗口只保留最近5轮 history_text f【用户】{msg.user}\n【助手】{msg.assistant}\n # 4. 插值填充模板变量 prompt template.replace({{query}}, query)\ .replace({{docs}}, docs_text)\ .replace({{history_msg}}, history_text)\ .replace({{biz_params}}, str(biz_params)) # 5. Token长度校验超限自动截断知识库 if count_token(prompt) MAX_INPUT_TOKEN: prompt truncate_knowledge(prompt) return prompt3. 知识库动态拼接避坑点文档分隔符统一用---分割多份检索文本让 LLM 区分不同资料来源去重召回知识库存在重复片段拼接前做文本相似度去重节省 token边界隔离知识库、历史、用户提问用明确标记隔离防止 LLM 混淆输入和输出禁止原始 HTML/Markdown 乱码直接拼接提前清洗换行、特殊标签减少无效 token。4. 安全防护防 Prompt 注入用户输入、外部知识库文本可能包含{{、# 角色、输出不要JSON等篡改指令破坏模板逻辑变量插值前转义特殊标记将{{替换为\{\{模板固定规则放在最顶部权重高于所有动态输入用户无法覆盖角色约束增加校验动态内容中出现 “忽略前面所有指令”“不要按照要求输出” 等注入关键词直接拦截。四、第三部分输出格式约束 —— 固定 JSON 返回工程落地核心自由文本输出会导致下游解析崩溃工业级 LLM 系统必须强制结构化 JSON 返回分三层约束模板强指令 Schema 约束 代码容错解析。1. Prompt 内强制 JSON 约束写法两种方案方案 1简单固定 JSON 模板字段少场景直接在模板末尾给出完整返回示例明确必填 / 空值规则## 输出硬性要求 1. 禁止输出任何解释、思考、前言、markdown、多余文字只能返回纯JSON 2. 不存在的数据字段值填空字符串数字填0数组为空[] 3. JSON不能有注释、不能换行错乱键名严格和下面一致 返回示例 { charge_price: 1.2, valley_time: 23:00-7:00, remark: }方案 2JSON Schema 标准约束复杂业务推荐直接将 JSON Schema 写入 Prompt标准化字段类型、枚举、必填项LLM 遵守 Schema 生成结果稳定性远高于简单示例。 模板示例片段# 输出JSON Schema规范严格遵守不允许新增字段、修改键名 { $schema: http://json-schema.org/draft-07/schema#, type: object, required: [name, phone, address], properties: { name: {type: string, description: 用户姓名无则为空}, phone: {type: string}, age: {type: integer, minimum: 0} } } 规则 1. 所有required字段必须存在 2. 类型严格匹配age必须是数字不能写字符串 3. 禁止返回json 代码块标记直接裸JSON。2. 解决 LLM 不遵守 JSON 的常见问题即使加约束模型仍可能输出 markdown 代码块、额外说明、残缺 JSON多层兜底方案兜底 1代码预处理清洗通用pythondef clean_llm_output(raw_text): # 移除 json 、 代码块标记 raw_text re.sub(r(json)?, , raw_text) # 去除首尾多余文字只截取第一个{到最后一个}之间内容 start raw_text.find({) end raw_text.rfind(}) if start -1 or end -1: return None json_str raw_text[start:end1] # 处理换行、制表符、中文空格 json_str json_str.replace(\n, ).replace(\t, ).strip() return json_str兜底 2异常重传机制JSON 解析失败时构造纠错二次 Prompt重新调用模型上一轮输出不符合JSON规范报错xxx 严格按照Schema重新生成纯JSON不要任何多余文字。兜底 3工具层强制校验JSON Schema 校验清洗完成后用 jsonschema 库校验结构、字段类型、必填项校验不通过直接触发重试或返回业务错误码。3. 业务异常统一 JSON 规范需要统一错误返回结构避免模型随机返回空 / 乱码 在模板中明确无数据、无法回答的标准返回当参考材料无对应信息、无法回答用户问题时固定返回 {code: 1001, msg: 暂无相关资料, data: {}} 正常返回code0data存放业务数据4. JSON 约束工程收益下游解析标准化统一用 JSON 库解析无需复杂正则减少线上 50% 以上解析异常结构化数据便于入库直接映射数据库实体 / DTO无需手动文本提取监控告警简单JSON 字段缺失、类型错误可自动化埋点统计快速定位 Prompt 缺陷多模型兼容切换通义、文心、GPT 等模型下游解析代码无需改动。五、完整端到端工程示例Python 可运行简化版1. 统一 Prompt 模板pythonKNOWLEDGE_QA_TEMPLATE # 角色 你是充电桩智能客服仅依据提供的参考文档回答用户问题严禁编造信息。 # 全局约束 1. 回答简洁不输出冗余描述无相关信息直接返回空数据 2. 输出只能是纯JSON禁止注释、代码块、额外文字 # 参考文档 {{knowledge}} # 历史对话 {{history}} # 用户当前问题 {{query}} # 强制输出JSON Schema { type: object, required: [code, answer, source], properties: { code: {type: integer, description: 0正常1001无资料}, answer: {type: string, description: 回答内容}, source: {type: array, description: 引用文档编号无则空数组} } } 无资料标准返回{code:1001,answer:暂无相关充电规则,source:[]} 2. 动态上下文拼接函数pythonimport re import json def build_full_prompt(user_query, history_msg_list, recall_docs): # 1. 拼接知识库 doc_text for idx, doc in enumerate(recall_docs): doc_text f文档{idx1}{doc}\n---\n # 2. 拼接对话历史滑动窗口保留最近3轮 history_text for item in history_msg_list[-3:]: history_text f【用户】{item[user]}\n【客服】{item[assistant]}\n # 3. 插值填充模板 prompt KNOWLEDGE_QA_TEMPLATE prompt prompt.replace({{knowledge}}, doc_text) prompt prompt.replace({{history}}, history_text) prompt prompt.replace({{query}}, user_query) return prompt3. JSON 清洗 解析工具pythondef parse_json_output(raw_resp): # 清洗代码块标记 clean_str re.sub(r.*?, , raw_resp, flagsre.S) left clean_str.find({) right clean_str.rfind(}) if left 0 or right 0: return None json_str clean_str[left:right1] try: data json.loads(json_str) # 基础字段校验 assert code in data and answer in data and source in data return data except Exception: return None4. 调用主流程python# 输入上下文 query 谷时充电多少钱一小时 history [{user:峰时电价,assistant:1.2元/度}] docs [谷时电价0.5元/度时段23:00-7:001小时充电约5元] # 1. 拼接完整Prompt full_prompt build_full_prompt(query, history, docs) # 2. 调用LLM模拟返回 llm_raw 根据文档谷时充电一小时约5元\n{code:0,answer:谷时充电一小时约5元,source:[文档1]} # 3. 清洗解析 result parse_json_output(llm_raw) print(result)六、线上生产环境落地优化要点模板版本管理每套模板记录 version日志打印使用的模板版本便于回溯 bad caseToken 监控埋点统计每次拼接后输入 token 长度监控截断频率优化知识库召回数量JSON 解析失败告警接入监控系统解析失败次数突增自动告警大概率是模板约束失效多模板灰度同一业务配置两套模板按用户流量灰度下发对比 JSON 准确率缓存优化固定业务参数、静态知识库摘要可缓存减少重复拼接计算限流与重试JSON 解析失败重试 1 次避免无限循环调用 LLM 浪费成本。七、三大技术组合核心价值总结模板化 Prompt统一管控业务规则消除硬编码支持热更新、可维护动态上下文拼接标准化多源信息整合滑动窗口控制 token防注入、防超限JSON 格式强约束输出结构化、下游解析零复杂逻辑线上异常大幅降低适配自动化数据处理。三者结合是企业 LLM 系统标准化、工业化落地的标配架构几乎所有知识库问答、抽取、自动化业务系统都会采用这套方案。