无痛入门LangChain智能体开发
LangChain 在初期被人吐槽抽象复杂、API难用。现在已经逐渐成熟,发展成了一套从研发、调试到部署的很全面的框架,是入门智能体开发的好帮手。本文将会介绍:(1) LangChain 生态中各个框架的功能。(2)LangChain 系列框架的基本概念 (3)三个典型应用案例【AI大模型教程】
发展历史
langchain architecture
从API到应用:LangChain
2022年底,GPT-3.5 的发布引起了开发基于 LLM 应用的热潮,但是开发者们发现,直接调用 LLM 的 API 只是第一步,要构建一个真正有用的应用,需要大量的“胶水代码”来处理:
- 管理和优化 Prompts。
- 将一个复杂的任务分解成多个 LLM 调用。
- 连接 LLM 到外部数据源(如文档、数据库)。
- 让 LLM 能够使用外部工具(如计算器、搜索引擎)。
LangChain提供了一套标准化的、易于使用的抽象组件,如 Chains、Agents、Indexes 和 Memory,极大地简化了上述“胶水代码”的编写。
Debug提效:LangSmith
随着开发者构建的应用越来越复杂,一个巨大的痛点浮现出来:调试。一个 Agent 的执行过程可能包含数十次 LLM 调用、工具使用和数据检索。当输出结果不符合预期时,开发者很难弄清楚到底是哪一步出了问题。Agent 的内部运作就像一个“黑盒”。
为了解决这个问题,LangChain 团队推出了 LangSmith。LangSmith 能够:
- 可视化追踪 (Tracing):将 Agent 的每一步执行都清晰地展示出来,包括完整的输入/输出、Token 消耗和延迟。
- 评估 (Evaluation):帮助开发者创建数据集,并测试他们的应用在这些数据集上的表现,以确保代码变更没有导致性能下降。
- 监控与调试 (Monitoring & Debugging):在生产环境中监控应用的运行情况,并快速定位问题。
控制流升级:LangGraph
标准的 LangChain Agent(如 ReAct 框架)本质上是一个简单的循环:思考 -> 行动 -> 观察 -> 思考...。这种线性或简单的循环结构在处理需要更复杂逻辑的任务时显得力不从心,例如:
- 需要多个智能体协作,互相传递任务。
- 需要在流程中加入“人类审批”环节 (Human-in-the-loop)。
- 需要根据不同情况执行不同的分支逻辑,甚至包含循环。
为了解决这个控制流(Control Flow)的限制,LangChain 团队推出了 LangGraph。它没有使用 Chain 的概念,而是将应用构建为状态图(State Graph):
- 状态 (State):代表每一个时刻系统的运行状态。
- 节点 (Nodes):代表一个计算步骤(如调用 LLM 或工具)。
- 边 (Edges):代表从一个节点到另一个节点的逻辑流。 通过这种方式,开发者可以明确地定义任何复杂的流程,包括循环、分支和多智能体协作。
从研发到部署
LangGraph已经基本可以支持我们开发出来所有想要的功能了,现在只差最后一步,部署中可能遇到的问题:
- 这些应用是有状态和长时运行的,传统的无状态 Serverless 架构不适用。
- 如何处理任务的持久化,确保服务器重启后任务能从中断处恢复?(即 Durable Execution)
- 如何在高并发下进行扩展?
- 如何为团队提供协作和管理这些复杂智能体的平台?
LangGraph Platform 提供以下功能:
- 全托管部署: 一键将 LangGraph 应用部署到云端。
- 持久化执行: 内置的检查点机制,自动保存每一步的状态,实现容错和恢复。
- 可扩展的基础设施: 专为有状态智能体优化的任务队列和内存管理。
- 协作工具: 如 LangGraph Studio,用于可视化构建和调试。
第三方工具支持
最后LangChain生态作为一个智能体开发平台,开发者们需要调用各种工具,例如不同的 LLM API 供应商、数据库等来实现自己的功能。Integration部分现在已经提供了几十家工具的集成。
基本概念
Runnable和LCEL
Runnable是 LangChain 的核心类,LLM API、工具调用、数据库/向量库查询、输出解析功能全部都是 Runnable 。以上每一种功能抽象的来看,都可以看成给 Runnable 喂一些输入,进行一些运算以后返回结果。
运算有三种模式,单个执行(invoke)、批量执行(batch)、流式执行(stream)。三种模式还有异步版本,分别是ainvoke、abatch和astream。
LCEL (LangChain Expression Language) 让我们可以很方便的将多个 Runnable 组合成一个完整的处理流程。
chain = prompt | model | StrOutputParser()
组合出来的chain也可以直接进行invoke、batch、stream操作。这样我们就可以把更多精力放在每一个 Runnable 积木怎么实现,靠LCEL可以让搭建一个流程像拼乐高一样愉快。
无状态 vs 有状态
假设我们定一个好一个 chain 以后,不论对 chain 输入什么内容都不会对它本身产生影响,也不需要把某些信息保存下来未来用,那么我们的系统是无状态的。
相对的,如果我们需要把历史对话或者运行过程中的结果保存下来,并且未来会用到,这种系统是有状态的。
Workflow vs Agent
做一个“工作流”听起来不如做一个“智能体”高级,为了明确我们要做的功能是什么,从而选择合适的工具,我们自己心里要清楚自己做的是什么。因为三种模式对于 LLM 智能的依赖和调试好的难度都逐级提高。
- LLM 作为工作流的一个节点。
- LLM 在预设好的工作流中运行。
- LLM 在运行中动态决定工作流程。
langchain-ai.github.io/langgraph/t… 这里给出了几种典型模式的参考实现
应用举例
有了上面的知识作为基础,下面再来看一些用 LangChain 生态都可以实现的典型应用。当我们自己有想要做的应用,可以找到类似的代码作为起点,节省时间。LangChain 官方文档提供了几个经典类型的案例。
聊天机器人
使用 LangGraph 的 MemorySaver,可以实现一个带记忆的聊天机器人。对话历史可以持久化到内存或者数据库,还可以用 thread_id 来区分不同的用户。
RAG问答
这个案例是用 WebBaseLoader 加载一个网页的内容,使用 RecursiveCharacterTextSplitter 切分,用 OpenAIEmbeddings 模型向量化,保存到内存向量库 InMemoryVectorStore。
上面这个案例是个典型的 workflow, 如果像做成agent可以参考这个案例实现react智能体。
添加人类干预 (human-in-the-loop)
这个例子展示了结合Agent Chat UI,一个带界面的对话机器人,使用 interrupt() 中断,等待人类输入后继续执行。
interrupt