AI全栈知识05:LangChain入门 – AI应用开发框架

写在前面
你可能已经会用Python调大模型的API了,发一个请求,拿到一个回答。但真实的AI应用远不止"一问一答":
- 要让对话有"记忆"(记住之前聊了什么)
- 要先搜资料再回答(RAG)
- 要让模型自己调工具完成任务(Agent)
这些如果全部自己手写,代码量大、容易出bug。LangChain就是帮你把这些常见模式封装好的框架,你拼装组件就行,不用从零造轮子。
LangChain是什么
一句话: AI应用开发的脚手架。把对话、RAG、Agent这些常见模式封装成现成组件,几行代码就能搭建复杂的AI应用。
生活类比
| 自己砍树、锯木头、造家具 | 买宜家的零件包,按说明书组装 |
| 每个功能从零写 | 现成组件拼装 |
| 灵活但慢 | 快但依赖框架 |
为什么需要它
直接调API只能做到:一个问题 > 一个回答。
但真实需求是:
| 带记忆的对话 | 自己管对话历史,每次手动拼到Prompt里 | Memory组件自动处理 |
| RAG(搜资料再回答) | 切文档>调Embedding>查向量库>拼Prompt>调模型 | 几行代码搞定整条链 |
| Agent(调工具) | 解析function_call>执行>结果返回>循环判断 | AgentExecutor自动循环 |
三个核心概念

概念一:Chain(链)- 把多步骤串成流水线
类比: 你去奶茶店点了一杯饮料,后厨的流程是:取杯>加茶底>加奶>加糖>封口>出品。每一步都依赖上一步的结果,不能跳着来。Chain就是这样,把AI应用的多个步骤像做奶茶一样串起来,前一步做完自动流转到下一步。
RAG的Chain(就像奶茶制作流水线):
用户问题(点单) > 转向量(备料) > 搜索向量库(找配方) > 拼装Prompt(调配) > 调大模型(制作) > 输出回答(出品)
用户问题 > 转向量 > 搜索向量库 > 拼装Prompt > 调大模型 > 输出回答
每一步的输出 = 下一步的输入,像链条一样串起来。
**代码形式(LCEL管道符写法):**
```python
# 像Linux管道一样:前一步 | 后一步 | 后一步
chain = prompt_template | llm | output_parser
result = chain.invoke({"question": "什么是K8s"})
如果你熟悉Linux的管道(cat file | grep error | wc -l),这个概念你秒懂,每个组件处理完传给下一个。
概念二:Memory(记忆)- 让对话有上下文
问题: 大模型的API每次请求都是独立的,它不记得上一轮你说了什么。这就像你每次打电话给客服都换一个人接,你得从头解释一遍你的问题。
Memory做的事: 帮你当"记录员",把每轮对话记下来,下次自动带上。这样模型每次都能"看到"之前聊了什么。
注意:不是模型真的"记住了",而是每次请求都把聊天记录一起发过去。 就像你把之前的聊天截图发给新客服看,不是客服记性好,是你把记录带上了。
没有Memory:
用户:"我叫张三" > 模型:"你好张三"
用户:"我叫什么" > 模型:"我不知道"(独立请求,没记忆)
有Memory:
用户:"我叫张三" > 模型:"你好张三"(Memory保存)
用户:"我叫什么" > 模型:"你叫张三"(Memory自动把上轮对话加到Prompt)
实际上模型看到的Prompt是:
[历史] 用户说"我叫张三",你回答了"你好张三"
[当前] 用户说"我叫什么"
Memory帮你自动管理这个"历史记录拼接"的过程。
概念三:Tool(工具)- 让模型能"动手"
问题: 模型只能生成文字,不能真的去查数据库、调API、执行命令。它就像一个被关在房间里的超级大脑,很聪明,但没有手脚,做不了房间外面的事。
Tool的作用: 给这个大脑"接上手脚",定义一组工具函数(查Pod、查日志、重启服务……),模型可以决定什么时候"伸手"去用哪个工具。
@tool
def get_unhealthy_pods(namespace: str = "default") –> str:
"""获取异常状态的Pod列表"""
# 调用K8s API
return "pod/order-service: CrashLoopBackOff"
@tool
def get_pod_logs(pod_name: str) –> str:
"""获取Pod的最近日志"""
# 调用K8s API
return "java.lang.OutOfMemoryError"
你只需要定义函数+写好描述,LangChain帮你处理:
- 模型决定调哪个工具 > 自动解析
- 执行工具 > 自动调用你的函数
- 结果返回给模型 > 自动拼装
- 模型再决定下一步 > 自动循环
这就是你K8sChat项目的核心机制。
代码示例
最基础:直接对话
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# 创建模型客户端(指向你公司的API或通义千问)
llm = ChatOpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="你的key",
model="qwen-turbo"
)
# 对话
messages = [
SystemMessage(content="你是一个K8s运维专家"),
HumanMessage(content="Pod Pending怎么排查?")
]
response = llm.invoke(messages)
print(response.content)
进阶:Agent模式(自动调工具)
from langchain_openai import ChatOpenAI
from langchain.agents import tool, AgentExecutor, create_openai_tools_agent
from langchain_core.prompts import ChatPromptTemplate
# 1. 定义工具
@tool
def get_unhealthy_pods(namespace: str = "default") –> str:
"""获取异常状态的Pod列表"""
return "pod/order-service-xxx: CrashLoopBackOff"
@tool
def get_pod_logs(pod_name: str) –> str:
"""获取Pod的最近日志"""
return "java.lang.OutOfMemoryError: Java heap space"
# 2. 创建Agent
llm = ChatOpenAI(base_url="…", api_key="…", model="qwen-turbo")
tools = [get_unhealthy_pods, get_pod_logs]
prompt = ChatPromptTemplate.from_messages([
("system", "你是K8s运维助手,用工具帮用户排查问题"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
# 3. 用户提问,Agent自动调工具
result = executor.invoke({"input": "有哪些Pod异常?帮我看下日志"})
print(result["output"])
Agent执行过程:
用户:"有哪些Pod异常?帮我看下日志"
> 模型决定调 get_unhealthy_pods
> 拿到结果:order-service CrashLoopBackOff
> 模型决定调 get_pod_logs("order-service-xxx")
> 拿到结果:OutOfMemoryError
> 模型总结:"order-service因为内存不足(OOM)一直重启,建议增加memory limit"

LangChain的生态
| langchain-core | 核心接口定义 | 了解即可 |
| langchain | 主框架(Chain、Agent) | ✅ 必须 |
| langchain-openai | 对接OpenAI兼容API | ✅ 必须(你公司API就用这个) |
| langchain-community | 社区集成(向量库等) | RAG时用 |
| langgraph | 新一代Agent编排 | 了解即可 |
| langserve | 把Chain部署成API | 生产部署时用 |
LCEL:管道符写法
LangChain现在推荐用"管道符"串联组件。如果你是Linux运维出身,这个你绝对秒懂,因为它跟Shell的管道一模一样:
# 你每天在用的Linux管道:每个命令处理完传给下一个
cat access.log | grep "500" | sort | uniq -c | sort -rn
# LangChain管道(LCEL):完全一样的思路
chain = prompt | llm | output_parser
水管接水管,前一段流出的水自动流进下一段。定义好"管道线路",一个.invoke()就跑通了。
Callback:插入监控逻辑
LangChain支持在执行过程中"插入"监控:
from langchain.callbacks import StdOutCallbackHandler
# 执行时会打印:调了什么模型、花了多少Token、每步耗时
result = chain.invoke({"input": "xxx"}, config={"callbacks": [StdOutCallbackHandler()]})
运维应用: 你可以用Callback做Token消耗统计、调用链追踪、延迟监控,这些是AI应用可观测性的基础。
LangChain vs 竞品
| LangChain | 全能型(Chain+RAG+Agent) | 通用场景首选 |
| LlamaIndex | 专注RAG/数据检索 | 只做知识库问答 |
| CrewAI | 专注多Agent协作 | 多个Agent配合 |
| AutoGen(微软) | 多Agent对话框架 | 研究/复杂协作 |
| 自己手写 | 完全可控,无依赖 | 需求简单/学原理 |
学一个LangChain就够了,它覆盖面最广。
LangChain的局限(要知道)
每个框架都有代价。LangChain就像一把瑞士军刀,功能齐全,但有时候你只想削个苹果,却要掏出一个20种功能的大家伙,反而不顺手。
| 抽象过度 | 简单需求用LangChain反而更复杂 | 削苹果用瑞士军刀不如用水果刀 |
| 版本不稳定 | 更新太快,旧教程代码经常跑不通 | 说明书每月换一版 |
| 性能开销 | 框架本身有额外开销 | 大卡车送一箱快递 |
| 调试困难 | 层层封装后出错不好定位 | 俄罗斯套娃里找东西 |
所以有些团队选择自己手写,需求明确时不需要框架的全部功能。就像你家装修,简单贴个壁纸不用请装修公司,自己动手更快。
对K8sChat的建议
| 手写Agent循环 | ⭐⭐⭐(证明理解原理) | 慢一些 |
| 用LangChain | ⭐⭐(证明会用框架) | 快 |
面试时"从零手写了Agent循环"比"用了LangChain"更加分,前者证明理解原理,后者只证明会用工具。
但如果赶时间出Demo,用LangChain也完全可以,后面可以重构。
面试怎么说
如果被问"你了解LangChain吗":
"了解,LangChain是AI应用开发框架,核心解决三个问题:Chain把多步骤串成流水线,Memory管理对话历史,Tool让模型能调外部API。
我开发的K8sChat运维助手就用到了Tool机制,定义K8s查询工具,让模型通过Function Calling自动调用。
不过LangChain也有局限,抽象重、版本迭代快。简单场景我倾向手写,复杂编排时才用框架。"
延伸思考
| LangChain必须用Python吗? | 主要是Python,也有JS/TS版本(langchain.js) |
| LangChain和FastGPT的关系? | FastGPT是产品(开箱即用),LangChain是开发框架(自己搭建) |
| 不用LangChain能做Agent吗? | 完全可以,自己解析function_call+写循环就行 |
| LangGraph和LangChain什么关系? | LangGraph是LangChain团队出的新Agent框架,比AgentExecutor更灵活 |
小结
本篇核心收获:
下一篇预告
AI全栈知识06:RAG实战,检索增强生成
下一篇我们将动手搭建一个RAG应用:
- 文档切分的策略
- Embedding是什么(把文字变成向量)
- 向量检索的原理
- 用LangChain搭建一个简单的知识库问答
参考链接
- LangChain官方文档
- LangChain GitHub
- LCEL教程
- LangChain Agent教程
- LangGraph文档
- LangSmith(调用链追踪)

