ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Agent开发分水岭:System Prompt与参数调优的实战方法论

2026/9/12 3:20:36 拓冰建站 浏览量
Agent开发分水岭:System Prompt与参数调优的实战方法论 1. 内容整体设计与思路拆解为什么“旋钮”才是 Agent 的分水岭做 Agent 开发这段时间我最大的体感是模型本身的能力差距远没有你想象中那么大真正的分水岭在 system prompt 和核心参数的组合拳上。同样一个底层模型有人跑出来的 Agent 像没睡醒的实习生答非所问、频繁卡壳有人跑出来的 Agent 像跟了你三年的老搭档指令清晰、边界分明、输出稳定。区别不在模型在你怎么“调”它。这就像同一台收音机有人能调出清晰的频道有人只听到滋滋的电流声——旋钮的位置不一样。这个系列到第三篇我们把焦点从“怎么搭一个 Agent 的骨架”转到“怎么让 Agent 真正听懂人话、干对事”。具体来说就是解决三个问题system prompt 到底该怎么写才能让模型精准执行temperature、top_p、max_tokens 这些参数到底在背后干了什么怎么组合调优才能让我这个 Agent 在真实场景下稳定输出我默认读者已经具备基础的 Python 能力和对 LLM API 的基本了解至少自己跑通过一次简单的对话补全。如果你是从零开始建议先把前两篇关于 Agent 整体架构和工具调用的内容过一遍再回来这篇是建立在“你手上已经有一个能跑的 Agent”前提上的。这篇我打算用我实际项目中踩过的坑和调过的参来写不整虚的。你看完能带走的最有价值的东西是一张可以直接照抄的 system prompt 模板、一套可复用的参数调优策略以及一份我攒了几个月的“参数失灵”排查清单。2. system prompt 构造的核心方法论让模型第一次就读懂你2.1 角色设定不是“扮家家酒”是给模型划边界很多人写 system prompt 的开头都是“你是一个智能助手”这基本等于没说。模型不像人它不会自动从“助手”两个字里推断出你需要的所有行为规范。你必须用角色设定把一个清晰的“行为边界”画出来。我常用的做法是三层结构身份层、能力层、行为层。身份层告诉模型“你是谁”但更重要的是告诉它“你不是谁”。比如我做一个代码审查 Agent 时不会只写“你是一个代码审查专家”我会写“你是一个有 10 年后端开发经验的资深代码审查员你专注于发现并发安全、内存泄漏和脆弱的事务处理逻辑。你不是代码风格检查工具不需要关注缩进和命名规范。”这样一个定义同时完成了正向引导和反向约束。能力层要写明“你能调用什么工具、不能调用什么工具”。这一步非常关键尤其当你的 Agent 接了多个工具时。我之前做过一个数据分析 Agent一开始没在 system prompt 里限制工具范围结果模型在用户问“现在几点”的时候去调了一次数据库查询工具。不是模型的错是我没告诉它这个问题的边界。行为层是最容易被忽略的它决定了输出风格。你是要 Step-by-step 思考还是要简洁结论优先你是要代码加注释还是不要注释你希望模型在有多个方案时给出对比还是直接给推荐这些都需要显式写清楚。2.2 目标对齐把“用户想要什么”翻译成“模型要做什么”我见过太多 system prompt 写成了用户需求说明书比如“用户需要一个能查询天气的助手”。这句话对模型没有指导意义。真正的目标是模型面对一个输入时应该执行什么样的认知和行为路径。这里有一个很实用的写法叫“指令分解”把目标拆成模型在推理时需要经历的步骤。举个例子我做一个客服工单分类 Agent 时不写“对工单进行分类”而是写先读取工单全文提取用户核心诉求判断诉求属于故障报修、咨询、投诉还是建议若包含多个诉求按紧急程度排序标记为主诉求和次诉求输出 JSON格式为固定模板。这种写法的好处是模型把这个过程当做一个“多步任务”来处理每一步的准确率叠加之后整体效果会明显好于让它一步到位直接给答案。这背后涉及的是模型对复杂指令的拆解能力——你把拆解的动作替它做了它在执行层的稳定性就会高很多。2.3 约束条件的三种表达否定式、条件式、枚举式约束条件是 system prompt 里信息密度最高、却最容易被写得含糊的部分。我从实际测试里总结出三种有效表达方式否定式约束“不要道歉不要解释你的推理过程直接输出结果。”这条对减少废话输出非常有效。条件式约束“如果用户的问题涉及金钱计算你需要输出计算过程其他情况下只输出最终结论。”枚举式约束“你可以使用以下工具search_web、calc、get_stock_price。除此之外的工具调用一律拒绝并提示用户。”建议在一条 prompt 里交替使用这三种方式比单一表达方式的约束效果好很多。有一次我把所有约束都写成否定式结果模型倒是听话不输出废话了但面对边界场景时它不知道该怎么办直接卡住输出空内容。加了条件式约束之后它才学会“在不确定时有理有据地拒绝”。2.4 few-shot 示例少而精别把 prompt 写成文档Few-shot 示例是提升 system prompt 稳定性的最有效手段之一但也最容易走极端。我看到过把 20 组 QA 全塞进 system prompt 的做法token 直接爆掉每次请求的延迟和成本都翻了几倍收益却不明显。我的经验是示例控制在 3 到 5 组覆盖不同难度和边界场景。难度太低的示例模型学不到东西全是难例又会让模型过度紧张遇到简单问题也搞复杂。理想的组合是一个常规情况、一个边界情况、一个容易出错的陷阱场景。以我做的内容分类 Agent 为例few-shot 我放了三条输入“帮我看看我的订单怎么还没到已经超了 3 天了。” 输出“分类售后投诉紧急程度高建议处理方案优先核实物流状态。”输入“你们这洗发水有没有不刺激的” 输出“分类售前咨询紧急程度低建议处理方案推荐温和配方系列。”输入“没事了不用你管了。” 输出“分类对话终止紧急程度无建议处理方案结束会话。”三条示例分别对应了正常请求、需要常识推理的模糊请求和容易被误判为“服务中”的终止请求。模型看到这种示例之后再遇到类似情况输出准确率明显提升。3. 核心参数逐项拆解每个旋钮背后是什么原理3.1 temperature决定 Agent 的“胆量”temperature 是调节模型输出随机性的核心参数。从技术原理说模型每次生成下一个 token 时会计算候选词的概率分布temperature 相当于在这个分布上做一次“重新塑形”值越低概率高的 token 被选中的可能性越大值越高低概率 token 也有机会被选出来。换句话说temperature 控制的是模型“保守还是激进”。做代码生成、JSON 输出、实体识别这类任务时我一般把温度压在 0.1 到 0.3宁可让它像个死板的执行者也不让它自由发挥。做创意文案、头脑风暴、商品命名这类任务我会拉到 0.7 到 0.9让它敢说点不一样的。有一个常见的误解是“temperature 越低越准确”这个说法不完全对。我实测过一个数学推理场景temperature 设成 0 和设成 0.3准确率差异不大但 0 时模型偶尔会在遇到概率极低的 token 时卡顿生成速度反而更慢。所以我现在的习惯是需要严格稳定的任务设 0.1 到 0.2而不是 0。留一点点扰动空间既避免输出完全固化又不会让模型放飞。3.2 top_p配合 temperature 的“筛子”top_p核采样的工作原理是按概率从高到低累加 token直到累加概率达到 p 值只从这个候选集合里采样。它的作用和 temperature 相似但逻辑不同——temperature 是改变概率分布的“形状”top_p 是直接截断候选集。以前我习惯两个参数一起调后来发现其实没必要同时猛调。OpenAI 官方的建议是改其中一个就好另一个保持默认。我自己的习惯是优先动 temperaturetop_p 保持默认值 1.0。只有在 temperature 调来调去都解决不了输出混乱问题时才去动 top_p把它往下压到 0.85 到 0.95 之间。举一个实际例子我之前做一个开放域问答 Agenttemperature 设到 0.8 之后输出多样性是有了但偶尔会在回答里穿插一个完全不相关的短语比如把“美国总统”和“披萨”混在一起说。排查一圈发现是 top_p 太高低概率噪声也进了候选集。把 top_p 从 1.0 降到 0.92 之后这种问题基本消失了同时保持了多样性的优势。3.3 max_tokens 的秘密它不止是“长度限制”max_tokens 这个名字容易让人以为它只是“限制输出长度”但它在 Agent 场景里还有一个更重要的作用防止模型在错误路径上越走越远。举个例子我的 Agent 接了一个网页抓取工具如果网页内容很长模型在解读时容易陷入“继续读、继续总结”的循环。我一度以为是工具逻辑写错了后来发现是 max_tokens 设太大给了它太多“表演空间”。把单轮输出的 max_tokens 收窄之后模型被迫在有限长度内尽快给出结论反而更稳健。设置 max_tokens 时先要估算任务输出的合理长度仅输出 JSON 结果的任务300 到 500 足够需要生成中等长度文案的任务800 到 1200需要长文写作的任务可以单独拉高。有一个技巧是在 system prompt 里提前告知模型“你的输出应控制在 200 字以内”配合 max_tokens 做双保险效果远好于只靠参数硬卡。3.4 frequency_penalty 和 presence_penalty控制重复的物理学家这两个参数在 Agent 场景里被用到的频率不高但当你遇到“模型同一个意思反复说”的问题时它们就是最后的杀手锏。frequency_penalty根据 token 在文本中出现的频率来惩罚它越频繁出现的 token 越容易被抑制数值范围 0 到 2一般设在 0.3 到 0.8。presence_penalty只要 token 出现过就给它一个固定的惩罚不管出现多少次。它鼓励模型引入新话题、新词汇范围同样是 0 到 2。我用这两个参数的场景是“让 Agent 做多方案推荐时不要重复踩同一个套路”。比如让模型推荐三个旅游方案它经常给出三个内容本质上差不多的方案。把 presence_penalty 设到 0.6模型就会倾向从不同角度去想方案避免同质化。而 frequency_penalty 更多用在长文本生成场景比如让 Agent 输出月度总结报告时0.4 左右的值可以明显减少车轱辘话。3.5 参数组合与不同服务商的映射关系不同模型服务商对参数的叫法和默认值差异很大这个坑我踩过不止一次。以下是主流 API 的参数对照参数含义OpenAIAnthropic Claude国产主流服务随机采样程度temperaturetemperaturetemperature核采样top_ptop_ptop_p最大输出长度max_tokensmax_tokensmax_tokens / max_new_tokens频率惩罚frequency_penalty不支持repetition_penalty存在惩罚presence_penalty不支持repetition_penalty对话历史messagesmessages / systemmessages / prompt注意两个特别容易踩坑的点第一Anthropic 的 API 里 system prompt 是独立参数不放在 messages 里如果你按 OpenAI 的习惯把 system 当作一条消息传进去部分版本会直接报错或静默忽略第二很多国产服务的 repetition_penalty 是一个参数控制两个功能它同时影响频率和存在性惩罚调优逻辑和 OpenAI 的分开控制不完全一样不能照搬经验值。4. 实操过程与核心调优实录从崩坏到稳定的完整记录4.1 从“能用”到“好用”的三个迭代层次我要分享的调优方法不是我拍脑袋想出来的是我把一个客服问答 Agent 从能用迭代到好用的全过程。整个调优分三个阶段第一阶段跑通为主。这个阶段不做任何精细调优system prompt 就写三五句话参数全用默认值。目标是验证工具调用链路是通的、模型能理解基本指令。这个阶段可以帮你建立基线别急着做优化。第二阶段结构化 prompt。把 system prompt 从三五句话扩展成角色层、能力层、行为层、约束层、示例层五个模块同时把 temperature 降到 0.3 附近。这个阶段完成后Agent 的行为就“像样”了至少能看出来它是有方向感地在执行任务。第三阶段参数细调。根据具体任务类型微调参数组合这个过程通常要跑几十次到上百次测试而且每次只动一个变量。贪多求快、一次改三个参数再测效果是最容易翻车的做法。4.2 参数调优的“控制变量”策略控制变量是这个环节的命门。我给自己的规矩是一次只改一个旋钮记录效果再动下一个。具体流程如下第一步确定评估指标。我的 Agent 是做客服问答的核心指标是“首次解答满意率”和“工具调用正确率”。你做一个摘要 Agent核心指标就是“摘要关键点召回率”。先定义好你怎么判断“变好了”再去调参。第二步固定 baseline。在默认参数下跑 10 到 20 个典型测试用例记录输出结果。这些输出就是你的对照组。第三步单参数扫描。比如要调 temperature在 0.1、0.3、0.5、0.7 四档各跑同一批测试用例记录输出差异。你会发现不同档位的失败模式也不一样低温是机械重复高温是偏离主题。第四步组合微调。单参数确定了大致区间后再去做组合测试。比如 temperature 在 0.2 到 0.3、top_p 在 0.9 到 0.95 的组合下可能会有比单独调每个参数更好的表现。4.3 一个完整的 system prompt 模板可以直接抄直接给一个我目前在生产环境验证过的模板这是客服质检 Agent 的简化版本你可以按自己的场景改。# 角色 你是一个客服质检员负责检查客服对话记录是否存在违规、态度问题和服务流程缺失。 # 能力 你可以调用 analyze_text 工具对文本进行情感分析调用 search_policy 工具查询客服规范文档。 禁止使用其他工具。 # 任务 对输入的对话记录执行以下步骤 1. 通读完整对话提取客服和用户的交替发言结构 2. 对照质检规范逐项检查是否使用违禁词、是否回避责任、是否在适当节点提供解决方案 3. 如果发现违规项输出违规类型和具体证据片段 4. 输出 JSON 格式的质检结果字段包括is_violation、violation_type、evidence、suggestion。 # 约束 - 不要输出思考过程只输出最终 JSON。 - 如果对话记录不完整在 suggestion 字段中提示需要补充的信息。 - 判断时只依据对话内容本身不要做无关推断。 # 示例 输入客服您好请问有什么可以帮您 用户我上周买的东西一直没发货。 客服这个不归我们管你去找仓库。 输出{is_violation: true, violation_type: 态度粗暴、回避责任, evidence: 这个不归我们管你去找仓库, suggestion: 应引导用户并提供物流查询渠道}这个模板在生产环境的效果比早期版本好用得多。关键在于三个点一是任务步骤拆得足够细模型知道按顺序干二是约束条件具体到“不要输出思考过程”这种细节级别三是示例起到了“标准答案”的锚定作用。4.4 不同任务类型下的参数经验值参考根据我的实测不同类型任务有一个初始参数区间可以直接作为起点再微调任务类型temperaturetop_pmax_tokens关键要点代码生成/补全0.1 - 0.21.0800 - 1500宁保守勿创造JSON/结构化输出0.0 - 0.21.0300 - 600配合 prompt 里的格式约束客服问答0.3 - 0.50.95300 - 800平衡礼貌与效率创意文案0.7 - 0.90.92800 - 1200给模型一点“任性”空间摘要/提炼0.3 - 0.50.9300 - 600防止过度概括遗漏细节多步推理0.1 - 0.21.0800以上温度太高会跳步再次提醒这个表是起点不是终点。你换了模型、换了任务描述可能都需要重新扫描。5. 常见问题与参数失灵排查踩坑得来的速查表5.1 怀疑模型“不听话”时先查 prompt 再看参数这个判断顺序真的要说三遍因为太多人一遇到问题就去调参数结果越调越糟。实际上70% 以上的 Agent 输出异常问题根源在 prompt 不在参数。我总结了一个判断逻辑。如果模型输出的是“错误但完整的内容”先排查 prompt 是否有歧义、约束是否到位如果模型输出的是“正确但混乱的内容”先排查参数是否过激。举个例子你让模型输出 JSON它给你传了一堆 Markdown 反引号和解释文字——这大概率是 prompt 里没说明“直接输出 JSON 不要加任何格式标记”跟 temperature 设多少关系不大。5.2 temperature 失灵可能是上下文太长把“随机性”磨平了这个坑比较隐蔽。有段时间我发现一个 Agent 的 temperature 从 0.2 调到 0.9输出风格竟然没明显变化一开始以为 API 没生效。后来排查发现是因为 system prompt 加上 few-shot 示例和用户消息拼接之后上下文总长度已经超过了一万 token。当上下文足够长时模型生成时会高度依赖上下文信息参数对输出的影响会被大幅削弱。这就像一个人在面对一沓厚厚的参考资料时就算你再让他“放开想象力”他也很难跳出资料的范围。解决办法有两个精简 system prompt 和示例长度或者改用支持更长上下文的模型版本让“有效信息区”之外的参数调节空间更大。5.3 max_tokens 不够用的典型表现输出被“腰斩”Agent 输出被截断是一个高频问题表现就是结果结尾突然中断甚至连 JSON 的右括号都没输出。这个问题的直接原因就是 max_tokens 设小了但背后还有一个容易被忽略的因素模型的输出 token 统计方式和你想象的不一样。中文字符的 token 消耗比英文高得多一段 500 字的回复可能要吃掉 800 到 1000 个 token而不是 500 个。如果你习惯用英文字符数来估算 max_tokens给中文 Agent 设置长度时会估算不足。我的经验是中文输出场景下max_tokens 设置为期望中文字数的 1.5 到 2 倍比较稳妥。5.4 输出格式时好时坏presence_penalty 的副作用这是一个冷门但真实存在的坑。之前我为了让长文本输出不那么重复把 presence_penalty 调到了 1.2结果发现同一个 Agent 在输出 JSON 时字段顺序开始不稳定甚至偶尔会把字段名改了。原因就是 presence_penalty 在抑制重复的同时也在抑制模型“固守同一个输出模式”JSON 的键名这种低频 token 也会被连带影响。如果你同时设置了 presence_penalty 过高的值和一个严格格式的 system prompt模型可能会在两者之间“打架”。解决方案有两个高 penalty 时用更严格的 few-shot 示例锚定输出格式或者用最大字段限制和工具调用约束来补充压住格式。5.5 常见问题速查表现象可能原因优先排查方向输出与指令无关的废话system prompt 没写“不要解释过程”加否定式约束JSON 格式破损max_tokens 不够 / 格式提示不明确检查截断 加严格格式示例同话题重复表述presence_penalty 过低提升到 0.5 以上多步骤任务跳步temperature 过高降到 0.2 以下输出风格不受参数控制上下文过长 / prompt 过分详细精简 prompt 再测参数工具调用频繁出错能力层边界不清晰明确“禁止使用其他工具”输出模板化、僵硬temperature 过低且示例单一拉高温度 增加示例多样性5.6 我的独家调试技巧日志记录 参数快照最后一个想分享的实战技巧是调参过程一定要有日志记录。我早期调参时经常凭感觉改一个参数跑两轮测试觉得不对又改回去然后完全忘记之前的配置是什么样的导致同一个问题反复出现。现在我用的方法是每次调参前导出一个“参数快照”记录当前 system prompt 全文、所有参数值、使用的测试用例版本和模型版本。调完跑测试后再导出一份结果快照。这样横向对比时一眼就能看出是哪次改动导致的效果变化。这个习惯看起来笨但在 Agent 开发里真的能救命。另外我强烈建议把测试用例沉淀成一份固定回归集。每次改动 prompt 或参数之后跑一遍回归测试确认没有把之前调好的能力调坏。没有回归测试的 Agent 调优就像走在悬崖边不看路早晚要摔。我个人现在的习惯是每次调参只动一个变量跑完 5 到 10 个固定测试用例再加 3 到 5 个随机边界用例记录结果再决策。这套流程慢一点但每一步都心里有数。说到底Agent 的稳定性不是靠一次“神仙调参”的运气而是靠一套可重复、可验证的工程方法堆出来的。