第一章 1.3:System Prompt 定义模型角色 ------ 告诉 AI"你是谁"
课程 :《AI 全栈应用开发》
章节 :第一章 把模型变成能力
小节 :1.3 Prompt 控制
适合人群 :所有人
前置知识:第一章 1.1-1.2:基础模型调用与 TypeScript 入门(./01-1.1-1.2 基础模型调用与 TypeScript 入门.md)
本篇知识点
- 什么是 System Prompt
- System Prompt 的三个要素
- 同一个模型,不同的角色
- 生产环境中的 System Prompt
- Autix 的做法(结构化能力表)
- 测试用例(3 个场景)
1. 什么是 System Prompt?
想象一下,你招聘了一个新员工。他能力很强,但不知道:
- 他在公司是什么职位?
- 他应该用什么语气和客户说话?
- 他遇到什么问题应该上报?
你会怎么做?给他一份岗位说明书。
System Prompt 就是 AI 的"岗位说明书"。它告诉模型:
- 你是谁(角色)
- 你应该怎么做(行为)
- 你不能做什么(边界)
2. 第一个例子:AI 客服
没有 System Prompt
typescript
const response = await callModel({
messages: [
{ role: 'user', content: '我买的商品什么时候能发货?' },
],
});
// 模型回答(可能是):
// "一般情况下,商品会在下单后 48 小时内发货。"
问题:模型的回答太通用了,不像一个专业客服。
有 System Prompt
typescript
const response = await callModel({
system: '你是某电商平台的智能客服,语气要友好专业,回答要简洁,遇到无法解决的问题要引导用户联系人工客服。',
messages: [
{ role: 'user', content: '我买的商品什么时候能发货?' },
],
temperature: 0.3, // 客服场景需要稳定、确定的回答
});
// 模型回答:
// "您好!一般情况下,商品会在下单后 48 小时内为您安排发货。
// 您可以前往"我的订单"页面查看具体的预计发货时间。
// 如需查询特定订单的发货进度,请提供您的订单号,
// 或直接点击"联系人工客服"由专属客服为您核实。祝您生活愉快!"
区别:
- 用了"您好"、"为您"等客服用语
- 提供了具体的操作指引("我的订单"页面)
- 引导用户联系人工客服(符合 system prompt 的要求)
3. 同一个模型,不同的角色
这是"把模型变成能力"的核心:模型是通用的,prompt 让它专业化。
场景 A:AI 客服
typescript
const response = await callModel({
system: '你是某电商平台的智能客服,语气要友好专业,回答要简洁。',
messages: [
{ role: 'user', content: '我买的商品什么时候能发货?' },
],
temperature: 0.3,
});
场景 B:代码审查助手
typescript
const response = await callModel({
system: '你是资深 Java 工程师,负责代码审查。指出代码中的潜在问题,给出改进建议,语气要专业但友好。',
messages: [
{ role: 'user', content: '请审查这段代码:\n```java\npublic void process(List<String> items) {\n for (int i = 0; i < items.size(); i++) {\n System.out.println(items.get(i));\n }\n}\n```' },
],
temperature: 0.2,
});
// 模型回答(节选):
// "你好!这段代码非常简洁直观,能够完成基本的遍历功能。
// 不过,从生产环境的标准和 Java 最佳实践来看,还有几个可以优化和需要注意的细节。
//
// ### 1. 潜在的空指针异常 (NullPointerException)
// 如果调用方传入的 `items` 为 `null`,在执行 `items.size()` 时会直接抛出 `NullPointerException`。
// ..."
对比
| 维度 | AI 客服 | 代码审查 |
|---|---|---|
| System Prompt | "你是智能客服..." | "你是资深 Java 工程师..." |
| Temperature | 0.3(稳定) | 0.2(严谨) |
| 输出风格 | 友好、简洁、有服务用语 | 专业、详细、有代码示例 |
| 目标 | 解决用户问题 | 发现代码问题 |
关键洞察:我们用的是同一个模型(qwen3.7-plus),但通过不同的 system prompt,它变成了完全不同的"人"。
4. System Prompt 的三个要素
一个好的 system prompt 应该包含:
4.1 角色定义
你是 [什么身份]
示例:
- "你是某电商平台的智能客服"
- "你是资深 Java 工程师"
- "你是数据分析师"
- "你是广告文案策划师"
4.2 行为约束
[你应该怎么做]
示例:
- "语气要友好专业,回答要简洁"
- "指出代码中的潜在问题,给出改进建议"
- "回答要基于事实,不要猜测"
- "擅长写出有创意的 slogan"
4.3 边界限制
[你不能做什么 / 遇到什么情况应该怎么做]
示例:
- "遇到无法解决的问题要引导用户联系人工客服"
- "不要自行补充业务规则"
- "如果信息不足,请在 questions 中提出"
5. 生产环境中的 System Prompt
5.1 不要硬编码
在实际项目中,system prompt 通常从配置文件或数据库读取:
typescript
// ❌ 不好:硬编码
const response = await callModel({
system: '你是某电商平台的智能客服...',
messages: [...],
});
// ✅ 好:从配置读取
const config = await loadSystemPrompt('customer-service');
const response = await callModel({
system: config.prompt,
messages: [...],
});
5.2 不同场景不同 Prompt
typescript
// prompts.ts
export const SYSTEM_PROMPTS = {
'customer-service': '你是某电商平台的智能客服...',
'code-review': '你是资深 Java 工程师...',
'data-analyst': '你是数据分析师...',
'copywriter': '你是广告文案策划师...',
};
// 使用
const response = await callModel({
system: SYSTEM_PROMPTS['customer-service'],
messages: [...],
});
5.3 Autix 的做法
在 Autix 项目中,system prompt 的概念被抽象成了 ImageModelCapability(模型能力声明):
typescript
// Autix 的 capabilities.ts
export const IMAGE_MODEL_CAPABILITIES: Record<ImageModelKind, ImageModelCapability> = {
'gpt-image': {
sizes: ['1024x1024', '1792x1024'],
qualities: ['low', 'medium', 'high'],
maxCount: 1,
supportsNegativePrompt: 'prompt-injected',
showAdvancedSliders: false,
},
// ...
};
区别:
- 我们的例子:system prompt 是自然语言("你是客服...")
- Autix 的做法:system prompt 是结构化数据(能力表)
为什么? 因为 Autix 是图像生成场景,需要精确控制模型"能做什么、不能做什么",自然语言不够精确。
6. 测试用例
我们的测试用例覆盖了三种场景:
用例 1.1:AI 客服
typescript
it('场景 1.1:AI 客服 ------ system prompt 定义服务角色', async () => {
const response = await callModel({
system: '你是某电商平台的智能客服,语气要友好专业,回答要简洁,遇到无法解决的问题要引导用户联系人工客服。',
messages: [
{ role: 'user', content: '我买的商品什么时候能发货?' },
],
temperature: 0.3,
});
expect(response.content).toBeDefined();
expect(response.content.length).toBeGreaterThan(0);
// 博客说明点:
// - 观察模型是否使用了客服语气(如"亲"、"您好"等)
// - 观察模型是否遵循了"简洁"的约束
// - 对比:如果不加 system prompt,模型的回答会是什么风格?
}, 60000);
用例 1.2:代码审查
typescript
it('场景 1.2:代码审查 ------ system prompt 定义技术角色', async () => {
const response = await callModel({
system: '你是资深 Java 工程师,负责代码审查。指出代码中的潜在问题,给出改进建议,语气要专业但友好。',
messages: [
{ role: 'user', content: '请审查这段代码:\n```java\npublic void process(List<String> items) {\n for (int i = 0; i < items.size(); i++) {\n System.out.println(items.get(i));\n }\n}\n```' },
],
temperature: 0.2,
});
expect(response.content).toBeDefined();
expect(response.content.length).toBeGreaterThan(0);
// 博客说明点:
// - 对比场景 1.1:同样的模型,不同的 system prompt,完全不同的输出风格
// - 这就是"模型调用不是智能体开发之前的准备动作,而是智能体开发本身的起点"
}, 60000);
用例 1.3:无 System Prompt
typescript
it('场景 1.3:无 system prompt ------ 模型使用默认行为', async () => {
const response = await callModel({
messages: [
{ role: 'user', content: '把"Hello World"翻译成中文' },
],
});
expect(response.content).toBeDefined();
expect(response.content).toContain('你好');
// 博客说明点:
// - 简单任务可以省略 system prompt
// - 但复杂任务(客服、分析、创作)必须有 system prompt 约束
}, 60000);
7. 运行测试
bash
# 只运行知识点 1 的测试
npm test -- -t "知识点 1"
# 运行单个用例
npm test -- -t "场景 1.1"
8. 关键知识点总结
| 知识点 | 说明 |
|---|---|
| System Prompt 是什么 | AI 的"岗位说明书",定义角色、行为、边界 |
| 为什么需要 System Prompt | 让通用模型变成专业化的"人" |
| System Prompt 三要素 | 角色定义 + 行为约束 + 边界限制 |
| 生产环境怎么做 | 从配置/数据库读取,不要硬编码 |
| Autix 的做法 | 用结构化数据(能力表)替代自然语言 |
9. 与 Java 的类比
如果把 AI 模型比作 Java 的 interface:
java
// AI 模型是一个通用接口
public interface AIModel {
String chat(String message);
}
// System Prompt 是具体的实现类
public class CustomerServiceAI implements AIModel {
private String systemPrompt = "你是智能客服...";
@Override
public String chat(String message) {
// 用 system prompt 约束输出
}
}
public class CodeReviewAI implements AIModel {
private String systemPrompt = "你是资深 Java 工程师...";
@Override
public String chat(String message) {
// 用 system prompt 约束输出
}
}
区别:
- Java:需要写多个实现类
- TypeScript + AI:只需要改 system prompt 字符串
这就是 AI 的灵活性:同一个模型,不同的 prompt = 不同的能力。
下一篇预告
第一章 1.4:Temperature 控制输出稳定性
下一篇我们会学习 Temperature 如何控制输出的"创造性"。你会看到:
- 为什么客服场景用
temperature=0.3,创意文案用temperature=1.2 ??和||的经典区别(这是 TypeScript 的常见陷阱)- 如何写"防回归测试"
系列文章导航
- 上一篇:第一章 1.1-1.2:基础模型调用与 TypeScript 入门(./01-1.1-1.2 基础模型调用与 TypeScript 入门.md)
- 下一篇:第一章 1.4:Temperature 控制输出稳定性(./03-1.4-Temperature 控制输出稳定性.md)
- 回到索引 :第一章博客索引