第 21 期 | 外部 API 集成:使用 OpenAPI 查询天气与汇率

⏱ 预计阅读 20 分钟 更新于 2026/5/7
💡 进群学习加 wx: agentupdate
(申请发送: agentupdate)

🎯 本期学习目标

嘿,各位未来的 AI 大师们!欢迎来到《LangChain 全栈大师课》的第五站。前几期我们已经对 LangChain 有了初步的认识,但要真正让你的智能客服活起来,我们必须深入它的“大脑”——那些强大到令人惊叹的大语言模型(LLM)。本期,我们将告别黑盒,彻底掌握 LangChain 如何与这些模型高效、优雅地对话。

学完本期,你将:

  1. 透彻理解 LangChain 中 LLMChatModel 的核心区别与最佳应用场景,不再混淆,精准选择。
  2. 掌握如何在 LangChain 中配置、调用主流大语言模型(如 OpenAI 的 GPT 系列),为你的智能客服注入强大的语言理解和生成能力。
  3. 学会通过 LangChain 的统一接口,灵活切换不同的大模型提供商,让你的应用拥有更高的可移植性和弹性。
  4. 洞察模型参数(如 temperaturemax_tokens)对生成结果的关键影响,成为一名真正的模型调优师。

📖 原理解析

好了,伙计们,系好安全带!我们要进入 LangChain 的“发动机舱”了。

想象一下,你是个顶级厨师,而大语言模型(LLM)就是你厨房里的各种先进设备:有能烤面包的烤箱,有能切菜的料理机,还有能调味的高精度电子秤。这些设备功能强大,但它们的说明书、操作界面、电源插座可能都不一样。直接操作,你得学一堆不同的接口和协议,这多麻烦!

LangChain 的 LLMChatModel 就是你的“通用操作面板”或者“智能中央控制器”。它们提供了一套标准化的接口,让你无论面对哪个品牌的烤箱(OpenAI)、料理机(Anthropic)还是电子秤(Hugging Face),都能用一套统一的指令来操作。

LLM vs. ChatModel:不仅仅是名称不同

  • BaseLLM (文本补全模型)

    • 核心功能:接收一段文本(string),然后返回一段补全的文本(string)。
    • 工作模式:它更像是你在一个文本框里写了一半话,然后模型帮你把剩下的内容“预测”出来、补全。
    • 典型场景:早期的大模型(如 GPT-3 的 text-davinci-003)主要就是这种模式。适用于简单的文本生成、摘要、翻译等,不涉及多轮对话或角色扮演。
    • 客服项目中的应用:如果你只是想让客服小助手对用户的一句话进行快速总结,或者从一段文本中提取关键词,LLM 就能胜任。
  • BaseChatModel (聊天模型)

    • 核心功能:接收一个消息列表List[BaseMessage]),然后返回一个消息对象BaseMessage)。
    • 工作模式:这是现代大模型(如 GPT-3.5-turbo, GPT-4, Claude)的主流接口。它更理解“对话”的概念,能区分系统指令(SystemMessage)、用户提问(HumanMessage)和 AI 回复(AIMessage)。这使得模型能够更好地理解上下文,进行多轮对话,并扮演特定角色。
    • 典型场景:几乎所有需要“智能对话”的场景。多轮问答、角色扮演、内容创作、代码生成等。
    • 客服项目中的应用:这才是我们智能客服小助手的大脑核心!它能记住之前的对话,理解用户意图,扮演“专业客服”角色,并根据系统给定的知识库信息进行回复。

为什么 ChatModel 越来越重要?

因为现代大模型的设计哲学变了。它们不再仅仅是“文本补全器”,而是“对话引擎”。通过明确的 SystemMessage,我们可以给模型设定“人格”和“行为准则”,比如“你是一个友善且专业的客服,请用中文简洁回答。”这对于我们的智能客服来说,是实现个性化、专业化服务的基石。

LangChain 的抽象层级

LangChain 的设计哲学就是“抽象化”。它将不同提供商(OpenAI, Anthropic, Hugging Face 等)和不同模型类型(LLM, ChatModel)的复杂性封装起来,暴露一个统一的接口。

graph TD
    subgraph LangChain 统一接口
        A[调用 LangChain LLM/ChatModel] --> B{选择模型接口}
    end

    B -- LLM 类型 --> C[BaseLLM 接口]
    B -- ChatModel 类型 --> D[BaseChatModel 接口]

    C --> C1(OpenAI LLM)
    C --> C2(HuggingFace LLM)
    C --> C3(Google Palm LLM)

    D --> D1(ChatOpenAI)
    D --> D2(ChatAnthropic)
    D --> D3(ChatGoogleGenerativeAI)
    D --> D4(ChatHuggingFace)

    subgraph 外部大模型服务
        C1 --> E1(OpenAI API)
        C2 --> E2(HuggingFace Transformers)
        C3 --> E3(Google Palm API)

        D1 --> E1
        D2 --> E4(Anthropic API)
        D3 --> E5(Google Generative AI API)
        D4 --> E2
    end

    E1 -- 文本/消息 --> F[大模型响应]
    E2 -- 文本/消息 --> F
    E3 -- 文本/消息 --> F
    E4 -- 文本/消息 --> F
    E5 -- 文本/消息 --> F

    F --> A

图解:LangChain LLM/ChatModel 抽象层

这张图清晰地展示了 LangChain 如何在你的应用和各种大模型之间搭建了一座桥梁。你只需要和 LangChain 的 BaseLLMBaseChatModel 接口打交道,至于底层是 OpenAI 还是 Anthropic,LangChain 会帮你处理好一切。这极大地降低了开发难度,并提升了应用的可扩展性。

💻 实战代码演练 (客服项目中的具体应用)

好了,理论说完了,是时候撸起袖子,让我们的智能客服小助手真正开口说话了!

首先,确保你的环境已经安装了必要的库。我们以 OpenAI 为例,因为它目前依然是业界标杆。

pip install langchain langchain-openai python-dotenv
# 或者对于 TypeScript/JavaScript
# npm install langchain @langchain/openai dotenv

别忘了设置你的 API 密钥。最安全的方式是使用环境变量。创建一个 .env 文件,内容如下:

OPENAI_API_KEY="sk-YOUR_OPENAI_API_KEY_HERE"

然后,在你的代码中加载它。

1. 使用 ChatModel (Python)

我们直接从 ChatModel 开始,因为它更强大,也更符合现代大模型的应用场景。我们的智能客服小助手就是基于 ChatModel 来进行多轮对话和角色扮演的。

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage

# 1. 加载环境变量
load_dotenv()

# 确保 OPENAI_API_KEY 已设置
if not os.getenv("OPENAI_API_KEY"):
    raise ValueError("OPENAI_API_KEY 环境变量未设置。请在 .env 文件中配置。")

print("--- LangChain ChatModel 实战:智能客服小助手初体验 ---")

# 2. 初始化 ChatModel
# model_name 可以是 "gpt-3.5-turbo", "gpt-4", "gpt-4o" 等
# temperature 控制生成文本的随机性。0.0 表示确定性最高,1.0 表示创造性最高。
# 对于客服场景,我们通常希望回复准确、一致,所以温度会设置得较低。
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.2)

# 3. 模拟客服对话:单轮提问
print("\n--- 场景一:客服小助手处理单轮用户提问 ---")
user_query_1 = "我的鼠标突然不动了,应该怎么排查?"
messages_1 = [
    SystemMessage(content="你是一个专业的电脑硬件客服助手,请提供简洁有效的排查步骤。"), # 设定系统角色和指令
    HumanMessage(content=user_query_1) # 用户提问
]

print(f"用户提问: {user_query_1}")
response_1 = chat_model.invoke(messages_1)
print(f"客服小助手回复: {response_1.content}")
# 预期输出可能包含:检查连接、更换电池、重启电脑、更新驱动等。

# 4. 模拟客服对话:多轮追问 (ChatModel 的强大之处)
print("\n--- 场景二:客服小助手进行多轮对话 ---")
user_query_2_part1 = "我按照你的方法试了,还是不行,是不是鼠标坏了?"
messages_2 = [
    SystemMessage(content="你是一个专业的电脑硬件客服助手,请提供简洁有效的排查步骤。"),
    HumanMessage(content=user_query_1), # 第一次用户提问
    AIMessage(content=response_1.content), # 小助手第一次回复
    HumanMessage(content=user_query_2_part1) # 用户追问
]

print(f"用户追问: {user_query_2_part1}")
response_2 = chat_model.invoke(messages_2)
print(f"客服小助手回复: {response_2.content}")
# 预期输出会基于之前的对话上下文,更深入地排查或建议送修。

# 5. 探索模型参数:temperature 的影响
print("\n--- 场景三:调整 temperature 观察模型回复风格 ---")
# 降低温度,让回答更严谨、事实性强
chat_model_strict = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.0)
messages_strict = [
    SystemMessage(content="你是一个严谨的科学研究员,请客观描述地球是圆的还是平的。"),
    HumanMessage(content="地球是什么形状?")
]
response_strict = chat_model_strict.invoke(messages_strict)
print(f"严谨模式 (temperature=0.0): {response_strict.content}")

# 提高温度,让回答更具创造性、发散性
chat_model_creative = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.8)
messages_creative = [
    SystemMessage(content="你是一个充满想象力的诗人,请用诗歌描述地球的形状。"),
    HumanMessage(content="地球是什么形状?")
]
response_creative = chat_model_creative.invoke(messages_creative)
print(f"创意模式 (temperature=0.8): {response_creative.content}")

print("\n--- 恭喜,你已初步掌握 LangChain ChatModel 的核心用法! ---")

1. 使用 ChatModel (TypeScript)

import { config } from 'dotenv';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage, SystemMessage, AIMessage } from '@langchain/core/messages';

// 1. 加载环境变量
config();

// 确保 OPENAI_API_KEY 已设置
if (!process.env.OPENAI_API_KEY) {
  throw new Error("OPENAI_API_KEY 环境变量未设置。请在 .env 文件中配置。");
}

console.log("--- LangChain ChatModel 实战:智能客服小助手初体验 ---");

async function runChatModelDemo() {
  // 2. 初始化 ChatModel
  // modelName 可以是 "gpt-3.5-turbo", "gpt-4", "gpt-4o" 等
  // temperature 控制生成文本的随机性。0.0 表示确定性最高,1.0 表示创造性最高。
  // 对于客服场景,我们通常希望回复准确、一致,所以温度会设置得较低。
  const chatModel = new ChatOpenAI({
    modelName: "gpt-3.5-turbo",
    temperature: 0.2,
  });

  // 3. 模拟客服对话:单轮提问
  console.log("\n--- 场景一:客服小助手处理单轮用户提问 ---");
  const userQuery1 = "我的鼠标突然不动了,应该怎么排查?";
  const messages1 = [
    new SystemMessage("你是一个专业的电脑硬件客服助手,请提供简洁有效的排查步骤。"), // 设定系统角色和指令
    new HumanMessage(userQuery1) // 用户提问
  ];

  console.log(`用户提问: ${userQuery1}`);
  const response1 = await chatModel.invoke(messages1);
  console.log(`客服小助手回复: ${response1.content}`);
  // 预期输出可能包含:检查连接、更换电池、重启电脑、更新驱动等。

  // 4. 模拟客服对话:多轮追问 (ChatModel 的强大之处)
  console.log("\n--- 场景二:客服小助手进行多轮对话 ---");
  const userQuery2Part1 = "我按照你的方法试了,还是不行,是不是鼠标坏了?";
  const messages2 = [
    new SystemMessage("你是一个专业的电脑硬件客服助手,请提供简洁有效的排查步骤。"),
    new HumanMessage(userQuery1), // 第一次用户提问
    new AIMessage(response1.content as string), // 小助手第一次回复
    new HumanMessage(userQuery2Part1) // 用户追问
  ];

  console.log(`用户追问: ${userQuery2Part1}`);
  const response2 = await chatModel.invoke(messages2);
  console.log(`客服小助手回复: ${response2.content}`);
  // 预期输出会基于之前的对话上下文,更深入地排查或建议送修。

  // 5. 探索模型参数:temperature 的影响
  console.log("\n--- 场景三:调整 temperature 观察模型回复风格 ---");
  // 降低温度,让回答更严谨、事实性强
  const chatModelStrict = new ChatOpenAI({ modelName: "gpt-3.5-turbo", temperature: 0.0 });
  const messagesStrict = [
    new SystemMessage("你是一个严谨的科学研究员,请客观描述地球是圆的还是平的。"),
    new HumanMessage("地球是什么形状?")
  ];
  const responseStrict = await chatModelStrict.invoke(messagesStrict);
  console.log(`严谨模式 (temperature=0.0): ${responseStrict.content}`);

  // 提高温度,让回答更具创造性、发散性
  const chatModelCreative = new ChatOpenAI({ modelName: "gpt-3.5-turbo", temperature: 0.8 });
  const messagesCreative = [
    new SystemMessage("你是一个充满想象力的诗人,请用诗歌描述地球的形状。"),
    new HumanMessage("地球是什么形状?")
  ];
  const responseCreative = await chatModelCreative.invoke(messagesCreative);
  console.log(`创意模式 (temperature=0.8): ${responseCreative.content}`);

  console.log("\n--- 恭喜,你已初步掌握 LangChain ChatModel 的核心用法! ---");
}

runChatModelDemo();

2. 使用 LLM (Python - 了解即可,ChatModel 更常用)

虽然 ChatModel 更推荐,但为了完整性,我们快速看一下 LLM 的用法。

import os
from dotenv import load_dotenv
from langchain_openai import OpenAI # 注意这里是 OpenAI 而不是 ChatOpenAI

load_dotenv()

if not os.getenv("OPENAI_API_KEY"):
    raise ValueError("OPENAI_API_KEY 环境变量未设置。请在 .env 文件中配置。")

print("\n--- LangChain LLM 实战:简单文本补全 ---")

# 初始化 LLM 模型 (通常使用较旧的模型或者特定场景)
# 注意:OpenAI 官方也推荐使用 gpt-3.5-turbo 等 ChatModel 来进行文本补全
# 此处为了演示 LLM 类,我们使用 text-davinci-003(如果可用,但通常会提示废弃)
# 或者可以直接用 ChatOpenAI,但传入的不是消息列表,而是字符串。
# 为了避免混淆,我们这里直接用 ChatOpenAI 但只传入单字符串。
# 如果你真的需要旧的 LLM 接口,可能需要降级 langchain-openai 版本或使用其他提供商。
# 这里我们用 ChatOpenAI 来模拟 LLM 的文本补全行为,因为更现代。
llm_model_as_chat = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.7)

prompt = "请用一句话总结智能客服知识库的核心价值:"
print(f"输入文本: {prompt}")
response_llm = llm_model_as_chat.invoke(prompt) # 直接传入字符串
print(f"LLM 风格回复: {response_llm.content}")
# 预期输出:智能客服知识库通过集中管理信息,快速响应用户查询,提升服务效率和用户满意度。

print("\n--- LLM 风格演示结束 ---")

2. 使用 LLM (TypeScript - 了解即可,ChatModel 更常用)

import { config } from 'dotenv';
import { OpenAI } from '@langchain/openai'; // 注意这里是 OpenAI 而不是 ChatOpenAI
import { ChatOpenAI } from '@langchain/openai'; // 引入 ChatOpenAI 用于模拟

config();

if (!process.env.OPENAI_API_KEY) {
  throw new Error("OPENAI_API_KEY 环境变量未设置。请在 .env 文件中配置。");
}

console.log("\n--- LangChain LLM 实战:简单文本补全 ---");

async function runLLMDemo() {
  // 初始化 LLM 模型 (通常使用较旧的模型或者特定场景)
  // 注意:OpenAI 官方也推荐使用 gpt-3.5-turbo 等 ChatModel 来进行文本补全
  // 此处为了演示 LLM 类,我们使用 text-davinci-003(如果可用,但通常会提示废弃)
  // 或者可以直接用 ChatOpenAI,但传入的不是消息列表,而是字符串。
  // 为了避免混淆,我们这里直接用 ChatOpenAI 来模拟 LLM 的文本补全行为,因为更现代。
  const llmModelAsChat = new ChatOpenAI({ modelName: "gpt-3.5-turbo", temperature: 0.7 });

  const prompt = "请用一句话总结智能客服知识库的核心价值:";
  console.log(`输入文本: ${prompt}`);
  const responseLlm = await llmModelAsChat.invoke(prompt); // 直接传入字符串
  console.log(`LLM 风格回复: ${responseLlm.content}`);
  // 预期输出:智能客服知识库通过集中管理信息,快速响应用户查询,提升服务效率和用户满意度。

  console.log("\n--- LLM 风格演示结束 ---");
}

runLLMDemo();

通过这些代码,你现在应该对 LangChain 如何与大模型交互有了清晰的认识。对于我们的智能客服小助手项目,ChatModel 将是我们的主力军,因为它能更好地处理对话上下文和角色扮演。

坑与避坑指南

作为一名资深 AI 架构师,我见过无数新手在这里踩坑。别担心,我已经帮你把路上的“地雷”都标记出来了。

  1. API Key 管理:头号大忌!

    • :直接把 OPENAI_API_KEY 硬编码在代码里,或者上传到 Git 仓库。这简直是在裸奔,分分钟被盗用,然后你的信用卡账单就爆炸了!
    • 避坑永远使用环境变量! .env 文件配合 dotenv 库是最佳实践。在生产环境中,使用云服务商提供的密钥管理服务(如 AWS Secrets Manager, Azure Key Vault, Google Secret Manager)。
  2. LLM vs. ChatModel 的选择困境

    • :纠结到底用哪个?或者为了旧习惯,非要用 LLM 去处理多轮对话。
    • 避坑优先使用 ChatModel 除非你有非常明确的理由(比如对接只能接受纯文本的旧模型),否则现代大模型(尤其是基于 Transformer 架构的)都是为对话而生。ChatModel 通过 SystemMessage 赋予模型“人格”,通过 HumanMessage/AIMessage 维护上下文,这才是发挥大模型潜力的正确姿势。你的智能客服小助手,99% 的场景都会用到 ChatModel
  3. 模型参数 temperature 的玄学

    • :不理解 temperature 的作用,随便设置一个值,导致模型回复要么过于死板,要么胡言乱语。
    • 避坑
      • temperature 接近 0.0:适用于需要准确、事实性、确定性高的场景。例如:从知识库中提取信息、总结报告、代码生成。客服小助手在提供解决方案或信息时,通常会倾向于低 temperature,以减少幻觉和不确定性。
      • temperature 接近 1.0:适用于需要创造性、发散性、新颖性高的场景。例如:写诗、头脑风暴、故事创作。
      • 经验法则:对于客服应用,temperature 通常设置在 0.00.5 之间。你可以根据实际测试效果微调。
  4. Token 限制与成本意识

    • :不了解大模型的 Token 限制,一股脑把所有历史对话和知识库内容都塞进去,结果不是报错就是天价账单。
    • 避坑
      • 每个模型都有其上下文窗口限制(例如 GPT-3.5-turbo 可能是 4K, 16K,GPT-4 可能更大)。超出限制会导致模型截断输入或报错。
      • Token 消耗直接影响成本。每次 API 调用都会根据输入和输出的 Token 数量计费。
      • 策略:对于客服小助手,我们需要智能地管理对话历史(例如,只保留最近几轮对话),并在必要时对知识库内容进行摘要或检索(这会是后续 RAG 章节的重点!)。
  5. 错误处理与重试

    • :不处理网络错误、API 限流等问题,导致应用崩溃或用户体验差。
    • 避坑:LangChain 内部对一些常见的 API 错误有重试机制,但你仍然需要考虑更全面的错误捕获和用户友好提示。例如,当模型返回空内容时,你的客服小助手应该能说一句“抱歉,我暂时无法回答这个问题,请您换个方式提问。”而不是直接报错。

📝 本期小结

恭喜你!本期我们深入探索了 LangChain 与大语言模型交互的核心基石:LLMChatModel。你现在不仅理解了它们之间的区别,更掌握了如何在智能客服项目中灵活运用 ChatModel 来驱动对话和角色扮演。

我们还一起排查了模型参数 temperature 的奥秘,并学习了如何避开常见的“地雷”,如 API Key 管理、Token 限制和模型选择。记住,对于你的智能客服小助手,ChatModel 配合低 temperature 将是你的黄金组合。

这些知识是构建任何 LangChain 应用的基石。在接下来的课程中,我们将在此基础上,为我们的智能客服小助手添加记忆、工具调用等更高级的能力,让它真正成为一个全能的 AI 助手!

准备好了吗?下一站,我们去探索如何让模型“记住”之前的对话,也就是——记忆(Memory)!那将是你的客服小助手从“傻瓜”到“聪明”的关键一步!