第6章 LMQL 语法概述:基于 Python 的 LLM 编程语言
概述
快速了解 LMQL 的语法与能力。LMQL 是一种基于 Python、带有声明式元素的 LLM 编程语言。下面通过一个简单示例来展示 LMQL 的基本语法:
``` # 待分析的评价 review = """We had a great stay. Hiking in the mountains was fabulous and the food is really good."""
# 用 prompt 语句向模型传递信息 "Review: {review}" "Q: What is the underlying sentiment of this review and why?" # 像 [ANALYSIS] 这样的模板变量用来生成文本 "A:[ANALYSIS]" where not "\n" in ANALYSIS
# 用受约束的变量生成分类结果 "Based on this, the overall sentiment of the message\ can be considered to be[CLS]" where CLS in [" positive", " neutral", " negative"]
CLS # positive ```
Model Output
``` Review: We had a great stay. Hiking in the mountains was fabulous and the food is really good. Q: What is the underlying sentiment of this review and why? A: ANALYSIS The underlying sentiment of this review is positive because the reviewer had a great stay, enjoyed the hiking and found the food to be good. Based on this, the overall sentiment of the message can be considered to be CLS positive ```
在这个程序中,我们让 LLM 对一条用户评价做情感分析。先让模型给出基础分析,再让它把整体情感归类为 positive、neutral 或 negative 三者之一。模型正确识别出这条评价的情感是 positive。
实现这个流程时,我们用了两个模板变量 [ANALYSIS] 和 [CLS],它们都通过 where 表达式施加了约束。
对于 ANALYSIS,我们约束模型不能输出换行符,避免它输出多行内容导致程序出错。对于 CLS,我们约束模型只能输出三个候选值之一。借助这些约束,模型给出的分析和分类都能保持格式规范、符合预期。
如果没有约束,上面的 prompt 可能产生 good、bad 之类的其他分类结果,那就得靠临时写解析逻辑来提取明确答案。而使用 LMQL 的约束,只需限制模型只输出预期值之一,就能实现稳健可靠的集成。关于 LMQL 各类约束的更多内容,参见 Constraints。
用分布(Distribution)提取更多信息
上面的查询能提取评价的情感,但拿不到模型对分类结果的置信度。要获得这一信息,可以额外使用 LMQL 的 distribution 子句,得到 CLASSIFICATION 所有可能取值的完整分布:
``` argmax # 待分析的评价 review = """We had a great stay. Hiking in the mountains was fabulous and the food is really good."""
# 用 prompt 语句向模型传递信息 "Review: {review}" "Q: What is the underlying sentiment of this review and why?" # 像 [ANALYSIS] 这样的模板变量用来生成文本 "A:[ANALYSIS]" where not "\n" in ANALYSIS
# 用受约束的变量生成分类结果 "Based on this, the overall sentiment of the message can be considered to be[CLS]" distribution CLS in [" positive", " neutral", " negative"] ```
Model Output
``` Review: We had a great stay. Hiking in the mountains was fabulous and the food is really good. Q: What is the underlying sentiment of this review and why? A: ANALYSIS The underlying sentiment of this review is positive because the reviewer had a great stay, enjoyed the hiking and found the food to be good. Based on this, the overall sentiment of the message can be considered to be CLS
P(CLS) - positive (*) 0.9999244826658527 - neutral 7.513155848720942e-05 - negative 3.8577566019560874e-07 ```
Distribution Clause
这里我们不再用 where 表达式约束 CLS,而是在单独的 distribution 子句中加以约束。在 LMQL 中,distribution 子句用于声明是否要额外获取某变量所有可能取值的分布。本例中,我们要获取 CLS 的取值分布。
扩展语法:注意,要使用 distribution 子句,必须显式指定解码算法,即在代码开头写上 argmax(详见 Decoding Algorithms)。一般来说,这种扩展形式的 LMQL 语法——缩进整个程序并在开头显式写明 argmax 等——是可选的,但如果要用 distribution 子句则建议这么做。本文档中两种语法写法都会用到。
除了让模型完成 ANALYSIS 之外,LMQL 还会对 CLS 的每个候选值分别打分,并把序列得分归一化为概率分布 P(CLS)(输出到 Playground 的 Terminal Output 或 CLI 的 Standard Output)。
可以看到,模型对把评价分类为 positive 相当有信心,概率高达 99.9%。
注意:目前像 CLS 这样的 distribution 变量只能出现在程序的末尾。
根据模型输出动态响应
改进初始查询的另一种方式,是构建更动态的 prompt,根据模型的输出做出响应。例如,可以根据模型的分类结果,让它对评价做更深入的分析:
``` argmax review = """We had a great stay. Hiking in the mountains was fabulous and the food is really good.""" """Review: {review} Q: What is the underlying sentiment of this review and why? A:[ANALYSIS]""" where not "\n" in ANALYSIS "Based on this, the overall sentiment of the message can be considered to be[CLS]" where CLS in [" positive", " neutral", " negative"] if CLS == " positive": "What is it that they liked about their stay? [FURTHER_ANALYSIS]" elif CLS == " neutral": "What is it that could have been improved? [FURTHER_ANALYSIS]" elif CLS == " negative": "What is it that they did not like about their stay? [FURTHER_ANALYSIS]" where STOPS_AT(FURTHER_ANALYSIS, ".") ```
Model Output
``` Review: We had a great stay. Hiking in the mountains was fabulous and the food is really good.
Q: What is the underlying sentiment of this review and why? A: ANALYSIS The underlying sentiment of this review is positive because the reviewer had a great stay, enjoyed the hiking and found the food to be good.
Based on this, the overall sentiment of the message can be considered to be CLASSIFICATION positive
What is it that they liked about their stay? FURTHER_ANALYSIS The reviewer liked the hiking in the mountains and the food. ```
如上所示,我们可以用 if 语句根据模型输出动态响应。本例中,根据评价的整体情感是 positive、neutral 还是 negative,让模型给出更细致的分析。所有中间变量,如 ANALYSIS、CLASSIFICATION 或 FURTHER_ANALYSIS,都可以视为查询的输出,交给外围的自动化系统进一步处理。
关于这类控制流引导 prompt 的更多能力,参见 Scripted Prompting。
另外可以看到,除了前面示例中的行内 where 表达式,还可以在程序末尾提供全局 where 表达式,用来声明对所有变量生效的约束。根据具体使用场景,这样可以避免重复书写相同的约束——比如本例中的 FURTHER_ANALYSIS。