☰
提示词工程实战:从大模型交互到AI Agent开发
2026/10/2 5:16:58 网站建设 项目流程

这篇博文的标题延续了系列化的学习记录风格。为了让其真正有价值,我选择将重点放在“为什么提示词在大模型应用中如此关键”以及“如何从提示词一步步走向真正的AI Agent”这两个核心问题上,结合实操案例展开。

1. 提示词不是“说话”,而是“编程”

刚开始接触大模型时,我犯过一个特别蠢的错误:把提示词当成跟一个聪明助理聊天,说一句“帮我看看这个数据”,然后等着它自己领悟。结果它确实领悟了——按它自己的方式,跑得偏到姥姥家。后来我才明白一个关键认知:提示词的本质不是“对话”,而是“程序”。我们和大模型之间的每一次交互,本质上是在一段极其有限的空间里,写下了一段即时执行的逻辑代码,只不过这门语言的编译器是数十亿参数的神经网络。

我所指的“程序”,不是说提示词要写成代码风格,而是说它的工作方式跟代码高度相似:你给定了角色、上下文、约束条件和输出格式,它就按照这套逻辑执行。没有定义清楚变量,它就会自己声明一个隐式变量;没有设置边界条件,它就会进入死循环式地胡编乱造;没有指定输出Schema,它就按训练数据里的概率分布给你来一段“最像样”的文本。这就像你给一个程序员下需求:“给我写个东西”,他写出来的任何结果你都不能说错,因为需求根本没说清。

在AI Agent的场景里,这条法则被放大了十倍。Agent不是一次性的问答,而是多轮自我驱动地完成任务。它需要在大模型的每次推理之间插入工具调用、读取返回值、再继续推理。这意味着我们不能只写一句漂亮的提示词,而要设计一套提示词体系:系统级指令、任务级指令、工具调用说明、输出格式约束、异常兜底逻辑,每一层都有它的职责。

许多刚进入AI Agent开发领域的朋友问我,为什么照着开源项目的提示词抄了一遍,效果还是不稳定?我通常反问一句:你抄的是“结果”,还是“逻辑”?举个例子,很多开源Agent会在系统提示词里写“You are a helpful assistant”,你把这个抄到自己项目里,它就只能是个“helpful”,而如果原项目写的是“You are a code reviewer with deep expertise in Python security”,你抄成“You are a helpful assistant”,能力直接掉了两个档位。提示词的价值在于精确定义行为边界,而不是提供一个泛泛而谈的“好人”设定。

所以我觉得,学Prompt Engineering的第一课,不是学什么模板、什么框架,而是接受一个心理模型:你是在用自然语言写程序,大模型是那个特别聪明但有点过于自由的编译器。你的每句话都要像写代码一样精打细算——定义清楚变量、标注清楚分支、收敛清楚输出。这样,后面所有高级技巧都只是写代码时用到的不同设计模式而已。

把这个想法想通之后,你再看那些所谓的“提示词技巧”“提示词模板”,视角完全不一样了。你不是在背公式,而是在挑选适合你这段“程序”的架构方案。接下来我详细拆解一下,在Agent开发里,一套合格的提示词体系到底长什么样。

2. 从“说人话”到“写规则”:提示词的核心三要素

很多教程喜欢把提示词拆成“角色设定 + 任务描述 + 输出格式”,这个框架大方向没错,但太粗了。用在简单的文案生成上可以,用在Agent开发上远远不够。我自己实践下来,一套真正能稳定工作的提示词,至少要覆盖这三个核心维度:角色与立场、任务与步骤、边界与约束。少了任何一个,Agent的稳定性都会大打折扣,尤其是在多轮工具调用场景。

2.1 角色与立场:让模型带上“职业滤镜”

同样是分析一段代码,让模型以“资深Python安全审计员”的身份分析,和以“刚入门的Python学习者”的身份分析,输出的内容天差地别。前者会主动关注注入风险、资源泄漏、并发问题;后者会讲“这段代码思路清晰,注释到位”。大模型的知识库里什么都有,角色描述本质上是一个“过滤器”,决定了它在执行任务时优先激活哪部分知识、采用哪套评价体系。

在Agent开发中,角色设定更要精确到可操作的程度。不要写“你是一个数据分析师”,而要写“你是一个数据分析师,擅长Python pandas和SQL,你的分析风格是严谨且注重可复现性,任何结论必须给出计算过程”。这等于在提示词里给模型的“职业滤镜”额外加了一层“行事风格”的镀膜。

我见过一个很典型的失败案例:某同学做一个股票K线分析Agent,系统提示词里写的是“你是一个量化交易专家”,结果模型每次分析完都建议“长期持有,逢低买入”。听起来没错,但对一个意图分析K线形态、识别买卖点的Agent来说,这种回答全是废话。后来把角色改成“你是股票技术分析助手,你的任务是识别图表中的形态特征,不提供任何投资建议,只输出观察结果”,输出质量立刻改善。原因很简单:角色设定变了,它激活的知识和评判体系就变了。

2.2 任务与步骤:别让模型“自由发挥”

凡是涉及多步骤任务,我就强烈建议在提示词里显式给出步骤约束。大模型本质上是在做“下一词预测”,如果你不规定它“第一步做什么、第二步做什么”,它就会按照训练数据里最常见的路径走——而这个常见路径往往不是你想要的。

我自己写Agent的系统提示词时,习惯用一种“行动清单”的写法。比如我让Agent做一个行业调研报告,我不会只说“帮我调研新能源车的市场情况”,我会写:

  1. 明确调研范围和目标问题,若目标不清晰,先向用户确认。
  2. 按照目标拆解信息需求,确定需要检索的关键词和信源类型。
  3. 对检索到的信息进行分类整理,标注来源和发布机构。
  4. 输出结构化报告,包含核心结论、关键数据、风险提示。

注意,我并没有把它写成“你必须、你应该”的死命令,而是给出逻辑路径。大模型对“路径感”的响应非常敏感,一旦你把步骤显式化,它就不会跳过一环直接跳到结论。这个技巧在Agent开发中的价值尤其大,因为Agent经常要在多轮里自主决定下一步动作,你通过步骤约束其实是在给它的“决策路径”加护栏。

2.3 边界与约束:明确什么能做、什么不能做

这是我踩过最深的坑。最初我设计Agent时只写了“你能做什么”,没写“你不能做什么”,结果Agent在搜索不到信息时,开始凭空编造数据,而且语气极其笃定,害得我差点把错误数据直接发出去。

后来我在所有Agent的系统提示词里都加了这么一段:

  • 如果你不确定某个信息的真实性,请明确说“不确定”,不要猜测。
  • 不要编造任何数据、引用或来源。
  • 当信息不足以支撑结论时,输出“信息不足,需要补充XX数据”。
  • 如果用户请求涉及违法、危险或超出能力范围的内容,礼貌拒绝并说明原因。

这个“负向约束”看着简单,但在实际运行中能减少一大半的跑偏问题。原因在于,大模型的默认行为是“迎合用户”,你只给正向指令时,它倾向于在不确定时给你编一个看起来合理的答案。但你把“编造”定义成不可接受的行为,它的概率分布就会明显向“承认不知道”倾斜。

我后来经常用一个比喻来跟团队新人解释:正向指令是告诉模型“怎么干活”,负向约束是告诉模型“哪些红线不能碰”。一个成熟的员工不会因为老板没说“别偷懒”就偷懒,但一个刚毕业且特别想表现的新人,真的可能因为你没说“别编数据”而编数据。大模型的训练方式和“特别想表现的职场新人”非常像。

3. 提示工程进阶:让大模型听懂Agent的“工具语言”

如果你的AI Agent只用大模型本身的能力,那你压根不需要Agent,一个对话框就够了。Agent与普通聊天的本质区别在于:它需要调用外部工具、解析返回结果、做出下一步决策。这就是提示工程从“单人对话”升级为“多角色协作”的关键转折点。

在最常使用的LangChain或LangGraph框架里,Agent在决定调用某个工具时,大模型要做的就是“生成一段符合特定结构的文本”——这段文本通常对应一个函数名和一组参数。大模型本身不执行函数,它只负责“决定调用哪个函数、传入什么参数”。这就引出一个非常关键的问题:你如何用提示词让大模型准确理解每个工具的用途,并正确填写参数?

我推荐的做法是,在工具描述(也就是函数的docstring)里,用“功能说明 + 参数说明 + 边界说明”的结构来写。举个例子,假设你要让Agent调用一个获取股票行情的工具:

get_stock_price(symbol: str, date: str) - 功能:获取指定股票在指定日期的收盘价、开盘价、最高价、最低价。 - 参数symbol:股票代码,必须使用标准代码,如AAPL或600519,不要使用公司名称。 - 参数date:日期,格式为YYYY-MM-DD,必须是过去日期或今天,不接受未来日期。 - 返回值:JSON对象,包含open、close、high、low、volume字段。 - 边界:本工具只返回真实存在的行情数据,不要虚构数值。

这段描述看起来只是给“人”看的说明书,但它实际上是在给大模型建立一套“工具使用心智模型”。大模型读了这段描述之后,会知道:遇到公司名称时要先转换成股票代码,日期格式严格、不能用自然语言,输出必须按JSON解析。这些细节如果不写到工具描述里,大模型就会自作聪明,把“苹果公司”当参数传进去,把“上周三”当日期传进去,解析必然失败。

另一个技巧是“分步工具调用”。在某个Agent任务里,我希望模型先调用A工具获取原始数据,然后调用B工具做二次处理,最后再自己总结输出。单靠随口指令,模型经常跳步。解决办法是在提示词里明确写出“工具调用顺序”,并强调“只有在A工具返回值确认无误后,才允许调用B工具”。这其实是在提示词层面模拟了编程中的流程控制。

我还想特别提一句“ReAct模式”的提示词写法。ReAct(Reasoning + Acting)是目前大多数Agent框架底层的推理范式,它的思路是让大模型交替输出Thought(推理过程)、Action(工具调用)、Observation(观察结果)。如果你不走框架,自己用提示词来模拟,可以这样写:

请按照以下格式循环处理: Thought: 分析当前状态,说明下一步需要做什么,为什么。 Action: 调用工具,格式为 工具名(参数) Observation: 记录工具返回的结果 ...(重复直到任务完成) 最终答案:给出最终答复

第一次看到这段提示词的时候会有一种感觉:这不就是在教大模型“写伪代码”吗?你说得对。所谓Agent,本质就是在一个推理循环里反复执行“思考-行动-观察”的过程。提示词的作用,就是把这个循环的形状定义清楚,让大模型不至于在一个循环里绕不出来,也不至于在只有一半信息时就草率输出结论。

这里顺带提醒一句:ReAct模式下务必设置“最大循环次数”。我在开发中遇到过Agent陷入无限循环,反复调用同一个工具却不推进任务的尴尬局面。光靠提示词说“不要重复调用相同工具”往往不够,更好的办法是在代码层面增加循环上限。提示词能约束模型的行为倾向,但你不能指望它像编程语言一样严格——所以永远要在框架层留兜底逻辑。

4. 实战演练:从零到一搭一个K线分析Agent

听完前面的理论,如果没上手实操,很可能只是“脑子会了”。我下面用一个完整的实战案例——做一个简单的K线形态分析Agent——来展示提示词工程到底怎么落地。这个案例选在“股票K线分析”场景,是因为它既贴合很多量化爱好者的需求,又非常适合展示“工具调用 + 多步推理 + 结构化输出”这三件事。

不过先声明一下:这个Agent只做形态分析,不提供买卖建议,目的纯粹是展示提示词工程的结构,不是推荐大家用它做交易决策。我见过有人尝试用这类Agent直接做期货、股票的自动交易,风险极高,不建议盲从。市场预测本身包含大量不确定性,任何声称能稳定预测行情的大模型方案都值得警惕。

4.1 系统提示词:Agent的“岗位说明书”

这个Agent的系统提示词,我采用的是前面提到的三要素结构。完整的提示词如下(我稍微做了简化,去掉了一些项目专属的配置):

你是一个股票K线形态分析助手,擅长识别常见技术形态(如头肩顶、双底、旗形、三角形、锤子线、十字星等)。 你的工作模式如下: 1. 当用户提供股票代码时,先调用 get_stock_history 获取最近一段时间的日K数据。 2. 根据K线数据识别出现的形态,描述每个形态的特征、出现位置、时间跨度。 3. 分析当前形态组合所反映的多空力量对比。 4. 输出结构化报告,包含:形态列表、关键K线特征、支撑压力位参考、不确定因素。 严格遵守以下规则: - 只根据真实K线数据进行分析,禁止编造任何价格、日期或形态。 - 不提供买卖建议,不预测未来价格走势,只描述当前图表特征。 - 如果数据不足或形态不清晰,明确说明“无法判断”,不要强行给出结论。 - 使用中文输出,专业术语可保留英文。

注意到没有?这个提示词里同时包含了角色定义、任务步骤、行为边界,还协调了工具调用逻辑。这里面最核心的设计意图是:让Agent“只描述、不预测”,因为技术形态分析本身的可靠率并没有高到可以作为交易信号的级别,而大模型在预测类任务上的幻觉率又偏高。通过把输出范围收敛到“当前图表特征”,既能保证内容的真实可靠性,也能让分析聚焦在形态识别这个相对有规律的任务上。

4.2 工具描述:Agent的“操作手册”

工具描述我用的是前面介绍过的“功能说明 + 参数说明 + 边界说明”结构。这里给出工具定义,方便大家对照参考:

def get_stock_history(symbol: str, days: int = 60): """ 获取指定股票最近N天的日K线数据。 参数symbol: 股票代码,必须使用标准代码(如AAPL、600519),不要使用公司名称。 参数days: 获取数据的天数,默认为60,最大不超过250。 返回值: JSON数组,每个元素包含 date, open, close, high, low, volume 字段。 边界: 仅返回真实历史数据,不进行任何预测性计算。 """ # 这里对接你的数据源,比如tushare、akshare、yfinance或本地数据库 pass

这里我想特别强调的是参数描述里的“必须使用标准代码,不要使用公司名称”这几句。实际跑下来你会发现,如果工具描述里不提这一点,Agent经常会把用户说的“苹果公司股票”原封不动传给get_stock_history,代码根本跑不通。加了边界说明之后,Agent会先想办法把公司名转换成代码,具体转换它可能通过另一段知识来完成,也可能直接问用户要代码。不管走哪条路,都比传一个“苹果公司”进去强一万倍。

4.3 完整运行链路与提示词的配合

当用户输入“帮我看看600519最近一个月的K线形态”时,Agent的执行链路大致是这样的:

  • 第一轮推理:从上下文里提取出股票代码600519和查询周期“最近一个月”,生成调用get_stock_history(symbol="600519", days=30)的动作。
  • 工具返回:一组包含日期、开高低收、成交量的JSON数据。
  • 第二轮推理:模型读取数据,识别形态。它会在“思考”过程中结合前期学到的K线形态知识,逐根K线比对,标注可能的形态。
  • 第三轮推理:整理分析结论,按系统提示词中规定的报告结构输出。

你会发现,在这个过程中,提示词并没有直接参与每一步的动作,但它像一条隐形的轨道,约束着模型在每个环节的行为表现。代码负责真正调用函数和传递数据,提示词负责让模型“在正确的时机做正确的决策”。提示词和代码二者是合伙关系,而不是谁替代谁。

关于“鹈鹕骑自行车”这个网络上流传很广的梗,我也多说一句:很多人用它来测试大模型的应对比能力,本质上是在考察模型对“不合理指令”的处理方式。放在Agent场景下,这个测试其实有很实际的意义——你的Agent是否会无脑执行所有指令?当用户提出的请求与预设规则冲突时,它能不能按照规则而不是盲目迎合?这提醒我们,在设计Agent提示词时,必须要考虑“规则冲突处理”的优先级问题。像“鹈鹕骑自行车”这种一看就很荒谬的请求,如果你的Agent真的去搜索“鹈鹕骑自行车的教程”,说明你的系统提示词里缺少一个关键约束——“只执行与任务目标相关的合理操作”。这个小点平时容易被忽略,但在生产环境里它就是区分“玩具Agent”和“可用Agent”的分水岭。

5. 常见问题与排查技巧实录

提示词工程的一大特点就是“效果玄学”:同一个提示词,换一个模型、换一个版本、甚至换一天运行,结果可能完全不同。做Agent开发这些年,我整理了几个高频问题和对应的排查思路,分享在这里,希望能帮大家少走一些弯路。

5.1 Agent完全忽视提示词中的规则

现象:系统提示词里明确写了“不要编造数据”,但Agent还是编了;写了“先调用工具A再调用工具B”,但它直接跳过了工具A。

排查思路:先确认你的提示词是否真的被“传”到了模型那里。在LangChain这类框架里,很容易出现系统提示词被对话历史顶掉,或者你在构造消息时把系统提示词和用户消息混在了一起。最稳妥的排查方法是直接打印发送给模型的完整消息列表,检查system消息是否在正确的位置、是否有被截断。

如果确认提示词已送达且完整,再看第二个可能:提示词本身写得“太弱”。我们在前面提到过,模型的默认行为是迎合用户,只有在明确被告知“这条规则优先于用户的即时请求”时,它才可能把规则放在前面。可以尝试加强规则的表达力度,比如把“不要编造数据”改成“如果数据来源不明确,回退到以下兜底话术:根据现有信息无法确认该数据,建议进一步核实”。规则越具体、越可执行,模型的遵守度越高。

最后还有一个非常现实的问题:你用的模型版本太弱。像GPT-3.5这类早期模型对长提示词中的规则跟随能力明显比GPT-4o、Claude 3.5之后的新模型差一个档次。如果你遇到规则频繁失效,先别怀疑提示词写法,换一个更强的模型试试,往往立竿见影。

5.2 模型输出格式不稳定导致解析失败

现象:你要求模型输出JSON,它给你在JSON外面加了一层```json代码块标记,或者在里面加了注释,解析直接报错。

这个问题的根源在于大模型的“文本惯性”。它在训练数据里见过太多“展示JSON时用代码块包裹”的例子,所以你只写“输出JSON格式”,它极大概率会顺手加上代码块标记。解决方案有两个方向:

一是把输出格式约束写得更“死”,直接用“只输出JSON,不要包含任何其他文字,不要使用markdown代码块”这种强度的表达。我试下来,对目前主流的新模型,这句话效果很好。

二是用框架级的JSON模式。OpenAI的json mode、Anthropic的tool use,以及一些开源框架自带的Pydantic输出解析器,都是从结构上强制模型输出合法JSON,不依赖提示词约束。我的建议是生产环境优先用框架能力,提示词约束只是辅助,不要把稳定性赌在模型的心情上。

5.3 上下文太长导致模型“忘记”早期指令

现象:对话超过十轮之后,Agent开始出现行为漂移,忘了最开始设定的规则。

这个问题的技术本质是注意力权重分配问题。大模型在推理时,会优先关注离当前位置最近的文本。早期系统提示词在几十轮对话后,对模型的影响力已经衰减得非常弱。解决办法是“上下文工程”的范畴了,这里给两个直接可用的建议:

一是动态压缩早期不重要的对话。随着对话变长,你可以定时把前面对话的核心信息摘要成一个“记忆片段”,和系统提示词拼接在一起。这样相当于给Agent做了一次短期记忆整理。

二是在关键节点重发系统提示词。LangChain里可以在Tool调用前后、或者在Agent准备进入新任务时,重新插入一遍系统提示词(或核心规则摘要)。这种“规则刷新”在长任务Agent里效果非常明显,代价只是多一点token消耗,但换来稳定的规则跟随,非常划算。

5.4 模型“自作主张”改进用户需求

现象:用户说“帮我查A股票的收盘价”,Agent反馈了一整段分析报告,里面还包含技术面、基本面、大盘走势——用户只想要一个数字。

这个问题本质上是“过度满足”问题。大模型的训练目标里包含“给用户提供完整有用的答案”,所以它会倾向于多输出内容。解决方向是在提示词里定义“信息量匹配”原则:根据用户问题的复杂度和明确度,决定输出内容的详细程度。如果用户问题只是一个具体查询,只输出查询结果即可;只有在用户明确要求分析时,才提供扩展内容。

我通常会在系统提示词里加一句“不要过度回答,除非用户明确要求,否则只回答问题的直接结果。简洁优先。”这句话对提升用户体验的效果比想象中大得多。

6. 几个值得现在就动手的小实验

讲了这么多理论和案例,最后我想用三个适合练手的小实验来收尾。这些都是我从零开始进入Agent开发时实际做过的事,难度不大,但对建立“提示词工程手感”非常有帮助。

第一个小实验:做一个“工具调用演示”Agent。不接任何真实API,自己写两个mock函数,比如一个返回天气、一个返回时间。然后试着用提示词让Agent学会“问用户要什么→调用对应工具→根据返回结果回答”。你会发现最困难的部分是让模型在用户没给出必要参数时,主动反问而不是自己编参数。这个实验能帮你理解工具描述怎么写才清晰。

第二个小实验:给同一个任务写三版不同风格的提示词。比如都让模型写一份产品需求文档,但分别用“命令式(你必须…)”“建议式(建议你…)”“协作式(我们一起…)”三种口吻来写,对比输出差异。这个小实验能让你直观感受到语气对模型行为的影响——大模型对语气的敏感度远比我们想象的高。

第三个小实验我觉得是现阶段最有价值的:把上下文工程纳入你的Agent设计。前面提到的上下文压缩、规则刷新、记忆管理,在简单Agent里可能感觉不到差别,但一旦你的任务涉及多轮决策、多次工具调用,上下文管理就成了Agent好坏的真正分水岭。我建议可以拿一个十轮以上的任务循环去测试,观察系统提示词在不同轮次的影响力衰减,然后尝试用“重发核心规则”的方式保持Agent行为稳定,这个实验会直接影响你对Agent架构的理解深度。

我个人的体会是,提示词工程不是一个“写一次就完事”的工作,它更像是在和大模型不断“对焦”。你写出第一版提示词,跑起来,看它哪里理解偏了,再改,再跑。每一轮修改都会让你更理解模型的思考方式——听起来有点玄学,但实践多了,你真的会形成一种“感觉”,能预判这个模型看到某段提示词时会怎么反应。这是写Agent最宝贵的经验,也是任何教程都给不了的东西。希望这些内容能给你一些实在的参考,少踩一点我已经踩过的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询