在大型语言模型 (LLM) 的领域中,”对话模型” (Chat Models) 和 “非对话模型” (或称为 “文本模型” Text Models) 是两种基本但又有所区别的模型范式,它们在设计、训练数据、输入/输出格式以及最佳应用场景上存在差异。理解这两种模型的区别是有效利用 LLM 进行开发的关键。

核心思想:对话模型优化用于多轮、上下文感知的交互,通过消息列表进行输入输出;非对话模型则擅长单次、直接的文本指令处理,通过字符串进行输入输出。


一、非对话模型 (Text Models / LLMs)

非对话模型是早期和传统的大型语言模型形式,它们通常设计为接收一个单一的字符串作为输入(通常称为 “prompt”),并生成一个单一的字符串作为输出。虽然这些模型也能在一定程度上处理对话,但通常需要通过在单次 Prompt 中手动构建对话历史来模拟。

1.1 特点

  1. 字符串输入/输出:输入是一个字符串,输出也是一个字符串。
    • 输入示例"把以下文本总结一下:[文本内容]"
    • 输出示例"这是一段总结后的文本。"
  2. 无内置上下文管理:模型本身不维护对话历史或上下文。如果需要模拟对话,用户必须通过将此前的对话轮次拼接成一个更长的 Prompt 来实现。
    1
    Prompt = "用户:你好!\nAI:你好!有什么可以帮助你的吗?\n用户:我想问一个关于AI的问题。\nAI:"
  3. 单次请求:每个请求通常被视为一个独立的任务,模型生成响应后即完成。
  4. 通常更早出现:许多经典的基础模型(如最初的 GPT 系列、text-davinci-003)都属于此类。
  5. Token 成本: 由于每次都需要将完整的对话历史作为 Prompt 输入,对于长对话,Token 消耗会迅速增加。

1.2 优点

  • 简单直观:对于单次任务或简单的问答,用法非常直接。
  • 灵活性:Prompt 的结构相对自由,可以通过各种技巧(如 Few-Shot Prompting)在单个 Prompt 中实现复杂指令。
  • 广谱性:适用于各种文本生成任务,如摘要、翻译、代码生成、创意写作等。

1.3 缺点

  • 复杂的对话管理:处理多轮对话时,需要额外的逻辑代码来管理和拼接对话历史,容易出错。
  • 上下文限制:随着对话轮次的增加,Prompt 会变得很长,容易超出模型的最大 Token 限制。
  • 性能下降:长 Prompt 会增加推理时间。

1.4 适用场景

  • 文本总结与提取:对给定文章进行摘要或提取关键信息。
  • 翻译:从一种语言翻译到另一种语言。
  • 文本补全:根据前缀推断并生成后续文本。
  • 代码生成:根据描述生成代码片段。
  • 内容创作:撰写文章、邮件、营销文案等。
  • 一次性问答:不涉及上下文的独立问题回复。

1.5 示例 (使用 LangChain 的 LLM 接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from langchain_openai import OpenAI

# 假设 OPENAI_API_KEY 已设置在环境变量中
llm = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.7)

# 单次调用
prompt_text = "写一个关于太空旅行的短诗。"
response = llm.invoke(prompt_text)
print("非对话模型响应:\n", response)

print("-" * 30)

# 模拟对话 (需要手动拼接上下文,可能效果不佳)
dialog_history = "用户:你好!\nAI:你好!请问有什么可以帮助你的吗?\n用户:写一个关于机器学习的简要定义。\nAI:"
simulated_response = llm.invoke(dialog_history)
print("非对话模型模拟对话响应:\n", simulated_response)

二、对话模型 (Chat Models)

对话模型是专门为处理多轮、上下文感知的对话而设计和优化的语言模型。它们不简单地接收一个字符串,而是接收一个消息列表(List of Messages),并且返回一个消息对象。这些消息通常带有明确的角色(如 SystemHumanAI)。

2.1 特点

  1. 消息列表输入/输出:输入是消息对象列表,输出是单个消息对象。
    • 消息类型SystemMessage (系统指令)、HumanMessage (用户输入)、AIMessage (AI 回复)、FunctionMessage (ToolMessage) 等。
    • 输入示例
      1
      2
      3
      4
      5
      6
      [
      SystemMessage(content="你是一个乐于助人的助手。"),
      HumanMessage(content="你好!"),
      AIMessage(content="你好!有什么可以帮助你的吗?"),
      HumanMessage(content="我想了解一下量子物理。")
      ]
    • 输出示例AIMessage(content="量子物理是...", role='assistant')
  2. 内置上下文管理优化:模型底层通常有更好的机制来理解和维护对话上下文,即便在长对话中也能保持一致性。它们在训练过程中被明确地指示如何处理交替的消息序列。
  3. 角色感知:通过明确的消息角色,模型能够更好地理解其在对话中的定位以及用户和系统指令的意图。
  4. 更高的 Token 效率:由于模型被优化来理解消息边界和角色,有时在处理对话时可以比文本模型更有效地利用 Token。
  5. 通常更现代:OpenAI 的 gpt-3.5-turbo, gpt-4 和 Google 的 Gemini 系列等更先进的模型多为对话模型。

2.2 优点

  • 优化的对话体验:更自然、更流畅地处理多轮对话,更好地理解指代和上下文。
  • 简化对话管理:开发者无需手动拼接整个对话历史,只需传递消息列表。
  • 更强大的指令遵循能力:通过 SystemMessage 能更好地控制模型的行为和人格。
  • 支持函数调用 (Function Calling/Tool Use):许多对话模型扩展了功能,可以直接理解并调用外部工具,进一步增强其能力。

2.3 缺点

  • 输入格式更严格:必须以消息列表的形式提供输入,不能直接传递纯字符串。
  • 对于简单任务可能过于复杂:如果只是想进行一次性的摘要或转换,使用对话模型可能需要额外的格式转换。

2.4 适用场景

  • 聊天机器人:构建客服机器人、个人助理或其他交互式对话系统。
  • 多轮问答系统:需要记忆和理解之前问题的上下文。
  • 智能助手:需要模仿人类对话、情感理解和复杂指令处理的场景。
  • Agent (代理):利用函数调用进行复杂任务分解和执行的系统。

2.5 示例 (使用 LangChain 的 ChatModel 接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage

# 假设 OPENAI_API_KEY 已设置在环境变量中
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.7)

# 构建消息列表进行对话
messages = [
SystemMessage(content="你是一个专业的烹饪助手,提供简洁美味的建议。"),
HumanMessage(content="我想做一道简单的晚餐,有什么推荐?")
]

response_chat_1 = chat_model.invoke(messages)
print("对话模型第一次响应:\n", response_chat_1.content)

print("-" * 30)

# 在上次对话的基础上继续 (添加新的 HumanMessage 和上一次的 AIMessage)
messages.append(AIMessage(content=response_chat_1.content)) # 将AI的回复加入历史
messages.append(HumanMessage(content="听起来不错!请问需要哪些主要食材?"))

response_chat_2 = chat_model.invoke(messages)
print("对话模型第二次响应:\n", response_chat_2.content)

三、比较总结

特征 非对话模型 (Text Models / LLMs) 对话模型 (Chat Models)
输入格式 单一字符串 (Prompt) 消息对象列表 (SystemMessage, HumanMessage, AIMessage 等)
输出格式 单一字符串 单一消息对象 (AIMessage)
上下文管理 需用户手动拼接 Prompt 历史 模型内部优化处理,通过消息列表自然表达
设计用途 通用文本生成、补全、摘要、翻译等单次任务 多轮对话、上下文理解、角色扮演
指令遵循 通过 Prompt 工程实现 通过 SystemMessage 和消息角色更强地引导模型行为
编程接口 llm.invoke("prompt_string") `chat_model.invoke