LLM 不应承担决策和业务逻辑执行
深度阐述如何正确限制 LLM 的系统角色,避免用其处理关键业务逻辑。是设计 AI 应用的重要最佳实践。
深度阐述如何正确限制 LLM 的系统角色,避免用其处理关键业务逻辑。是设计 AI 应用的重要最佳实践。
不要让 LLM 做决策或执行业务逻辑:它们在这方面很烂。我为在线游戏构建 NPC,经常有人问我"你是怎样让 ChatGPT 做到这一点的?"答案总是:"我没有,你也不应该。"
在大多数应用中,LLM 应该仅作为用户和你的应用程序逻辑 API 之间的用户界面。LLM 不应该执行任何逻辑。尽快离开 LLM,能远离就远离。
这最好通过一个人为的例子来说明:你想写一个通过 WhatsApp 访问的国际象棋机器人。用户发送他们想做什么的描述("用我的象吃掉对方的马"),机器人与他们对战。
你能让 LLM 负责维护棋盘的状态并进行令人信服的棋局吗?可能可以,也许吧。你会吗?绝对不会,原因如下:
性能:LLM 能够下棋本身令人印象深刻,但它们在这方面很烂(截至 2025-04-01)。专门的国际象棋引擎总是会成为更快、更好、成本更低的棋手。即使是像 Stockfish 这样包含神经网络的现代国际象棋引擎,仍然是专门构建的特殊系统,具有明确定义的输入和评估函数——而不是试图通过文本维护游戏状态的通用语言模型。
调试和调整:不可能推理和调试 LLM 为什么做出了某个决定,这意味着如果你需要调整它的决策方式,就很难改变。你不理解它通过高维语义空间走过的路程才得到你的答案,它也很难解释这一点。即使是像棋引擎中那样专门构建的神经网络在可观测性方面也很有挑战,而通用 LLM 更是一场噩梦,尽管 Anthropic 在这方面取得了很大进展。
其他问题:测试 LLM 输出比单元测试已知的代码路径困难得多;LLM 在数学方面远不如你的 CPU;LLM 在选择随机数方面不够好;版本控制和审计变得更加困难;监控和可观测性变得很痛苦;通过自然语言的状态管理很脆弱;你受到 API 速率限制和成本的制约;当所有东西都通过 prompt 流动时,安全边界变得模糊。
棋例说明了使用 LLM 处理核心应用逻辑的根本问题,但这个原则远远超出了游戏的范围。在任何精确性、可靠性和效率都很重要的领域,你都应该遵循相同的方法:
用户说他们想用 vorpal sword 攻击玩家 X?LLM 不应该是判断用户是否有 vorpal sword 或结果会如何的系统:LLM 只负责将用户给你的自由文本翻译成 API 调用,并将结果翻译成文本供用户使用。
你在构建一个应该响应用户报价的协商 agent?LLM 不负责谈判,只负责打包、传递给谈判引擎,以及告诉用户结果。
你需要做出随机选择来响应用户?LLM 无权选择。
虽然我专注于 LLM 不应该做什么,但同样重要的是理解它们的优势,以便你能适当地利用它们:
LLM 擅长转换和分类,对"世界如何运作"有相当好的理解,这正是你应该在流程中部署它们的地方。
LLM 擅长接受"用我的剑击中 orc"并将其转换为 attack(target="orc", weapon="sword")。或者接受 {"error": "insufficient_funds"} 并将其转换为"你没有足够的黄金来做这件事。"
LLM 擅长弄清楚用户到底在尝试做什么,并将其路由到你的系统的正确部分。这是战斗命令吗?库存检查?帮助请求?
最后,LLM 擅长理解人类概念,知道"blade"可能是剑,"smash"可能意味着攻击。
注意到所有这些优势都涉及转换、解释或通信——而不是复杂的决策制定或维护关键应用状态。通过将 LLM 限制在这些角色中,你可以获得它们的好处,而不会陷入前面描述的缺陷。
LLM 能做和不能做的事情不断变化,让我想起了神学中的"填补空白的神"——每个神秘现象曾经被解释为神圣的干预,直到科学填补了那个空白。同样,人们不断识别新的"仅限人类"的任务来声称 LLM 不是真正的智能或有能力的。然后,仅仅几个月后,一个新的模型出现,可以很好地处理这些任务,迫使每个人再次移动目标杆,这样的例子随处可见。这是一个不断发展的目标,今天似乎无法达到的东西可能会比我们预期的更快被解决。
就像在我们的棋例中一样,我们可能很快就会拥有能够合理地处理我们上述所有例子的 LLM。但我怀疑大多数缺点不会消失:你传递的非 LLM 逻辑将更容易推理、更容易维护、运行成本更低、更容易版本控制。
即使 LLM 继续改进,基本的架构原则仍然存在:将 LLM 用于它们最擅长的事情——界面层——并依靠专门构建的系统来实现你的核心逻辑。