跳到主要内容

136 篇博文 含有标签「prompt-engineering」

查看所有标签

停止序列的“自毁”陷阱:当用户输入与分隔符发生冲突

· 阅读需 12 分钟
Tian Pan
Software Engineer

一位用户将一段 Markdown 粘贴到你的支持代理中。他们粘贴内容中的第一个标题是 ### Steps I tried。你的提示词模板(prompt template)使用 ### 作为停止序列(stop sequence)。模型尽职地读取了用户的输入,开始回答,并生成了 ### 作为其结构化响应的一部分——结果 API 返回了两句自信的回复,随后便是沉默。工单以“模型质量退化”的名义进入你的队列。其实不然。修复方法只是网关中的一行代码。

停止序列是生产级 LLM 技术栈中极其关键却又常被忽视的调节开关。它们通常是在最初编写提示词的那一周选定的,那时输入还是整洁的工程示例,还没有人粘贴过 JIRA 工单的堆栈信息。十二个月后,用户内容的分布已经远远超出了提示词作者的想象,曾经整洁的分隔符现在变成了潜伏在每三百个用户粘贴中就有一个的隐患。没有任何告警。评估套件(eval suite)依然能够通过。受影响部分的 CSAT 指标下降了 0.5 分并维持在那里。

这不是模型的问题。这是一个伪装成模型问题的输入契约(input-contract)问题,它的形态类似于典型的分布式系统 Bug:为一方的内容分布选择的分隔符被强制应用于另一方的内容分布,且在边界处没有任何监控。

你的系统提示词还在用英文:AI 本地化不完全的隐形成本

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的团队发布了一项 AI 功能。你为本地化工作感到欢欣鼓舞:每个按钮标签、工具提示和错误消息都被翻译成了 12 种语言。产品经理签了字。该功能在全球上线。

然而,六周后,一位德国用户发布了一张截图。AI 的回答用词正确但语域(Register)不对 —— 在非正式的客服场景中显得过于生硬。一位日本用户反映,结构化输出中的日期格式为 MM/DD/YYYY,这导致他们的下游工具出现故障。一位巴西的支持工程师注意到,AI 在对复杂查询进行推理时,偶尔会在句子中途滑入英语。这些并不是基础设施故障。你的仪表盘显示一切正常。但对于非英语用户来说,产品正在悄无声息地变得更糟。

根本原因几乎总是一样的:团队翻译了 UI 字符串,但却让系统提示词保留为英文。这看起来像是本地化,但事实并非如此。

大多数团队在无意中做出的上下文格式选择:JSON vs Markdown vs 纯文本

· 阅读需 11 分钟
Tian Pan
Software Engineer

大多数团队在开发初期选择一次上下文格式后,就再也不会重新审视它。一位开发者选择 JSON 是因为它看起来结构化且机器可读。另一位开发者则选择 Markdown,因为他们在 README 文件中一直使用它。当似乎没有其他必要时,普通文本(Plain text)就成了默认选择。这些并不是工程决策——它们只是习惯。并且它们在无形中塑造了你的模型如何进行推理。

你传递给 LLM 的格式并非死板的包装。它本身就是一条指令。结构化的 JSON 上下文会引导模型进入遵循模式(schema-following)的行为。Markdown 鼓励层次化的综合。普通文本则开启了更灵活的推理。即使只是选错了一个格式类别,也可能导致准确率下降 40% 或更多——而且你无法在日志中查看到这种错误。

LLM 系统中的软约束与硬约束:为什么失配会导致真正的失败

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数 LLM 系统故障并非源于模型出错。而是源于系统误判了模型能够强制执行的约束。当你在系统提示词中写下“绝不泄露客户数据”并将其等同于“撤销数据库凭据”时,你引入了一个范畴错误。这最终会导致安全事件、可靠性故障或受损的用户体验——而你直到故障在生产环境中发生时才会察觉。

软约束与硬约束之间的区别是架构层面的,而非风格层面的。搞错这一点不会导致风格退化,而是会导致安全漏洞。

系统提示中的冲突指令:无人负责的隐性故障模式

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 AI 功能在上线时运行良好。六个月后,它有时给出简短的一两句话,有时写出五段长文,偶尔还会拒绝回答上个季度毫无障碍地处理过的问题。代码库中没有任何变化——至少你是这么认为的。实际上,系统提示在悄然改变,经过四名工程师跨两个团队提交的十一个拉取请求,逐步演变。每次改动单独来看都合情合理,但合在一起,却将你的提示变成了一台矛盾制造机。

这就是指令冲突问题。它不会抛出异常,不会出现在错误日志中,而是以行为漂移的形式表现出来——模型在细微不同的情境下做出细微不同的事,难以复现,更难溯源。等到用户提交 bug 报告时,提示可能已经被再次打过两个补丁了。

AI 入职差距:为什么工程师无法学习他们无法测试的东西

· 阅读需 12 分钟
Tian Pan
Software Engineer

一名新工程师加入了一个重度依赖 AI 的团队。入职第三天,他们发现系统指令中有一个措辞别扭的双重否定。看起来像是个 bug。于是他们把它清理了——这是任何合理的人都会做的小小优化。两小时后,一条关键流水线的客户端分类准确率从 91% 跌至 74%。没有人知道原因。

这种情景以某种形式发生在几乎每一个基于 LLM 构建系统的团队中。新工程师并不粗心。那个提示词看起来确实有问题。但那个双重否定在某种意义上是"承重墙"——只有写下它的人才真正理解,而那是在经过数周实验之后才领悟到的。他们从未把这种理解写下来。

这就是 AI 入职差距:AI 代码库表面上的行为与实际行为之间的鸿沟,以及为什么这个鸿沟在有人掉进去之前是不可见的。

上下文窗口是一个 API 界面:像对待合约一样对待你的提示词结构

· 阅读需 11 分钟
Tian Pan
Software Engineer

在一个生产环境中的 LLM 功能上线半年后,一名工程师提交了一个 bug:模型在上个季度的某个时间点开始给出错误的输出。没人记得改过提示词(Prompt)。Git blame 显示它为了“提高可读性”被清理过。之前的版本已经找不到了。调试工作只能从零开始。

就在这一刻,团队才发现他们的上下文窗口(context window)从未被真正工程化过——它只是被拼凑出来的。

上下文窗口是你的系统与模型之间的契约。进入其中的每一个标记(token)——系统指令、检索到的文档、对话历史、工具架构、用户查询——都是对一个函数调用的输入,这个调用既费钱又耗时,且会产生非确定性的输出。然而,大多数团队将上下文组合视为实现细节,而非 API 表面。提示词被就地编辑,没有版本控制。各部分通过累加增长。没有人负责布局。变化在无声无息中传播。调试体验比 LLM 时代之前的任何东西都要糟糕,因为至少堆栈跟踪(stack traces)会告诉你什么是改变了的。

超参数幻觉:为什么 Temperature 和 Top-P 应该最后才调

· 阅读需 10 分钟
Tian Pan
Software Engineer

当 LLM 的输出感觉不对劲时,工程师会本能地去调 temperature。这是调试手册里最早的动作之一——调低它以获得更强的一致性,调高它以获得更多创意。这感觉很有效,因为改动简单且效果立竿见影。但这几乎从来都不是正确的做法。

Temperature 和 top-p 只是输出质量最后 10% 的因素,而不是前 90%。真正决定模型成败的变量是上下文质量、指令清晰度和模型选择——依次排列。在一个有问题的提示词之上再调整采样参数,就像给一道还没煮熟的菜调味一样。根本问题并没有消失。

群体提示问题:为什么你的系统提示对80%的用户有效,却悄然让另外20%的用户失望

· 阅读需 11 分钟
Tian Pan
Software Engineer

当你编写系统提示时,脑海中有一个预设的用户形象。也许是一位用简洁英语提出有针对性问题的专业人士,也许是发送简短、范围明确、完全符合提示假设的请求的人。你针对看似具有代表性的示例进行测试,调整直到输出效果令人满意,然后上线。

然后你看到了生产流量。

你的系统提示必须处理的真实查询群体,并非你所设计的中位情形,而是一个分布——有些查询范围狭窄,更多的漫无边际——还有一条长尾,暴露出你指令中每一个隐藏假设。对大多数生产系统而言,15%到30%的真实查询落入提示处理欠佳的类别。令人不安的是:这些失败大多是静默的。系统返回200状态码,用户得到一个看似合理的答案,失败永远不会浮现在你的日志中。

Prompt 权重归因:识别系统提示词中的“无效指令”

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队发现他们的系统提示词存在冗余问题的方式都如出一辙——一次成本审查、一次延迟激增,或者某位工程师终于从头到尾读了一遍。他们通常会发现一个在六个月内有机增长的 2,000 token 的文档,其中散落着三个不同版本的“保持简洁”,还有指向二月份就已弃用的产品工作流的指令,以及模型在每次运行时都明显忽略的十几条规则。提示词规模庞大,但大部分内容其实毫无用处。

这就是 Prompt 信用分配问题 (Prompt Credit Assignment Problem):弄清楚一个数千 token 的系统提示词中,哪些指令真正驱动了模型行为,哪些只是消耗 token 并分散注意力的冗余负重。坏消息是,大多数团队完全跳过了这一步——他们在行为出错时添加指令,却从未减少过。好消息是,这有一套可重复的工程准则。

提示工程的职业陷阱:哪些 AI 技能会复利增长,哪些会逐渐退化

· 阅读需 11 分钟
Tian Pan
Software Engineer

在 2023 年,“提示词工程师”(prompt engineer)是科技领域搜索频率最高的职位名称之一。LinkedIn 上到处都是重新包装个人简介的工程师。招聘信息许诺给那些懂得如何诱导 GPT-4 表现的人六位数的薪水。但职位描述中没有提到的是,其中列出的许多技能已经处于“借来的时间”中——到 2026 年,那些能够分辨出持久技能与衰减技能区别的工程师,最终的境遇将大不相同。

提示词工程的职业陷阱并不在于这个领域消失了,而在于它变化太快,以至于在 12 个月内建立的技能到第 18 个月就变成了负资产。那些在错误的层面过度投入而忽视了正确层面的工程师发现,随着下一个模型版本的发布,他们所掌握的专业知识变得毫无意义。

Prompt 变异测试:找出哪些系统提示词指令真正起作用

· 阅读需 12 分钟
Tian Pan
Software Engineer

有一种特定的工程债(Engineering debt)永远不会出现在你的指标中。每当有人在系统提示词(System prompt)中添加一个句子来修复一个偶发的投诉——比如 “绝不讨论竞争对手的产品” 或 “始终以正式的口吻回复” ——而随后又没有人验证模型是否真的执行了它,这种债务就会累积。几个月后,提示词增加到 800 个 Token。它听起来很有权威感,包含的内容包罗万象。但也许其中三分之一根本没起作用。

提示词变异测试(Prompt mutation testing)就是找出那三分之一无效指令的实践。该技术借鉴了软件工程中经典的变异测试:系统地在代码中引入微小、刻意的错误,以确定你的测试套件是否真的能捕获它们。在这里,你向系统提示词中引入刻意的扰动——删除一个分句、抵触一条规则、用近义词替换关键关键词——并衡量模型的输出实际发生了多大变化。那些在扰动下幸存且不影响行为的指令是装饰性的。而那些一旦被触碰就会导致出错的指令则是承重的(Load-bearing)。