LangChain入门:用Python构建LLM应用

当你第一次用 OpenAI SDK 调通一个大模型,那种“AI 真的能听懂我说话”的兴奋感会持续好几天。但兴奋过后,真正的工程问题随之而来:如何复用提示词?如何让模型记住上下文?如何让模型调用外部工具?如何把私有文档喂给模型?这些问题单靠一个 chat.completions.create 是解决不了的。

这就是 LangChain 出现的原因。它是目前最流行的 LLM 应用开发框架,把“模型调用、提示词管理、记忆、工具、检索”抽象成可组合的组件,让你像搭积木一样构建复杂的 AI 应用。本文将从零开始,带你用 Python 跑通 LangChain 的核心能力,并在最后展示如何通过 EnlyAI 统一 API 接入多种模型。

一、LangChain 是什么

LangChain 最初由 Harrison Chase 在 2022 年底开源,定位是“面向大语言模型的应用开发框架”。它的核心理念是:把 LLM 应用拆解成可组合的模块,而不是把所有逻辑塞进一个巨大的 prompt 字符串里。

LangChain 的核心模块包括:

理解这六个模块,就理解了 LangChain 的全部骨架。下面我们逐一上手。

二、环境搭建与安装

LangChain 在 0.2 版本之后做了模块化拆分,主包只包含核心抽象,具体模型的集成需要单独安装。对于大多数开发者,推荐直接安装 langchainlangchain-openai

# 安装 LangChain 核心包与 OpenAI 集成
pip install langchain langchain-openai

# 如果需要 RAG,再装向量库和文本分割器
pip install langchain-community faiss-cpu

安装完成后,建议把 API 密钥放到环境变量里,而不是硬编码在脚本中:

# Linux / macOS
export OPENAI_API_KEY="sk-your-api-key"
export OPENAI_BASE_URL="https://enlyai.com/v1"

# Windows PowerShell
# $env:OPENAI_API_KEY="sk-your-api-key"
# $env:OPENAI_BASE_URL="https://enlyai.com/v1"

提示:把 OPENAI_BASE_URL 指向 https://enlyai.com/v1,LangChain 就会通过 EnlyAI 聚合平台调用模型,一套密钥即可访问 GPT、Claude、Gemini 等数十种模型。

三、第一次调用:ChatOpenAI

LangChain 中最常用的模型类是 ChatOpenAI,它封装了 OpenAI 兼容的聊天接口。由于 EnlyAI 完全兼容 OpenAI API 格式,所以可以直接用这个类接入。

from langchain_openai import ChatOpenAI

# 通过 EnlyAI 统一接入,可随时切换底层模型
llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1",
    temperature=0.3
)

# 直接传入字符串即可调用
response = llm.invoke("用一句话解释什么是向量数据库")
print(response.content)

这里有几个关键参数需要理解:

四、提示词模板:PromptTemplate

真实应用中,提示词往往很长,而且包含动态变量。直接用 f-string 拼接会让代码很难维护。LangChain 提供了 ChatPromptTemplate 来管理提示词结构。

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一位资深 {role},请用专业但易懂的语言回答。"),
    ("user", "{question}")
])

# 渲染模板
messages = prompt.invoke({
    "role": "数据库工程师",
    "question": "为什么 PostgreSQL 比 MySQL 更适合复杂查询?"
})
print(messages)

from_messages 接收一个消息列表,每条消息是 (角色, 内容) 元组。花括号里的 {role}{question} 是变量,调用 invoke 时传入字典即可填充。

五、链(Chains):LCEL 表达式

LangChain 0.2 之后推荐使用 LCEL(LangChain Expression Language) 来构建链。它的语法非常优雅:用管道符 | 把组件串联起来,就像 Unix 管道一样。

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1"
)

prompt = ChatPromptTemplate.from_template("请把以下文本翻译成{language}:\n{text}")

# 用管道符串联:prompt -> llm -> 输出解析器
chain = prompt | llm | StrOutputParser()

result = chain.invoke({
    "language": "英文",
    "text": "大模型让软件开发变得更有趣了"
})
print(result)

这条链的执行流程是:prompt 把输入字典渲染成消息 → llm 调用模型生成回复 → StrOutputParser 把回复对象转成纯字符串。LCEL 的好处是每个组件都支持 invoke / stream / batch,切换流式输出只需把 invoke 换成 stream

# 流式输出
for chunk in chain.stream({
    "language": "日文",
    "text": "今天天气真好"
}):
    print(chunk, end="", flush=True)

六、记忆(Memory):多轮对话

LLM 本身是无状态的,每次调用都是独立的。要实现“记得上一轮说了什么”的多轮对话,需要把历史消息拼到当前请求里。LangChain 提供了 ChatMessageHistory 来管理对话历史。

from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1"
)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个友好的助手,记住之前的对话内容。"),
    "placeholder",   # 这里会自动插入历史消息
    ("user", "{input}")
])

chain = prompt | llm

# 用 session_id 区分不同用户的会话
store = {}
def get_history(session_id):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

chain_with_history = RunnableWithMessageHistory(
    chain, get_history,
    input_messages_key="input",
    history_factory_config=[]
)

# 第一轮
r1 = chain_with_history.invoke(
    {"input": "我叫小明,今年 28 岁"},
    config={"configurable": {"session_id": "user-1"}}
)
print(r1.content)

# 第二轮,模型能记住上一轮的信息
r2 = chain_with_history.invoke(
    {"input": "我刚才告诉你我叫什么?"},
    config={"configurable": {"session_id": "user-1"}}
)
print(r2.content)  # 会回答"小明"

生产环境中,建议把 InMemoryChatMessageHistory 换成 Redis 或数据库实现,避免服务重启后丢失历史。

七、RAG:让模型读懂你的私有文档

RAG(Retrieval-Augmented Generation,检索增强生成)是 LangChain 最热门的应用场景。它的思路是:先从知识库中检索出与问题相关的文档片段,再把这些片段塞进 prompt,让模型基于文档回答。这样既能让模型“知道”私有知识,又能避免幻觉。

一个最小可用的 RAG 流程如下:

from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 准备文档
docs_text = """
EnlyAI 是一个 LLM API 聚合平台,支持 OpenAI、Claude、Gemini 等多种模型。
API base URL 是 https://enlyai.com/v1,完全兼容 OpenAI API 格式。
新用户注册即送免费额度,可以在控制台查看用量和账单。
"""

# 2. 切分文档
splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
chunks = splitter.create_documents([docs_text])

# 3. 生成嵌入并存入向量库
embeddings = OpenAIEmbeddings(
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1"
)
vectorstore = FAISS.from_documents(chunks, embeddings)

# 4. 构建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

# 5. 检索 + 生成
llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1"
)

prompt = ChatPromptTemplate.from_template("""
根据以下资料回答问题。如果资料里没有答案,请说"我不知道"。

资料:
{context}

问题:{question}
""")

from langchain_core.runnables import RunnablePassthrough

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt | llm | StrOutputParser()
)

answer = rag_chain.invoke("EnlyAI 的 API 地址是什么?")
print(answer)  # 会回答 https://enlyai.com/v1

这段代码完成了“切分 → 嵌入 → 存储 → 检索 → 生成”的完整闭环。实际项目中,你只需要把 docs_text 换成从 PDF、网页或数据库加载的真实文档即可。

八、Agent:让模型自主调用工具

前面所有例子都是“固定流程”:输入 → 处理 → 输出。但有些任务需要模型自主决策——比如“查一下北京明天天气,然后写一首诗”,模型需要先调用天气工具,拿到结果后再写诗。这就是 Agent 的用武之地。

from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate

# 定义一个工具:计算器
@tool
def calculate(expression: str) -> str:
    """计算一个数学表达式并返回结果。输入应为合法的 Python 表达式,例如 '12 * 8 + 5'。"""
    return str(eval(expression))

llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="sk-your-api-key",
    base_url="https://enlyai.com/v1"
)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个能调用工具的助手。"),
    ("user", "{input}"),
    ("placeholder", "{agent_scratchpad}")
])

tools = [calculate]
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

result = executor.invoke({"input": "帮我算一下 (123 + 456) * 2 等于多少"})
print(result["output"])

运行后你会看到模型先调用 calculate 工具,拿到 1158,再组织成自然语言回复。Agent 的强大之处在于:你只需要定义工具,模型会自己决定什么时候用、怎么用。

九、用 EnlyAI 统一接入多模型

前面所有代码都用了 gpt-4o-mini。但真实业务中,你可能需要在不同模型间切换:用 GPT-4o 做复杂推理,用 Claude 写文案,用 Gemini 处理长文档。如果每个模型都单独对接,密钥管理、计费、SDK 切换会非常麻烦。

EnlyAI 提供了统一 API 接口,完全兼容 OpenAI 格式。你只需要把 base_url 指向 https://enlyai.com/v1,就能用同一套 LangChain 代码调用几十种模型:

from langchain_openai import ChatOpenAI

# 同一套代码,只改 model 名称即可切换
configs = [
    {"model": "gpt-4o-mini", "desc": "GPT-4o mini"},
    {"model": "claude-3-5-sonnet", "desc": "Claude 3.5 Sonnet"},
    {"model": "gemini-2.0-flash", "desc": "Gemini 2.0 Flash"},
]

question = "用一句话解释什么是 RAG"

for cfg in configs:
    llm = ChatOpenAI(
        model=cfg["model"],
        api_key="sk-your-enlyai-key",
        base_url="https://enlyai.com/v1"
    )
    answer = llm.invoke(question)
    print(f"[{cfg['desc']}] -> {answer.content}")

对应的 cURL 测试命令,方便你在终端快速验证:

curl https://enlyai.com/v1/chat/completions \
  -H "Authorization: Bearer sk-your-enlyai-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet",
    "messages": [{"role": "user", "content": "用一句话解释什么是 RAG"}]
  }'

统一 API 的价值在于:

十、生产环境最佳实践

把 LangChain 应用从 Demo 推向生产,有几点经验值得分享:

  1. 用 LCEL 而不是旧的 LLMChain:LCEL 原生支持流式、异步、批量,性能更好,且是官方主推方向。
  2. 把记忆持久化:生产环境不要用 InMemoryChatMessageHistory,改用 Redis 或数据库,否则服务重启历史就丢了。
  3. 限制 Agent 的迭代次数:用 max_iterations 防止 Agent 陷入死循环烧 token。
  4. 监控 token 消耗:每次调用都记录 usage_metadata,否则账单会悄悄失控。
  5. 密钥走环境变量:永远不要把 API key 写死在代码里,用 os.getenv("OPENAI_API_KEY") 读取。
  6. 给 RAG 加引用来源:让模型在回答中标注引用了哪些文档片段,方便用户核实,也能降低幻觉风险。

总结

LangChain 的学习曲线确实比直接调 OpenAI SDK 陡峭,但它解决的问题也是真实的:当你的应用从“单次问答”进化到“多轮对话 + 文档检索 + 工具调用”时,没有一个框架会非常痛苦。掌握本文讲的六个核心模块——Models、Prompts、Chains、Memory、Retrievers、Agents——你就能应对绝大多数 LLM 应用场景。

而把 LangChain 和 EnlyAI 统一 API 结合起来,你既能享受框架的工程能力,又能用一套密钥、一个地址访问所有主流大模型,把精力集中在业务逻辑而不是基础设施上。

想用 LangChain 调用所有主流大模型?

EnlyAI 提供 OpenAI 兼容的统一接口,支持 GPT、Claude、Gemini 等数十种模型,注册即送免费额度,LangChain 代码只需改一个 base_url 即可接入。

立即注册 EnlyAI →