☰
从GPT到AI Agent:提示词工程驱动大模型执行力的实战指南
2026/10/22 3:09:40 网站建设 项目流程

1. 从“会回答”到“会执行”的一步之遥

前几天有位朋友跑来问我一个问题:他已经把某大模型接到自己的业务里了,提示词也写得挺规矩,角色设定、输出格式、少样本示例全都有,可让这个聊天机器人去帮他查一下库存、算一下补货量、再更新一下内部的进货表,它死活做不到,最后还是得人工复制粘贴。

这事我太熟了。过去一年大家喊的“提示词工程”,大多数时候是在解决“如何让模型把话说对”——把答案写得更规范、更像人话、更有条理。但到了真实工作流里,光是“把话说对”远远不够。你需要的是一个能拆解任务、按步骤调用系统、并对每一步结果负责的智能体。这就是标题里说的那句“执行力升级”:从GPT这类对话模型,到能跑通流程的AI Agent,中间真正变掉的不是模型的“智商”,而是提示词工程的设计方式。

OpenCSG在做相关实践时,我们最常被问的问题其实就三个:任务到底怎么拆?工具到底怎么调?安全边界到底划在哪?这篇博客把这三件事一次讲透,送给正在把大模型从“聊天窗”往“干活系统”里搬的人。

1.1 大家都在说的“提示词工程”其实分两个时代

如果你拆开看,提示词工程这两年其实经历了两次完全不同的考卷。第一次考卷是“单向生成”:模型接收到一段文字,输出一段文字,任务边界清晰,评价标准是“答得对不对、好不好”。这时候的提示词大量使用角色扮演、语气限制、输出模板,本质是在指导一个表达能力很强但没有行动能力的文员写报告。

第二次考卷是“多轮执行”:模型接收目标,自己规划步骤,选择合适的工具,观察工具返回结果,再决定下一步动作。这时候的提示词不再是静止的“台词脚本”,而是一份动态的“任务说明书”,它要能被同一个主循环反复读取、更新、校验。问题也随之而来——说明书写得太粗,模型不知道从哪里下手;写得太细,又很快烧光上下文额度。

很多团队把第一代经验直接搬到第二代,结果就是朋友遇到的那种状况:模型在“说”的部分表现完美,在“做”的部分完全拉胯。

1.2 智能体不是一个产品形态,而是一种执行逻辑

所以要理解从GPT到智能体的升级,关键不是“换一个更聪明的模型”,而是“换一套执行框架”。GPT时代的提示词工程,对象是模型的输出分布——怎么让生成结果落在你想要的区间里。智能体时代的提示词工程,对象是“模型+工具+状态”的闭环——模型负责决策,工具负责落地,状态负责告诉模型“上一步到底发生了什么”。

这个闭环通常包含三个组件:记忆,让智能体知道上下文和历史;规划,让智能体把大目标拆成小步骤;执行,让智能体通过调用外部工具真正改变系统状态。提示词在其中的作用,是把这个闭环里的每一步都约束在可控范围内。说到底,提示词依然是灵魂,只是它的工作方式从“写一篇作文的要求”变成了“指挥一个团队运行的流程文档”。

2. GPT的“高分作文”与智能体的“干活逻辑”差在哪

你要想清楚一个事:GPT本质上是一个“静态知识发生器”。它从训练数据里学到的世界是凝固的——你问它“今天天气怎么样”,它能给你写一篇关于天气系统如何运作的千字科普,但它不知道窗户外面现在下没下雨。因为训练数据停在某个时间点,模型没有实时传感器。

这不叫“蠢”,这是架构天生的边界。大模型的强项是语言理解、知识检索、逻辑推理、内容生成,它的弱项是所有涉及“当前状态”和“物理世界动作”的环节。而智能体要干的事,恰恰是补上这两个缺口:实时状态的获取,以及对外部系统的影响。

2.1 静态知识与实时状态之间的断层

举个非常具体的例子。让GPT直接回答“我们仓库A类物料的库存还剩多少”,它会给你一段“仓库管理需要注意……”的建议,这不是它不配合,而是它的训练数据里根本没有你们公司的库存表。你可以在提示词里把库存数字写进去,但它没法保证数字是最新的,更没法在每次变化后自动更新自己。

于是你想到了工具调用:让模型去查数据库。这个思路完全正确,但只是第一步。因为查完之后呢?如果库存低于安全阈值,模型要不要自动生成采购申请?采购申请走哪条审批流?审批通过后要不要更新预测模型?这一连串动作,靠一次“问答”永远答不完。

这中间的断层在于:模型理解世界的单位是“事实和概念”,业务系统运转的单位是“事件和状态变更”。提示词工程要做的,就是搭一座桥,让模型的理解能力能被拆成一系列事件,把“理解”变成“动作”。

2.2 模型缺的不是智商,是记忆、规划、执行三块拼图

所以你看那些跑起来的智能体项目,背后几乎都是同一类架构:一个规划循环在反复运转。

第一步,模型根据用户目标生成一个计划。第二步,系统按计划选择一个工具,模型抽取参数、发起调用。第三步,工具执行完返回结果,模型观察结果,判断计划是否需要调整。第四步,循环继续,直到目标达成或达到终止条件。

这个循环里,提示词工程干的活不是“写一段漂亮的话”,而是设计三个东西:怎么让模型把计划拆得足够可执行;怎么让工具列表对模型来说是“可理解、可选择、可调用的”;怎么确保这个循环在任何一步出错时都能安全收住。

我见过不少团队在产品原型阶段犯同一个错误:他们把注意力全放在“选个聪明的模型”上,结果模型推理能力强了,但工具调用一塌糊涂。因为工具调用不是模型“顺手就会”的,它是工程问题,是提示词、接口、数据格式、错误处理合在一起的结果。

3. 拆分步骤:把“目标”翻译成模型能逐步走完的走查单

智能体时代的第一课,是任务分解。别急着写工具、调接口,先把“目标”拆成“步骤”。拆得对不对,直接决定后面的稳定程度。

这里的拆,不是让模型随便想想“先做什么后做什么”,而是要拆成一个带依赖关系、可验证、可回滚的任务序列。你可以把它理解成给新人写的SOP:不能写“把项目搞定”,要写“先读配置、再拉数据、再跑校验、最后出报告,每一步的输出是什么,卡住了找谁”。

3.1 两步拆分法:目标树 + 依赖关系

我自己常用的方法分两步。第一步先画目标树:把最终目标往下拆,直到每个叶节点都能对应一个“动作 + 可验证结果”。第二步做依赖分析:哪些任务必须串行,哪些可以并行,哪些失败了必须中止整个流程。

举个例子,目标是“汇总本周各组项目状态并发出周报邮件”。拆开以后大概是:拉取各组进度数据 -> 汇总成统一格式 -> 生成周报正文 -> 调用邮件工具发送。这里面拉取数据和生成正文可以并行,但生成正文依赖拉取结果,发送又依赖生成完成。如果一个环节的数据源挂了,你是继续用缓存生成还是直接终止,应该提前定义好,而不是让模型临场发挥。

这种拆分最大的价值是“可观测”。每一步的输入输出都是明确的,你可以在任意一步插入检查点,确认数据没有跑偏。

3.2 什么时候算“拆到位”:可验证、可回退、可合并

很多新手拆任务容易拆成两个极端。拆太粗,一个任务里还是塞了一堆动作,模型的规划能力反而成了瓶颈;拆太细,每一步都调用一次模型,Token消耗和延迟双双爆炸。

我自己的判断标准有三条:可验证,这步完成后有一个明确的结构化结果来判断成败;可回退,这步出错时能回到上一步,不影响全局;可合并,相邻步骤如果能共享同一个数据源且不存在外部副作用,就应该合成一步。

拿“生成周报”来说,“整理各组数据”和“按模板生成文字段落”可以分开,但“生成文字段落”和“在本地临时文件里存一份”就没必要分。前者是决策步骤,需要模型参与,后者是纯机械动作,可以直接由代码完成。智能体的每一步未必都要经过大模型,能在工程代码里硬编码的,就别浪费模型的推理。

3.3 与子任务配套的Prompt写法

任务拆完之后,还要给每个子任务写一段“独立的小提示词”。这段提示词的职责很单一:解释这个子任务的目标、输入数据的格式、输出结果的预期结构,以及遇到异常情况时怎么办。

这跟传统的“一段prompt走天下”完全不同。子任务提示词不需要讲背景故事,不需要预设角色,只需要说清楚“你手头有什么、你要产出什么、什么情况下算失败”。比如拉取数据那段,提示词只需要说明数据接口的路径、鉴权方式、失败重试次数,以及返回JSON的写入位置。段落越短越好,因为上下文窗口终究有限,把最重要的执行信息放在最显眼的位置,模型理解的准确率才会高。

我见过不少团队把任务拆好了,但给每个子任务配的提示词还沿用“你是资深专家”那一套,不仅没用,还浪费上下文。子任务提示词是“操作指令”,不是“角色设定”。

4. 工具调用:把大模型“对话能力”引到外部系统的工程细节

任务拆好了,接下来就是让模型真正“使用工具”。工具调用的成熟方案现在很多,主流的大模型API基本都支持Function Calling机制。其原理并不复杂:你在请求里声明一批“工具”,每个工具包含名称、功能描述和参数结构;模型根据对话上下文,决定“要不要调用某个工具、参数填什么”;系统收到调用指令后,去执行真实代码,再把结果回传给模型。

这套机制看似简单,但工程细节极其容易翻车,尤其是工具描述本身的质量问题。

4.1 工具描述本身就是一种提示词

很多人没意识到:Function Calling里的“工具描述”,本质上就是一种提示词。它是模型唯一能用来判断“何时调用、调用哪个、参数怎么填”的依据。如果你把工具描述当成API文档来写,全是准确但冷峻的技术术语,模型经常会在“该用哪个”上犹豫。

比如你给两个工具:“查询订单信息”和“查询退款信息”。模型面对用户说“帮我看看我上个月那笔订单”,它很可能拿不准该查哪个,于是随便选一个,结果数据对不上。如果你把描述写成“当用户提到订单、购买记录、物流等场景时使用”,模型的选择准确率会高很多。

参数结构也一样。每个参数都要写明含义、类型、取值范围、是否必填,能加默认值的加默认值。别把参数设计成“让模型猜”,模型不是特别擅长猜你的内部字段命名习惯。

4.2 一次工具调用的完整生命周期

一个标准的工具调用生命周期长这样:模型输出一个工具调用请求 -> 系统校验请求格式、检查参数合法性 -> 系统执行真实工具函数 -> 拿到返回结果 -> 将结果作为“观察消息”重新塞回对话 -> 模型根据结果继续生成下一步。

这里最核心的坑在“系统校验”这一步。我建议所有工具调用都先做一次参数白名单校验,把不符合schema要求的请求直接拦截,而不是贸然执行。因为模型偶尔会生成一些“似是而非”的参数,比如日期格式写错、枚举值越界、字符串里混入多余字符。如果直接把这种参数丢给业务接口,轻则报错,重则写入脏数据。

另外,工具返回结果也要设计得适合模型阅读。别把数据库原始记录整包丢回去,字段一多,模型很快晕掉。最好做一次“压平”处理:只保留当前任务需要的字段,并格式化好枚举值的中文含义,让模型一眼能看懂结果意味着什么。

4.3 工具调用最容易翻车的三个地方

第一个翻车点是工具名和描述里的“歧义”。“获取用户信息”和“获取用户详情”,字面上几乎一样,模型根本分不清。解决办法是给工具加场景前缀,比如“CRM_获取用户核心资料”“订单_查询用户近期订单”,让工具名自带分类信息。

第二个翻车点是参数冲突。你有一个工具接收“日期范围”,比如start_date和end_date,模型很可能把两个参数的顺序填反。这时候你可以在参数描述里写清楚“开始日期不能晚于结束日期”,并且在系统校验阶段加一个自动校正逻辑,发现start_date比end_date晚就自动交换,而不是直接报错。

第三个翻车点更隐蔽:上下文污染。工具调用好几次之后,对话历史里塞满了观察结果,模型看到后面,前面关键信息被冲淡。解决办法是定期压缩历史,保留用户核心目标、最近两轮的工具结果以及当前未完成的子任务状态,不需要把全部工具返回都堆在提示词里。

5. 安全边界:执行力越强,越要管住“最后一公里”

智能体跟聊天机器人的本质区别是它会“动作”。能动作就必然带来风险。你让聊天机器人胡说八道,顶多是被用户骂两句;你让智能体误删数据、误发邮件、误转账,那就是真事故了。所以安全边界的核心原则是:在智能体的执行链路上,防系统性风险而不是只防单点错误。

5.1 最小权限与工具白名单

我的第一个建议:给智能体开放的工具集,永远走“最小权限”原则。能只读的不要给写权限,能查当前组织数据的不要给全平台数据查询权限,能返回汇总数据的不要给原始库表接口。

工具白名单设计同样重要。不要把所有接口一股脑注册成Function,而是按场景划分工具包。比如“查询场景”只注册三个只读接口,“执行场景”单独注册一个带审批钩子的写接口。模型每次可选的工具范围是有限的,这会直接减少误选概率。

有一个真实的教训:某团队把所有内部系统的接口都注册成了工具,包括“删除用户”“修改订单金额”这种高危接口。然后在测试时让智能体去“模拟一次越权访问”,模型竟然真的调用了删除接口,虽然最后因为环境权限拦截住了,但把运维吓出一身冷汗。高危操作必须需要审批,不能再靠“模型应该知道不能做”。

5.2 操作确认与人工闸门

对高影响操作,我强烈建议加一个“人工确认闸门”。具体做法是:把工具分成两级,一级工具模型可以直接调用,通常是只读、低风险操作;二级工具模型只能“申请调用”,调用请求会进入一个待确认队列,真实执行要等人工点了确认按钮。

这样设计的理由很简单:模型对后果的感知是极其有限的。它能推理“删除用户是会伤害用户的行为”,但它理解不了“这个用户关联了一百条业务记录、十张工单、五条审批流,删了会连锁报错”。人工确认闸门把这个理解成本转移给了更靠谱的人。

你可以在产品上做成弹窗形式:智能体执行到高危步骤时,界面弹出“将执行以下操作:发送邮件给张三,内容为……”,人工点“允许”或“拒绝”。实测下来,这个设计不仅降低了事故率,还明显提升了用户对智能体的信任感,因为用户觉得“它是我的助手,不是我失控的代理”。

5.3 提示注入与越权指令的防护思路

提示注入是智能体特有的安全威胁。攻击者把恶意指令藏在文本里,比如商品评论、用户输入、文档内容,让模型去执行不该执行的操作。防注入没法百分百做到,但可以从三个层面降低风险。

第一层是输入侧过滤:对进入对话系统的外部文本做大模型安全分类,识别明显的恶意指令模式。第二层是工具侧校验:就算模型被诱导,工具调用层也要校验参数是否越权,高危操作必须有二次确认,攻击者没法通过“语言引导”绕过工程权限。第三层是结果侧审计:所有工具调用留痕,谁发起的调用、模型说了什么、返回了什么,全部进日志。

说白了,安全边界不能只依赖模型的“道德判断”,要在工程链路上设置硬闸门。语言模型可以被诱导,但权限系统和人工审批流不会被一段prompt骗过去。

6. 一个最小可复现的“跨系统执行”示例

讲了这么多原理,上点实战。我选一个最常见的场景:让智能体根据邮件内容,去系统里查询项目信息,再生成一封周报回复,并且在最终发送前要人工确认。整个示例尽可能简单,但足以覆盖“任务拆解、工具调用、安全边界”三个主题。

6.1 场景设定与工具清单

假设业务场景是这样的:用户给智能体发一段原始邮件文本,内容是“请帮我看一下某项目的当前进度,整理成进度摘要,然后以邮件草稿的形式回复给我”。

我给它注册三个工具,刚好对应三级安全策略:

  • fetch_project_progress(project_id):只读工具,查询项目进度,供模型直接调用。
  • generate_draft_email(project_id, summary, recipient):写操作,生成邮件草稿,但不真正发送,可供模型直接调用。
  • send_email(draft_id, recipient):高危操作,真正发送邮件,必须经过人工确认。

工具描述我写成下面这样,注意描述里的场景引导词:

[ { "name": "fetch_project_progress", "description": "当用户询问项目进度、交付状态、里程碑完成情况时使用。返回项目各阶段的最新进度、风险点和负责人。", "parameters": { "project_id": { "type": "string", "description": "项目唯一标识" } } }, { "name": "generate_draft_email", "description": "基于进度数据生成回复客户或内部团队的邮件草稿。不发送,仅保存草稿后返回草稿ID。", "parameters": { "project_id": { "type": "string", "description": "项目标识" }, "summary": { "type": "string", "description": "邮件正文的核心摘要" }, "recipient": { "type": "string", "description": "收件人邮箱" } } }, { "name": "send_email", "description": "最终发送指定邮件草稿。此操作不可逆,执行后邮件将真实发出。", "parameters": { "draft_id": { "type": "string", "description": "要发送的草稿ID" } } } ]

注意看,工具描述本身把“什么时候该用这个工具”的逻辑写进去了,不是干巴巴的接口文档。模型看到“当用户询问项目进度……”就更容易把输入文本匹配到第一个工具。

6.2 主循环与安全阀代码示意

简化版的主循环逻辑可以写成这样,只展示核心过程,每行都给了注释:

def agent_loop(user_input, max_steps=6, confirm_func=None): messages = [{"role": "user", "content": user_input}] for step in range(max_steps): # 第一层:让模型决定下一步动作,传入工具定义 resp = llm.call(messages, tools=TOOLS) msg = resp.choices[0].message # 模型没有发起工具调用,说明任务可能已完成或需要提问 if not msg.tool_calls: return msg.content messages.append(msg.model_dump()) for call in msg.tool_calls: tool_name = call.function.name args = json.loads(call.function.arguments) # 第二层:参数白名单校验 if not validate_tool_params(tool_name, args): messages.append(gen_tool_error(tool_name, "参数校验失败")) continue # 第三层:高危操作走人工确认闸门 if tool_name == "send_email": allow = confirm_func(args) if not allow: messages.append(gen_tool_result("操作被用户取消")) continue # 执行真实工具 result = exec_tool(tool_name, args) messages.append(gen_tool_result(tool_name, result)) raise RuntimeError("超过最大执行步数")

这段代码里的三层机制就是这部博文反复强调的:模型负责决定,但系统负责校验、拦截和执行。run到“send_email”时,refuse允许就是靠confirm_func人工确认,否则模型再聪明也不能把邮件发出去。

6.3 实测验证与常见失败模式

我把这个Demo跑过不下五十轮,常见的几个失败模式非常有代表性。

第一类是模型把项目ID填错。用户邮件里写的内容往往不是标准ID,模型经常把“RF-2024-15”这种编号里的数字提取错。解决办法是在参数校验里加上“ID必须匹配正则 ^RF-\d{4}-\d{2}$”,不匹配就反馈给模型重新提取。

第二类是模型生成摘要时过度发挥。明明查询结果只有三条更新,它却编出一些“预计下月完成”的推测。这种幻觉单靠工具调用链路拦不住,需要在“生成摘要”的提示词里加约束:只能引用工具返回数据,不得额外推断。如果还是出现,就再让工具返回结果里带上“更新时间戳”,由系统校验摘要里是否内部一致。

第三类最值得注意:模型在这个任务里反复调用fetch_project_progress,因为用户原始邮件里提到了多个项目。模型可能分不清“主要询问的是哪个”,于是每个都查一遍。这本身没坏处,但会拖慢响应。处理办法是在提示词里加一句“如果用户未明确指定项目,先询问澄清,不要批量查询”,让模型学会停住。

7. 我在实战里踩过的几个坑(写给正在搭建Agent的人)

最后分享几个比较碎但很实用的心得,基本都来自我在OpenCSG社区里看到的共性问题。

7.1 “工具描述全是精确术语”并不好理解

早期我给工具写描述时,喜欢用特别学究的说法:“Call create_dispute(API-3B)发起售后争议流程。”结果模型经常不调用它,因为用户不会说“售后争议流程”,用户只会说“我要退款”“这单有问题”“把钱退给我”。

后来我把描述改成:“当用户对订单不满、要求退款、抱怨货物有问题,或提出售后相关诉求时,可以调用本工具发起争议处理流程。”模型的理解准确率立刻上来了。这就是“工具描述是用给模型看的,不是用给文档评审看的”含义。

7.2 温度参数不是越高越好调

很多人调Agent时习惯把temperature调到比较高,觉得“生成内容更丰富”。但在工具调用场景,这是大忌。温度一旦调高,模型输出JSON时格式不稳定的概率显著增大,参数值也会出现无意义的偏移。

我目前的做法是:涉及工具调用的推理环节,temptature固定在0.1以内;只有“生成文案”这种创意型子任务,才把温度调到0.7以上。也就是同一个Agent内,不同子任务用不同的温度参数,而不是全局一套设置。

7.3 先拦截动作,再拦截输出

最后一条经验,来自一次差点出事的事故。某个内部工具可以删除项目附件,模型在生成回复时提到“用户要求删除附件,已处理”。但实际上模型根本没有调用删除工具,它只是在“输出层面”编造了一个结果。幸好当时有动作审计日志,一查发现没有对应调用记录,才没让用户以为真的删了。

从此我养成了一个习惯:所有输出给用户的结果,必须能跟工具调用记录一一对应。模型可以说“已处理”,但如果处理记录里没有动作,那就说明它撒谎了。先拦住“动作”,再去纠正“输出”。这也是安全边界的最后一环——审计追踪。

搭智能体跟搭传统服务不一样,你要同时面对模型的创造性、系统状态的复杂性、以及用户预期的错位。但只要把任务拆明白、把工具描述写清楚,再把安全边界划到执行链路里,这件事就会从一个“玩具”变成“生产力”。剩下的,就是多跑几轮,让异常样本帮你打磨系统的每一个判断分支。

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

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

立即咨询