读完这篇,你能做什么
能把模糊需求改写为模板,并用八个边界样例比较两个提示版本。
学习理由、准备要求与知识点
为什么学它
先说清任务怎样才算完成,再用固定样例比较提示版本,才能知道改法是否有效。
先读这些内容
知识点清单
- 任务目标与验收标准
- 输入资料边界
- 零样本提示
- 少样本示例一致性
- 缺失与冲突信息策略
- 模板变量与分隔符
- 单因素提示实验
- 解释文本与证据区别
运行前先确认完整算法使用 Java 17 标准库;JDK 源码基线为 OpenJDK 17 GA。示例是内存中的机制模型,外部服务接入需要另外配置和验证。
01先弄懂它是什么
提示写得清楚,首先要把要做的事说清楚。“帮我整理资料”没有说明范围、来源和怎样算完成。换成“从给定笔记提取三条索引使用条件,每条附片段 ID,资料不足时说明缺项”,程序就有办法检查结果。任务、输入和验收条件越明确,提示也越容易维护。
只说明任务、不给示例,叫零样本提示;补充少量输入输出例子,叫少样本提示。例子不只是展示语气,还会影响模型采用哪些字段、按什么顺序写、缺资料时怎么办,因此彼此不能矛盾。例如同时给出“资料足够”和“资料不足”两种样例,就能更清楚地说明什么时候应回答、什么时候应说明缺项。
模板变量将稳定规则和动态数据分开,方便版本化与测试。但分隔符只是表达结构,不是权限墙。资料中出现“忽略规则”仍是不可信文本,应用必须在工具授权与数据边界处执行策略,不能把安全性完全寄托于一段提示。
文中这几个词,先认一认
- 验收标准
- 能实际核对的完成条件,例如字段是否齐全、引用是否对应来源、缺资料时是否明确说明。
- 模板变量
- 模板里由应用填入动态数据的位置。填入的内容不应被再次当作新的模板指令执行。
- 少样本示例
- 用少量输入和理想输出来说明任务应该怎么做,这些例子需要遵守同一套规则。
02看看它怎么工作
把提示拆成目标、资料、输出约束与缺失策略四部分。每部分只解决自己的问题:目标说明要做什么,资料声明可使用内容,约束定义输出形态,缺失策略处理不足和冲突。不要让示例中的临时事实变成所有请求的固定答案。
渲染模板时,只扫描原始模板并替换其中允许的变量一次。例如用户资料本身包含 ${secret},应把它当作普通文字放进去,不要再把 secret 当变量继续查找。否则资料内容就能改变模板处理过程,甚至带出内部字段。这个做法保护的是模板怎样被解释,并不能单独解决模型读到恶意指令后的提示注入。
实验时固定一组正常、空资料、冲突资料和恶意指令资料,先保存模板版本,再每次只改一个因素。记录合规率与具体失败类型,而不是凭一次回答是否顺眼决定优劣。模型提供的“我已核对”也应由引用映射或外部检查证实。
正在加载流程图…
查看流程图源码(Mermaid)
flowchart LR
G["任务与验收标准"] --> T["版本化模板"]
D["授权资料变量"] --> R["单次字面渲染"]
T --> R
R --> M["模型输出"]
M --> V["结构与证据校验"]
V --> E["固定样本比较"]按顺序看,每一步做了什么
- 把模糊目标写成可以核对的输出和禁止行为。
- 确定输入资料范围与缺失、冲突处理策略。
- 选择一致的少样本示例,建立版本化模板。
- 单次渲染变量,不递归解释变量值。
- 在固定样本上做单因素比较并保留失败回归。
03对照实现代码
OpenJDK 17 GA,jdk-17+35 · Matcher.quoteReplacement / appendReplacement
下方为原创 Java 教学片段,调用已核验的 JDK API 说明局部机制;不是该类原样源码,也不实现神经网络。完整程序见算法模块。
Matcher matcher = Pattern.compile("[$][{]([a-z]+)[}]").matcher(template);
StringBuffer out = new StringBuffer();
while (matcher.find()) {
String value = values.get(matcher.group(1));
// 替换语法中的美元符号和反斜线按普通字符处理,避免被当作分组引用。
matcher.appendReplacement(out, Matcher.quoteReplacement(value));
}
matcher.appendTail(out);Matcher.quoteReplacement生成适合替换字符串语法的字面表示,主要处理美元符号和反斜线;它不是HTML转义、JSON转义或模型安全过滤器。
appendReplacement扫描的是原匹配输入,替换值被追加到输出缓冲,不自动再次作为模式输入。本题完整程序使用手写单遍扫描,显式展示同样的不递归边界。
模板变量不存在时应给出明确错误,而不是把null拼成字符串。生产模板还需控制允许变量名和最大输出长度,防止配置错误或巨大资料使请求失控。
Java片段解释的是确定性字符串处理。模型如何理解最终提示仍有概率性,模板渲染正确只能证明构造的文字符合规则,不能证明模型一定遵守所有自然语言要求。
代码先调用谁,再调用谁
- 加载受版本控制模板
- 识别原模板变量
- 检查变量白名单及存在性
- 按字面追加值而不递归解释
- 将完整提示交给后续受控调用
04动手写一个例子
不递归的单遍模板渲染
模板支持${name},变量名只能是字母数字下划线且非空;未知变量或未闭合表达式拒绝。替换值不再次展开。Java17 Main.java含固定边界测试。
- 输入 1
模板你好${name},name=Java- 输出 1
你好Java
- 输入 2
模板${x},x=${secret}- 输出 2
${secret}
游标只在原模板中前进,找到起始符后定位对应右花括号,验证变量名再取值。输出缓冲不重新送回扫描器,因此变量值无法引入新的展开步骤。
不以反复String.replace实现渲染,避免变量遍历顺序改变结果。例如先替换x再替换secret会误展开x的值,而相反顺序又产生不同输出。
遇到非法变量直接失败,调用者可以定位模板配置。没有占位符的普通文本原样保留,空模板输出空串;这种可预测行为便于对提示版本做差异测试。
为什么这样写是对的游标之前的原模板已按规则恰好处理一次,输出是该前缀的字面渲染;输出中出现的占位符从不影响剩余原模板的解释。
T为模板长度,O为输出长度;各模板片段扫描和复制次数有界,变量哈希查找平均常数但需读取变量名。输出巨大时空间同样巨大,应由上层设置长度上限。
保存为 Main.java,运行 javac --release 17 -encoding UTF-8 Main.java,再运行 java Main。程序包含固定输入自测,断言失败时会抛出错误。
import java.util.*;
public class Main {
static String render(String template,Map<String,String> values){
StringBuilder out=new StringBuilder();int i=0;
while(i<template.length()){
if(template.charAt(i)=='$'&&i+1<template.length()&&template.charAt(i+1)=='{'){
int end=template.indexOf('}',i+2);
if(end<0)throw new IllegalArgumentException("unclosed variable");
String name=template.substring(i+2,end);
if(name.isEmpty())throw new IllegalArgumentException("empty name"); // 空变量名属于模板配置错误。
for(char c:name.toCharArray())if(!(c>='a'&&c<='z'||c>='A'&&c<='Z'||c>='0'&&c<='9'||c=='_'))throw new IllegalArgumentException("name");
String value=values.get(name);if(value==null)throw new IllegalArgumentException("missing variable");
out.append(value);i=end+1; // 值只追加,绝不重新扫描它。
}else out.append(template.charAt(i++));
}
return out.toString();
}
static void eq(String e,String a){if(!e.equals(a))throw new AssertionError(a);}
static void bad(String t){try{render(t,Map.of());throw new AssertionError();}catch(IllegalArgumentException expected){}}
public static void main(String[] args){
eq("你好Java",render("你好${name}",Map.of("name","Java")));
eq("${secret}",render("${x}",Map.of("x","${secret}","secret","hidden")));
eq("$5"+(char)92+"x",render("${x}",Map.of("x","$5"+(char)92+"x")));// 字面保留特殊字符。
eq("",render("",Map.of()));eq("AA",render("${x}${x}",Map.of("x","A")));
bad("${missing}");bad("${x");bad("${}");
System.out.println("PASS 8 tests");
}
}这些特殊情况也要试一试
- 值含新的占位符也保持字面,不递归展开。
- 变量名缺失与变量值为空字符串不同,空值可合法输出。
- 未闭合模板是配置错误,不能默默当普通文字。
进阶选读 · 后续再读:可组合模板的依赖验证
场景模板片段相互引用且需要复用,单遍规则不足以表达结构。
做法把引用建成有向图,先检测循环与未知节点,再按拓扑顺序展开;限制总展开长度,避免无环但指数膨胀的重复引用。
复杂度图验证O(V+E),实际展开至少O(输出长度);无环并不保证输出长度对输入图规模为线性。
好处与代价组合模板提高复用,但增加依赖与版本管理;简短固定模板往往更易审计和比较。
05项目里怎么用
将提示模板当作可版本化配置,与数据样本和输出Schema一起评审。修改“允许补充常识”为“仅使用资料”会改变正确性标准,必须相应调整评估集。模板版本应进入运行元数据,才能解释相同问题在两次运行中的行为变化。
输入资料保留来源ID、时间与适用版本,冲突时要求指出分歧而非擅自合并。示例可以展示如何引用,但最终引用ID必须来自当前允许集合。模板渲染器不应把隐藏凭证或跨用户资料作为变量提供,即使提示声明“不要泄露”也不能替代数据最小化。
安全验收看实际工具轨迹:恶意资料是否诱导越权检索、写操作或外部发送。提示层表达规则,应用层执行授权、参数校验与确认;这两个层次配合才能缩小失控范围。基础练习先完成确定性模板与固定样本,再读工具安全专题。
容易踩的坑
- 大量添加“专业、认真”等词却没有验收标准。
- 少样本示例字段与正式要求不一致。
- 递归展开用户数据,改变模板控制流程。
- 将分隔符或
quoteReplacement当作提示注入防护保证。
几种做法,怎么选
表格有四列,窄屏可左右滑动查看代价和适用条件。
| 方案 | 优势 | 代价与限制 | 适用条件 |
|---|---|---|---|
| 零样本规格 | 短且易维护 | 复杂格式可能表达不充分 | 任务简单且契约明确 |
| 少样本模板 | 能展示边界和风格 | 占上下文,示例偏差会传播 | 需要示范结构与缺失处理 |
| 程序校验配合提示 | 可强制结构与授权边界 | 需要额外代码和错误流程 | 可验收的正式应用 |
06检验是否读懂了
先自己想、自己写,再展开答案核对。场景题是假设的练习情境;遇到还没学过的内容,可以做完基础后再回来。
先用自己的话解释
01提示目标与验收标准有何区别?
展开参考答案与推导
目标说明想完成什么,验收标准说明怎样核对完成;“整理知识”是目标,“三条条件并附来源ID”是可检查标准。
02quoteReplacement能防什么?
展开参考答案与推导
它防止替换字符串中的特殊字符被解释成正则替换语法,不负责HTML、JSON或模型层安全。
03为什么变量值不应递归展开?
展开参考答案与推导
动态数据不应改变模板控制结构;递归还使结果依赖替换顺序,并可能读取原本不该引用的变量。
换个情况,还会处理吗
01提示改完一次回答很好,能认定更优吗?
展开参考答案与推导
需要在固定样本和相同配置下重复比较,通过率与失败类型比单个展示案例更有解释力。
02资料要求忽略规则,该在哪里阻止越权?
展开参考答案与推导
把资料作为不可信输入,同时由应用检查身份、工具范围和资源归属;提示提醒只是其中一层。
03引用格式正确却来源不存在怎么办?
展开参考答案与推导
核对引用ID是否在当前资料集合,拒绝未知ID并保留失败样本;格式规范不能证明引用真实存在。
写代码试一试
01两次相同变量怎么处理?
- 输入 / 条件
${x}-${x},x=A- 输出 / 预期
A-A
提示 每次读取原模板变量。
展开参考答案与推导
两处都追加同一字面值,输出不被再次扫描,复杂度与最终输出长度相关。
02如何区分空值与缺字段?
- 输入 / 条件
x=""与没有x- 输出 / 预期
前者输出空串,后者拒绝
提示 检查映射存在与值策略。
展开参考答案与推导
本题允许空字符串但拒绝null;若业务允许null,应使用containsKey区分存在性并明确null渲染规则。
03无环模板为什么仍可能很大?
- 输入 / 条件
每层引用前一片段两次- 输出 / 预期
展开长度随层数倍增
提示 图规模与输出规模不同。
展开参考答案与推导
拓扑检测只保证没有循环,不能限制重复复制;必须设置最大输出长度并对共享片段采用受控渲染。
读完之后,独立完成
课后作业:自己做一遍
本篇共 10 道作业,先完成 8 道基础与综合任务,再按前置知识挑战进阶题。其中包含 1 道思维拓展,试着换个条件,看看原来的办法是否还管用。不附参考答案。
能把模糊需求改写为模板,并用八个边界样例比较两个提示版本。
本篇重点加练
资料边界与单因素实验帮助识别提示改动的真实作用,重点防止比较条件被同时改变。
- 输入资料边界
- 单因素提示实验
重点内容会多练几次。先说清楚怎么做,再试试空数据、出错或条件改变时会发生什么。
先自己做,卡住时记下问题,再回来查。问答题写清“为什么、什么时候适用”;动手题留下输入、输出和运行步骤,方便下次重做。
基础必做
- 作业 01原理问答
将“帮我安排学习”改写为可验收任务,明确输入资料、目标用户、结果字段和资料之外的信息处理要求。
- 提交内容
- 一份独立书面回答或标注图,包含自造例子、概念边界及判断依据。
- 怎样算完成
- 逐项回应题目要求,区分事实、假设与个人判断。
- 能用自己的例子解释适用条件,记录尚未弄懂的点。
练到的知识点任务目标与验收标准 · 输入资料边界
- 作业 02代码推演
为同一任务分别构造零样本与两例少样本提示,逐项审查示例在格式、标签和边界处理上是否一致。
- 提交内容
- 手工推演记录,写明输入约定、中间状态、最终判断;可运行时附程序对照记录。
- 怎样算完成
- 推演包含中间过程,数据形状、单位、顺序或状态前后一致。
- 主动检查至少一个边界或异常条件,能解释手算与运行差异。
练到的知识点零样本提示 · 少样本示例一致性
- 作业 03原理问答
为提示实验编写输入冻结清单,区分任务内容、资料版本、提示变量与外部模型设置,说明哪些变化会让单因素结论失效。
- 提交内容
- 概念或合同说明、关系图与自造案例,明确事实、假设和适用条件。
- 怎样算完成
- 关键概念有明确边界,能用案例检验声明。
- 未获证据支持的假设单独标注。
练到的知识点输入资料边界 · 单因素提示实验
综合应用
- 作业 04面试场景
输入资料缺少截止日期且两条记录相互矛盾,模板变量中还包含类似分隔符的内容。设计输出契约与输入编码规则。
- 提交内容
- 场景分析与决策记录,包含信息缺口、约束、备选方案和验证计划。
- 怎样算完成
- 方案回应给定约束,列出至少一种替代方案及代价。
- 每项关键结论说明所需证据,不能核实的部分明确标注。
练到的知识点缺失与冲突信息策略 · 模板变量与分隔符
- 作业 05编程实践
建立六条固定测试输入,仅改变一个提示因素并运行假模型或可用模型,分别记录结果与引用证据,保留不能验证的输出。
- 提交内容
- 可复现的最小程序或实验材料、自写测试、环境说明与运行记录;题目允许纸面实验时提交完整案例表。
- 怎样算完成
- 提交物按说明可以重现;测试覆盖正常、边界与失败场景。
- 运行证据与断言能核验声明的行为,注明模拟与真实执行范围。
练到的知识点单因素提示实验 · 解释文本与证据区别
- 作业 06排错实验
在少样本中故意插入一个格式冲突例子,再将变量替换为空值,观察并记录失败类型,不把一次成功当稳定性证明。
- 提交内容
- 最小故障输入、复现步骤、观测记录、定位依据及回归用例。
- 怎样算完成
- 其他人可按记录复现故障,并区分现象与已验证原因。
- 定位过程有观测依据,回归用例可以再次暴露原问题。
练到的知识点输入资料边界 · 少样本示例一致性 · 模板变量与分隔符
- 作业 07编程实践
构造两份只在资料边界表达上不同的提示,使用同一组含额外无关资料的离线任务,保存逐项判定记录和实际改变的文本差异。
- 提交内容
- 可复现的小程序或题目允许的离线实验、自写测试、输入和运行记录。
- 怎样算完成
- 输入、环境和运行过程可重现,测试覆盖声明的重点条件。
- 验证目标由合同确定,模拟结果不冒充真实服务证据。
练到的知识点输入资料边界 · 单因素提示实验
- 作业 08排错实验
一份提示对照报告同时换了示例、模型与资料版本。拆解报告的可支持结论,设计最少的补充实验来缩小不确定性。
- 提交内容
- 最小故障序列、观测记录、原因核对与可再次触发原问题的测试。
- 怎样算完成
- 故障可以稳定重现,现象与已验证原因分开。
- 观测记录足以判断声明的合同是否被违反。
练到的知识点输入资料边界 · 单因素提示实验
进阶挑战 · 掌握前置后选做
- 作业 09设计评审
设计提示版本的发布与回滚流程,包含开发样例、冻结测试集和人工复审,说明何种证据足以支持更新。
- 提交内容
- 设计评审文档或对照实验报告,包含前置条件、方案取舍、验收证据与尚未验证的范围。
- 怎样算完成
- 比较使用一致条件与事先声明的标准,记录失败与未知结果。
- 说明方案的适用前提、未覆盖风险及后续验证方法。
练到的知识点任务目标与验收标准 · 缺失与冲突信息策略 · 单因素提示实验
思维拓展
先写出你的猜想,再用例子或实验验证。答案可以不同,但要说清依据、适用情况,以及还有什么没弄懂。
- 作业 10思维拓展 · 开放探究
提出“明确标出资料范围能改善某类任务”的可证伪假设,预先定义失败情形与评价方法,并说明样本不足时如何限制结论。
- 提交内容
- 可证伪假设、预先声明的比较协议、小规模证据与限制说明。
- 怎样算完成
- 假设存在可被否定的条件,协议在观察结果前声明。
- 包含不支持假设的可能结果及不确定性说明。
练到的知识点输入资料边界 · 单因素提示实验
完成后,再检验一次
给每题标记“独立完成 / 查阅后完成 / 尚未完成”。查过资料或没做出的题,记下卡在哪里。隔一天换一组输入再试,能解释结果和出错原因,再把这个知识点标为掌握。
继续阅读
先看能帮你完成当前练习的部分。例子跑通后,再读更深入的解释。
- 必读实践指南英文
Transformers:Prompt engineering (新标签页)↗
阅读任务说明、少样本示例和提示迭代方法,建立固定样例集比较不同提示版本。
- 实践参考文档英文
Spring AI:ChatClient (新标签页)↗
按所选 Spring AI 版本阅读请求构造、完整响应、实体映射及流式响应;保留元数据用于验收。
- 深入实践指南英文
OWASP:提示注入防御指南 (新标签页)↗
阅读直接和间接提示注入、工具相关攻击与多层防御,使用虚构资料验证执行边界。
- 深入参考文档英文
OpenJDK 17 Matcher 源码 (新标签页)↗
按指定版本定位
Matcher.quoteReplacement/appendReplacement;对照源码分析理解实际调用边界。