Prompt 基础
Prompt 的核心是把角色、任务、上下文、输出格式和回答边界说清楚,让模型更稳定地完成具体任务。
Prompt 是什么
Prompt,中文一般翻译为“提示词”或“提示语”。
Prompt 可以先理解成给大模型的输入说明。
它不只是用户问的一句话,而是由几部分组合出来的:
角色设定
任务目标
上下文资料
输出要求
示例
限制条件
用户问题
上一篇调用 API 时已经看到 messages 了。
[
{
"role": "system",
"content": "你是一个严谨的 Java 后端工程师,回答要简洁。"
},
{
"role": "user",
"content": "什么是 LLM API?用一句话解释。"
}
]
这里的 system 和 user,其实就是 Prompt 工程最基础的入口。
结论:
Prompt 要明确任务说明、上下文和输出规则,目标是提高模型回答的稳定性。
Prompt 的使用场景
普通聊天、RAG、Tool Calling、Agent 都会用到 Prompt。
普通聊天:
用户问题
-> 拼接 system / user prompt
-> 调用 LLM API
-> 返回回答
RAG:
用户问题
-> 检索知识库
-> 把资料放进 Prompt
-> 要求模型只根据资料回答
-> 返回答案和引用来源
Agent:
用户任务
-> Prompt 说明可用工具和执行规则
-> 模型判断下一步
-> 调用工具
-> 再根据工具结果生成最终回答
Prompt 的作用是:
让模型知道自己扮演什么角色
让模型知道当前要解决什么问题
让模型知道哪些事情不能乱答
让模型按后端服务需要的格式输出
System Prompt
system prompt 主要放全局规则。
可以理解成这次对话或这次调用的“工作说明”。
比如:
{
"role": "system",
"content": "你是一个严谨的 Java 后端工程师。回答要简洁,优先给可落地的方案,不确定时直接说明不确定。"
}
这里适合放:
角色
回答风格
安全边界
输出格式
业务规则
禁止事项
不适合放太多临时问题。
临时问题应该放到 user prompt 里。
一个简单例子
你是一个严谨的 Java 后端工程师。
请用面向工程落地的方式回答问题。
如果问题信息不足,先说明缺少什么信息。
不要编造不存在的接口、类名或配置项。
这类规则适合作为固定模板。
后面写成代码时,可以像这样组织:
String systemPrompt = """
你是一个严谨的 Java 后端工程师。
请用面向工程落地的方式回答问题。
如果问题信息不足,先说明缺少什么信息。
不要编造不存在的接口、类名或配置项。
""";
User Prompt
user prompt 放用户当前的具体问题。
比如:
{
"role": "user",
"content": "Spring Boot 项目里怎么用环境变量读取 API Key?"
}
如果问题比较复杂,最好不要只写一句话。
可以按这个结构写:
背景
目标
约束
输入
希望输出
比如:
背景:我是 Java 后端,正在学习 AI Agent。
目标:想在 Spring Boot 里安全读取大模型 API Key。
约束:不要把 Key 写死到代码里。
希望输出:给一个最小可用示例。
这种写法比单纯问一句:

怎么读取 API Key?
要稳定很多。

结论:
输入越清楚,输出越接近预期。
System 和 User 怎么分工
可以先按这个规则理解:
长期规则放 system
当前问题放 user
业务资料放 user 或单独上下文
历史对话按顺序放 user / assistant
示例:
{
"messages": [
{
"role": "system",
"content": "你是一个严谨的 Java 后端工程师。回答要简洁,不确定时说明不确定。"
},
{
"role": "user",
"content": "请解释 Spring Boot 中 Controller、Service、Repository 的分工。"
}
]
}
不要把所有东西都堆进一段大文本里。
后面系统复杂后,Prompt 最好拆成几块:
systemPrompt
contextPrompt
taskPrompt
outputPrompt
这样代码更容易维护,也方便后面调试效果。
Few-shot 是什么
Few-shot 就是在 Prompt 里给几个示例。
模型会根据示例学习你想要的回答方式。
比如我要模型把用户问题分类成:
技术问题
账号问题
订单问题
其他问题
可以这样写:
请判断用户问题类型,只返回分类名称。
示例1:
用户:登录时提示 token 过期怎么办?
分类:账号问题
示例2:
用户:我的订单为什么还没发货?
分类:订单问题
示例3:
用户:Java 调用接口超时怎么排查?
分类:技术问题
现在判断:
用户:Spring Boot 项目启动后端口被占用怎么办?
分类:
Few-shot 的价值在于:
减少模型自由发挥
统一输出风格
让模型理解边界
提高分类、抽取、改写任务的稳定性
Zero-shot 和 Few-shot
不提供示例,直接让模型完成任务,叫 zero-shot。
请判断这个问题的类型:我的订单为什么还没发货?
提供几个示例,再让模型完成任务,叫 few-shot。
示例1:...
示例2:...
现在判断:我的订单为什么还没发货?
我的使用习惯可以先这样定:
简单问答:zero-shot
分类任务:few-shot
格式要求严格:few-shot
模型总是答偏:few-shot
如果后面要做客服 Agent,意图识别、工单分类、问题改写这些地方都很适合用 few-shot。
约束回答边界
大模型有一个问题:
会补全
会猜
会把不确定说得像确定
所以 Prompt 里要明确边界。
常见约束:
不知道就说不知道
只能根据给定资料回答
不要编造字段、接口、链接
不要输出无关解释
输出必须符合指定格式
如果信息不足,先说明缺少什么信息
比如 RAG 里经常这么写:
请只根据下面的资料回答用户问题。
如果资料中没有答案,请回答“根据现有资料无法判断”。
不要使用资料之外的知识补充答案。
回答最后列出引用的资料编号。
这类边界很重要。
不然知识库问答系统最容易变成:
资料里没有
模型自己脑补
用户以为系统真的查到了
这就是后面做 RAG 时要重点防的幻觉问题。
输出格式约束
学习阶段可以先用普通文本约束。
比如:
请按下面格式回答:
结论:
原因:
示例:
注意点:
如果要让后端解析,就要更严格。
比如:
请只输出 JSON,不要输出 Markdown,不要添加解释。
{
"category": "订单问题",
"confidence": 0.8,
"reason": "用户询问订单发货状态"
}
不过这篇先不展开 JSON。
下一篇 Day 4 会专门整理结构化输出,包括:
让模型输出 JSON
Java 解析 JSON
Python Pydantic 校验
异常兜底
这里先记住一点:
只靠一句“请输出 JSON”不够,工程里还要做解析、校验和兜底。
Prompt Template
后面写代码时,不可能每次手写一整段 Prompt。
更常见的是做模板。
比如:
你是一个技术学习助手。
请根据下面资料回答问题:
资料:
{context}
用户问题:
{question}
要求:
1. 只根据资料回答
2. 不知道就说不知道
3. 回答要简洁
代码里填变量:
String prompt = template
.replace("{context}", context)
.replace("{question}", question);
正式项目里可以用更规范的模板工具。
但学习阶段先理解本质:
固定规则
+
动态上下文
+
用户问题
=
一次完整 Prompt
Java 后端视角下的 Prompt
对 Java 后端来说,Prompt 不应该散落在业务代码里。
不建议这样:
String prompt = "你是...请帮我..." + userInput;
更好的做法是先拆出来:
prompt/
├── system-prompt.md
├── rag-answer-prompt.md
├── intent-classify-prompt.md
└── tool-result-summary-prompt.md
或者放到配置里:
application.yml
数据库
配置中心
后面如果要优化效果,至少能知道改的是哪一类 Prompt。
这也方便做版本记录:
v1:回答太发散
v2:增加“不知道就说不知道”
v3:增加引用来源格式
v4:增加 few-shot 示例
Prompt 也要像代码一样管理。
常见问题
回答太长
加输出长度和格式要求。
请用 5 句话以内回答。
请按要点输出,不要展开背景介绍。
也可以配合 API 参数:
max_tokens
回答不稳定
降低随机性。
temperature: 0.1 - 0.3
再补 few-shot 示例。
如果是分类、抽取、判断类任务,示例通常很有用。
模型乱编
加边界约束。
不知道就说不知道。
不要编造不存在的字段、接口、类名或链接。
如果资料不足,说明缺少什么信息。
RAG 场景还要加:
只根据给定资料回答。
不要使用资料之外的知识。
输出格式不对
先用更明确的格式说明。
比如:
只输出下面四行:
分类:
置信度:
原因:
建议:
如果后端必须解析,下一步就要上 JSON 结构化输出和校验。
System Prompt 写很多还有用吗
有用,但不是越长越好。
太长的问题是:
增加 token 成本
模型可能抓不住重点
后续维护困难
我的原则:
长期稳定规则保留
临时任务不要塞进去
能用示例说明的,不写一堆抽象规则
一个完整示例
下面是一个学习阶段可以直接拿来测试的 Prompt。
System:
你是一个严谨的 Java 后端工程师。
请用工程落地视角回答问题。
如果信息不足,请说明缺少什么信息。
不要编造不存在的接口、类名、配置项或链接。
User:
背景:我正在学习 AI Agent,已经能调用 LLM API。
目标:理解 Prompt 的基础写法。
问题:System Prompt、User Prompt、Few-shot 分别是什么?什么时候用?
希望输出:
1. 用简单的话解释
2. 给一个示例
3. 说明常见坑
这类写法比只问:
讲一下 Prompt
要好很多。
它把背景、目标、问题和输出要求都给清楚了。
练习清单
这一篇我只要求自己完成几件事:
能区分 system prompt 和 user prompt
知道 system 里放长期规则
知道 user 里放当前问题
能写一个带背景、目标、约束的 user prompt
能写一个 few-shot 分类示例
知道怎么限制模型不要乱编
知道 RAG 里为什么要写“只根据资料回答”
知道输出格式约束和 JSON 结构化输出不是一回事
可以准备三个小练习。
练习 1:普通问答 Prompt
角色:Java 后端学习助手
任务:解释一个技术概念
要求:简洁、准确、给示例
练习 2:分类 Prompt
输入用户问题
输出问题分类
分类范围:技术问题 / 账号问题 / 订单问题 / 其他问题
加 3 个 few-shot 示例

练习 3:RAG 边界 Prompt
给定一段资料
要求模型只根据资料回答
资料里没有就说无法判断
不要补充资料之外的信息
建议目录:
ai-agent-study
├── java
│ └── prompt-demo
│ └── PromptDemo.java
├── python
│ └── prompt-demo
│ └── prompt_demo.py
└── docs
└── prompt-basic.md

小结
这一篇先记住这句话:
Prompt 的核心不是把话写得玄,而是把角色、任务、上下文、格式和边界写清楚。
对 Java 后端来说,Prompt 后面会变成系统的一部分。
它会参与:
普通聊天
RAG 问答
意图识别
Tool Calling
Agent 工作流
结果总结
异常兜底
所以不要只把 Prompt 当成临时字符串。
更好的习惯是:
拆模板
留版本
可测试
可回滚
能配合日志观察效果
先掌握 system、user、few-shot 和边界约束,后面再接结构化输出、RAG 和 Agent。
它们的外层结构很像,区别主要在知识怎么组织、规则怎么写。
可以这样记:
普通问答 Prompt:告诉模型怎么回答
Few-shot Prompt:给模型几个例子,让它照着做
RAG Prompt:给模型一批资料,让它只能基于资料回答
更抽象一点:
Prompt = 任务说明 + 上下文信息 + 约束条件 + 输出格式
你后面写 AI Agent、RAG、分类器,基本都是在改这四样东西。
比如:
任务说明:你要做什么?
上下文信息:给你哪些资料?
约束条件:哪些不能做?
输出格式:最后怎么返回?
真正工程里,Prompt 不要写得太玄乎。先按这个模板来就够了:
你是一个【角色】。
你的任务是:【任务目标】。
规则:
- 【规则1】
- 【规则2】
- 【规则3】
参考信息:
【上下文 / 示例 / 知识库内容】
用户输入:
【用户问题】
输出要求:
【只返回 JSON / 只返回分类 / 先结论后解释】
一句话:Prompt 的骨架基本一样,变化的是任务、资料、边界和输出格式。


Comments | 0 条评论