使用大型语言模型 (LLM)#
引言#
虽然 Colang 核心不需要大型语言模型 (LLM) 作为后端,但 Colang 标准库 (CSL) 中的许多更高级机制都依赖于它。
要启用 LLM 后端,首先需要在 config.yml 中配置 LLM 访问,通过添加如下所示的 models 部分来实现
models:
- type: main
engine: openai
model: gpt-4-turbo
确保也定义所需的 API 访问密钥,例如对于 OpenAI,您需要设置 OPENAI_API_KEY
环境变量。
每个 LLM prompt 都包含一个默认上下文,必要时可以修改以适应特定的用例。请参阅此示例配置以开始。这将极大地影响所有 LLM 调用。
支持的模型#
Colang 目前开箱即用支持以下模型
engine: openai
model: gpt-3.5-turbo-instruct
model: gpt-3.5-turbo
model: gpt-4-turbo
model: gpt-4o
model: gpt-4o-mini
NVIDIA AI Foundary 托管的 NIMs
engine: nim
model: meta/llama3-8b-instruct
model: meta/llama3-70b-instruct
model: meta/llama-3.1-8b-instruct
model: meta/llama-3.1-70b-instruct
要支持其他模型,您需要创建一组新的模板 prompts,这些 prompts 需要考虑模型的特定能力和 API,并将它们添加到您的 bot 配置中。
自然语言描述 (NLD)#
Colang 中主要的 LLM 生成机制之一是所谓的自然语言描述 (NLD),它与“生成”运算符 ...
结合使用。
# Assign result of NLD to a variable
$world_population = ..."What is the number of people in the world? Give me a number."
# Extract a value from the current interaction context
$user_name = ..."What is the name of the user? Return 'friend' if not available."
# Extract structured information from the current interaction context
$order_information = ..."Provide the products ordered by the user in a list structure, e.g. ['product a', 'product b']"
# Use an existing variable in NLD
$response_to_user = ..."Provide a brief summary of the current order. Order Information: '{$order_information}'"
每个 NLD 将在运行时由配置的 LLM 后端解释和替换,并可用于 Colang 中生成上下文相关的值。使用 NLDs,您可以从与用户的对话中或基于其他来源(如数据库或外部服务)的结果中提取值并总结内容。
注意
NLD 与变量名一起由 LLM 直接解释。根据您使用的 LLM,您需要确保非常具体地说明您希望生成什么值。好的做法是始终清楚地指定您希望响应的格式和类型(例如,$user_name = ..."Return the user name as single string between quotes''. If no user name is available return 'friend'"
)。
另外,您也可以在 flow 的开头使用类似 docstring 的 NLD 来描述 flow 的目的和功能。在 flow 中使用独立的生成运算符 ...
将利用 flow 的 NLD 自动推断正确的 flow 扩展。
flow main
"""You are an assistant that should talk to the user about cars.
Politely decline to talk about anything else.
Last user question is: "{{ question }}"
Generate the output in the following format:
bot say "<<the response>>"
"""
$question = await user said something
...
有关其工作原理的更多详细信息,请参阅LLM Flows 中的示例。
请注意,对 NLD 响应格式没有明确的控制,有时它会无法生成预期的结果。通常,您可以通过在 NLD 中提供更明确的指令来改进它,例如“用一个包含在引号中的短句欢迎用户,像这样:‘嗨!’”。另一种方法是使用例如 is_str()
函数检查返回值,以确保其格式符合预期。
用户意图匹配#
在定义 Flows 一节中,我们已经了解了如何定义用户意图 flows。其局限性在于它们无法泛化到给定用户意图示例的变体。借助 LLM 的帮助,我们可以克服这个问题并利用其推理能力,通过导入 llm 标准库模块并激活 flows automating intent detection
和 generating user intent for unhandled user utterance
(Github 链接),将意外的用户话语匹配到当前活动的用户意图 flows。
import core
import llm
flow main
activate automating intent detection
activate generating user intent for unhandled user utterance
while True
when user greeted
bot say "Hi there!"
or when user said goodbye
bot say "Goodbye!"
or when unhandled user intent # For any user utterance that does not match
bot say "Thanks for sharing!"
flow user greeted
user said "Hi" or user said "Hello"
flow user said goodbye
user said "Bye" or user said "See you"
运行此示例时
> Hi
Hi there!
> hi
Hi there!
> hallo
Hi there!
> How are you?
Thanks for sharing!
> bye bye
Goodbye!
您可以看到,如果我们有完全匹配的内容,例如“Hi”,LLM 将不会被调用,因为它直接匹配了其中一个等待的 user said
flows。对于任何其他用户话语,激活的 flow generating user intent for unhandled user utterance
将调用 LLM,然后再找到合适的用户意图。如果用户话语与预定义的用户意图 flows(即 user greeted
或 user said goodbye
)足够接近,将导致相关的 flow 成功完成。这使您甚至可以使用不同的语言(如果 LLM 支持)来成功映射到正确的 flow。如果没有找到好的匹配项,则 unhandled user intent
flow 将匹配。
您可能会问自己 LLM 如何知道哪些 flows 被视为用户意图 flows。这可以通过激活 flow automating intent detection
根据 flow 名称自动检测以“user”开头的 flows 来实现,或者使用显式的 flow decorator 来标记它们,使其独立于名称。
@meta(user_intent=True)
flow any fancy flow name
user said "Hi" or user said "Hello"
注意
从语义角度来看,即使通过用户意图 meta decorator 标记,以“user”开头用户意图 flow 也是有意义的。
Bot Action 生成#
与我们希望能够处理用户输入的变化类似,我们已经看到了定义预定义 bot actions 变体的 bot intent flows。虽然这对于响应预期用户输入来说已经足够好,但我们也希望能够处理意外的用户话语,并且不总是回复“Thanks for sharing!”。对于这种情况,标准库中的另一个 flow 可以帮助我们,名为 llm continue interaction
。
import core
import llm
flow main
user said something
llm continue interaction
> Hello
Hi there! How can I help you today?
> Tell me a funny story
Sure! Did you hear about the fire at the circus? It was intense!
> funny!
I'm glad you liked it! Do you want to hear another one?
> Bye
Bye! Have a great day!
您可以看到,通过这个,bot 可以对任何用户输入做出反应并给出合适的 bot 回答。这很好地泛化到多模态交互,如果提供合适的 prompting 上下文,也可用于生成 bot 姿态和 bot 手势。
注意
生成的 actions 很大程度上取决于当前的交互上下文、config.yml 中的通用 prompt 指令以及示例对话。尝试更新它们以达到预期的结果。
基本交互循环#
现在我们可以将所有这些组合成一个基本的交互循环
import core
import timing
import llm
flow main
activate automating intent detection
activate generating user intent for unhandled user utterance
while True
when unhandled user intent
llm continue interaction
or when user was silent 12.0
$response = ..."A random fun fact"
bot say $response
or when user expressed greeting
bot say "Hi there!"
or when user expressed goodbye
bot inform "That was fun. Goodbye"
flow user expressed greeting
user said "hi"
or user said "hello"
flow user expressed goodbye
user said "goodbye"
or user said "I am done"
or user said "I have to go"
这个循环将负责尽可能地将用户话语与预定义的用户意图匹配(例如 user expressed greeting
或 user expressed goodbye
),或者使用 flow llm continue interaction
对意外的用户意图生成合适的响应。此外,如果用户超过 12 秒没有说话,bot 将通过 NLD 生成一个随机的趣事并说出来。
实施 Guardrails#
查看入门部分中的示例,或参考NeMo Guardrails 文档,了解如何使用 Colang 对 LLM 响应和用户输入实施 guardrails。