脚本专家 发表于 2026-6-15 10:00:02

Python通过LangChain调用LLM模型:ChatOpenAI配置与流式/非流式实践

在构建Agent应用时,最基础的一步就是通过LangChain调用大语言模型(LLM)。LangChain并非模型本身,而是一套AI应用开发框架,负责统一管理模型调用、消息组织、提示词模板、工具集成等。其中,模型入口层是核心,后续的Tool、RAG、Memory、LangGraph都围绕模型调用和消息流转展开。本文以ChatOpenAI为例,展示如何用Python通过LangChain完成一次完整的LLM调用,包括非流式与流式两种方式。

LangChain通过langchain-openai包提供对OpenAI接口格式的支持。这个包不仅支持OpenAI官方模型,也兼容DeepSeek、代理网关等第三方服务——只要它们实现了相同的请求格式。配置时只需修改base_url即可切换模型服务端。

安装依赖
推荐使用uv管理项目依赖,执行命令:

uv add langchain-openai python-dotenv

如果临时使用pip,也可以:

pip install langchain-openai python-dotenv

langchain-openai负责模型集成,python-dotenv用于从.env文件读取环境变量。

环境变量配置
以DeepSeek为例,在项目根目录创建.env文件,写入以下内容:

LLM_MODEL=deepseek-v4-pro
LLM_API_KEY=your_deepseek_api_key_here
LLM_BASE_URL=https://api.deepseek.com

说明:
- LLM_MODEL:模型名称,DeepSeek当前可用deepseek-v4-flash或deepseek-v4-pro。
- LLM_API_KEY:在DeepSeek平台申请的API Key。
- LLM_BASE_URL:接口地址,DeepSeek兼容OpenAI格式,因此填入https://api.deepseek.com。若使用OpenAI官方服务,可省略此变量或设为官方地址。

创建模型实例
编写两个辅助函数:required_env()用于校验必填环境变量,create_model()用于统一创建ChatOpenAI实例。这样能避免每个调用点重复配置,并在启动时暴露缺失的变量。

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

def required_env(name: str) -> str:
    value = os.getenv(name)
    if not value:
      raise RuntimeError(f"Missing environment variable: {name}")
    return value

def create_model() -> ChatOpenAI:
    base_url = os.getenv("LLM_BASE_URL")
    model_kwargs = {
      "model": required_env("LLM_MODEL"),
      "api_key": required_env("LLM_API_KEY"),
      "temperature": 0.2,
      "timeout": 30,
      "max_retries": 2,
    }
    if base_url:
      model_kwargs["base_url"] = base_url
    return ChatOpenAI(**model_kwargs)


非流式调用 (invoke)
invoke会等待模型完整生成所有内容后一次性返回。返回对象是AIMessage,其content属性包含回复文本。

def invoke_demo() -> None:
    model = create_model()
    response = model.invoke([
      {"role": "user", "content": "用三句话解释 LangChain 是什么。"}
    ])
    print(response.content)

注意:invoke返回的AIMessage中还有tool_calls字段,当模型需要调用工具时会存放调用意图,这在后续学习Tool时非常重要。

流式调用 (stream)
stream适合聊天界面或长文本生成的实时输出,它会将生成的内容分段(chunk)依次返回。

import sys

def stream_demo() -> None:
    model = create_model()
    stream = model.stream([
      {"role": "user", "content": "介绍一下重庆火锅文化。"}
    ])
    for chunk in stream:
      if isinstance(chunk.content, str):
            sys.stdout.write(chunk.content)
            sys.stdout.flush()
    sys.stdout.write("\n")

每个chunk是一个AIMessageChunk对象,文本内容存储在content属性中。

参数分类与说明
ChatOpenAI初始化时的参数可归为三类:
1. 连接参数:api_key(密钥,应从环境变量读取)、base_url(服务地址,可省略或自定义)、model(模型名称,建议放环境变量以便切换)。
2. 生成控制参数:temperature(控制随机性,代码/抽取类任务设低值,创意任务设高值)、max_tokens(限制输出长度)、top_p(一般先调temperature,避免同时调节两个)。
3. 请求控制参数:timeout(超时秒数,防止网络卡死)、max_retries(失败重试次数,应对临时波动)。

小结
本文核心要点:
- ChatOpenAI是LangChain的模型调用层,通过它可连接OpenAI或兼容接口的第三方服务。
- invoke用于一次性完整回复,stream用于实时流式输出。
- 参数按连接、模型选择、生成控制、请求控制四个维度理解,有助于灵活调优。

掌握这些基本操作,就打通了Agent应用开发中模型调用的入口,后续学习Tool、RAG、Memory等将更加顺畅。

热心网友7 发表于 2026-6-15 10:10:00

Re: Python通过LangChain调用LLM模型:ChatOpenAI配置与流式/非流式实践

非常感谢楼主这么详细的分享!从环境变量配置到模型实例创建,再到流式和非流式调用的代码示例,步骤非常清晰,对新手很友好。特别是把参数分成连接、生成控制和请求控制三类来讲解,让人一目了然。我最近也在尝试用LangChain对接不同的模型服务,看到您用base_url切换第三方服务的方式很实用,后续我也准备试试DeepSeek。想请教一下,在实际项目中,您通常怎么处理流式输出的chunk合并?直接拼接content会不会丢失一些中间状态信息?

热心网友7 发表于 2026-6-16 17:25:00

Re: Python通过LangChain调用LLM模型:ChatOpenAI配置与流式/非流式实践

很实用的教程!我之前一直用直接HTTP调 OpenAI,看了你这篇才意识到 LangChain 的 ChatOpenAI 封装能省这么多配置工作,特别是 `required_env` 和 `create_model` 这两个函数,统一管理密钥和模型名,项目多了切换起来方便多了。 想请教一下,流式调用里每个 chunk 只取 content 来写,但如果模型需要返回 tool_calls,会不会有特殊处理?还有,你在生产环境里会把 temperature 固定为 0.2 还是根据任务动态调整?期待后续讲 Tool 和 LangGraph 的部分。

热心网友5 发表于 2026-6-16 20:00:00

Re: Python通过LangChain调用LLM模型:ChatOpenAI配置与流式/非流式实践

很实用的一篇教程!环境变量校验和统一创建模型的思路很好,能避免重复配置和遗漏。我用LangChain时也经常在stream里直接print,你这用sys.stdout.write flush更规范。想请教下,如果模型返回的内容里有特殊字符或ASCII控制字符,在流式处理时怎么处理比较稳妥?
页: [1]
查看完整版本: Python通过LangChain调用LLM模型:ChatOpenAI配置与流式/非流式实践