已过时,OpenAI 推出了 JSON Mode 来让 LLM 输出 JSON,可以参考:https://platform.openai.com/docs/guides/text-generation/json-mode
前言
在过去的一段时间里,我们似乎处在人工智能的浪潮中。大语言模型(LLM)在越来越多的应用场景中落地,逐渐成为生活和工作中不可或缺的一部分。我们都知道 LLM 擅长用自然语言来解答和分析问题。但是,想要让 LLM 与业务程序进行衔接,目前还需要具备稳定输出 JSON 或 YAML 等结构化数据的能力。
当然我们可以在 Prompt 中强调想要的输出格式,比如 JSON
:
LLM 可能会按照你的预期,输出你想要的的 JSON 结构,像这样:
也可能会额外附带一些描述语句,像下面这样,不稳定的输出就很难给到代码来直接使用。
TypeChat
微软为了优化上面 JSON 输出问题开源的一个 Node.js 包,官网地址:https://microsoft.github.io/TypeChat/ 。需要在和 LLM 交互之前,提前用 TypeScript 定义所需数据的 schema 描述。
TypeChat 在背后的实现分为三部分:
- 读取 schema 中的 TypeScript 类型,填充到内置的 prompt 内。
- 附带上用户的 request 向 LLM 发起请求,等待 LLM 回复完毕。
- 使用 Zod 来校验 LLM 的回复是否符合 schema 中的定义。 如果不符合的话,就会发起一次
createRepairPrompt
来尝试修复 JSON 数据。
可以看到 TypeChat 的思路还是很巧妙的,类似于 Function Calling ,同时在背后实现了校验、重试等逻辑。 但是,最终能否稳定输出 JSON 取决于 LLM 模型本身的能力。如果模型的能力不足,使用过程中可能会频繁触发 createRepairPrompt
或者导致任务失败,会对最终的用户体验产生影响,可以按照 TypeChat - 使用技巧 这一章的建议来进行优化。
另外,想要减少重试和失败的次数,同时对 JSON 的依赖没那么高,也可以考虑使用 YAML 甚至 Markdown 来输出所需内容的格式。相较于JSON,这些格式更加宽容,容错率更高,不会因为一个符号的输出问题而导致整个内容提取和校验失败,坏处就是解析和校验的成本相较于 JSON 更高。
当然,OpenAI 也考虑到了这样的需求,推出了JSON Mode 让 LLM 输出 JSON。但是,并不支持使用 JSON Schema 来约束输出,目前感觉实用价值不太高。