System Prompt vs User Prompt:一个管「你是谁」,一个管「你要什么」

发布时间:2026/6/1 12:14:32

System Prompt vs User Prompt:一个管「你是谁」,一个管「你要什么」 一只用 AI Agent 搭副业产线的程序员上篇我们说了 Prompt 要当代码写。但代码需要架构。这篇文章给你 Prompt 架构的第一层System Prompt 和 User Prompt 的分工。很多人混在一起用结果就是 Prompt 一长就失控。别混。这两个角色天然不同。先搞清楚AI 收到的不是一段话是两个人每次调用 API你传的Messages数组里有一个role字段。可以填三种Role谁说的干什么的system你开发者定义 AI 的行为规则、角色、边界user用户具体的任务、问题、输入assistantAI历史回复多轮对话用这三者的关系像什么System Prompt 员工手册入职第一天发的管所有行为 User Prompt 任务单每天变化的管这一个任务 Assistant 工作日志之前干了啥管上下文连续性一个反例混在一起会怎样很多人这样写 Prompt你是一个优秀的 Go 后端开发有 10 年经验擅长写高性能代码。 你的回答要简洁、准确、代码完整可运行。不要写废话。 现在帮我写一个 LRU 缓存。 哦对了用泛型。要有测试。还有……这有什么问题角色定义和具体任务搅在一起。每次新任务你都要把角色定义再说一遍。想复用角色设定复制粘贴。想换一个角色全删了重写。更糟的是——如果你在一个循环 Agent 里用这种 Prompt每一轮都要重复发送角色描述。10 轮对话角色重复了 10 次全是钱的流失。正确的分层// System Prompt —— 一次定义永久复用systemPrompt:你是 Go 后端开发专家。 行为规则 1. 代码完整可编译不省略 import 和 package 声明 2. 所有公开函数包含 godoc 注释 3. 不确定的 API 明确说不确定不编造 4. 不要解释代码为什么这样写除非被问到 输出约束 - 代码块使用 go标记-错误处理不要用panic用 fmt.Errorf 包装-时间相关的逻辑使用 time.Time不要用字符串// User Prompt —— 每次不同只管任务userPrompt:用 Go 泛型实现一个线程安全的 LRU 缓存。 要求 - 支持 Get、Put、Len 方法 - 容量满了淘汰最久未使用的 - 并发安全这样分开后System Prompt 你可以复用 100 次、1000 次。User Prompt 只管这一次的任务。用 JSON 配置驱动 Prompt 管理更进一步——把 System Prompt 从代码里抽出来用配置文件管理{roles:{go-backend-dev:{name:Go 后端开发专家,system:你是 Go 后端开发专家。代码完整可编译不确定的 API 明确说不知道。输出简洁精准。,temperature:0.1,max_tokens:500},code-reviewer:{name:代码审查员,system:你是代码审查员。只找问题不表扬。按严重程度排序高危 中危 低危。每个问题标注行号。,temperature:0.0,max_tokens:800},doc-writer:{name:技术文档写手,system:你是技术文档写手。写中文 godoc 风格注释。准确、简洁、不说废话。,temperature:0.3,max_tokens:1000},rubber-duck:{name:小黄鸭调试助手,system:你是小黄鸭调试助手。用户会向你解释代码逻辑。你的任务是通过提问帮他发现思维盲区。不要直接给答案。用苏格拉底式提问。,temperature:0.7,max_tokens:300}}}然后在 Go 代码里加载packagemainimport(encoding/jsonfmtos)typeRoleConfigstruct{Namestringjson:nameSystemstringjson:systemTemperaturefloat64json:temperatureMaxTokensintjson:max_tokens}typeConfigstruct{Rolesmap[string]RoleConfigjson:roles}typePromptManagerstruct{config*Config}funcNewPromptManager(configPathstring)(*PromptManager,error){data,err:os.ReadFile(configPath)iferr!nil{returnnil,err}varcfg Config json.Unmarshal(data,cfg)returnPromptManager{config:cfg},nil}func(pm*PromptManager)BuildMessages(roleKeystring,userPromptstring)([]Message,float64,int,error){role,ok:pm.config.Roles[roleKey]if!ok{returnnil,0,0,fmt.Errorf(未知角色: %s,roleKey)}messages:[]Message{{Role:system,Content:role.System},{Role:user,Content:userPrompt},}returnmessages,role.Temperature,role.MaxTokens,nil}funcmain(){pm,_:NewPromptManager(roles.json)// 换角色只需要换一个 keymessages,temp,maxTok,_:pm.BuildMessages(go-backend-dev,写一个 WebSocket 心跳检测函数)result:callLLM(messages,temp,maxTok)fmt.Println(result)// 同一个代码库不同的角色messages2,temp2,maxTok2,_:pm.BuildMessages(code-reviewer,result)// 把刚生成的代码丢给审查员review:callLLM(messages2,temp2,maxTok2)fmt.Println(review)}切换角色现在是一行代码的事。团队里不同的人可以复用同一个角色库。System Prompt 写什么的 4 层模型层内容示例第 1 层角色定义AI 是什么身份「你是 Go 后端开发专家」第 2 层行为规则怎么做事「代码完整可编译不确定的说不知道」第 3 层输出约束输出什么格式「用 go 代码块不输出解释」第 4 层禁止事项不要做什么「不要编造 API不要用 panic」第 1 层是必须的第 2-4 层根据任务复杂度选配。简单任务可能只需要第 1 层 第 3 层。一个真实的坑System Prompt 太长我一开始给 Agent 写的 System Prompt 有 3000 字规定了各种场景下的行为。结果呢AI 经常「忘记」后面的规则。因为 System Prompt 太长离得远的规则权重降低了。后来我优化成 200 字以内只保留最重要的 3-4 条规则。准确率反而提高了。System Prompt 不是越长越好。是越精越好。User Prompt 怎么写三段式模板[任务] 用 Go 实现一个带过期时间的本地缓存。 [输入] 无 [输出] 完整可编译的 Go 代码包含 - Set(key, value, ttl) 方法 - Get(key) (value, bool) 方法 - 过期自动清理机制三段式任务 输入 输出。简洁明确不给 AI 发挥空间。总结一张表分清 System 和 UserSystem PromptUser Prompt谁写你开发者你或最终用户频率写一次复用多次每次任务不同内容角色、规则、约束具体任务、输入数据维护方式JSON 配置文件代码里拼接或模板长度尽量短200 字内根据任务复杂度类比员工手册任务单下一篇我们搞一个实验——同一个任务用 Few-shot给示例和 Zero-shot不给示例各跑 50 次统计准确率差异。告诉你什么时候该给示例什么时候给了反而坏事。关注我别错过。 一只用 AI Agent 搭副业产线的程序员全平台同名虾哥不加班需要定制 AI 工具来聊聊 → lob_ai源码GitHub - lobster-bujiaban

相关新闻