目录
- 引言:从"记忆"到"思考"的演进
- 第一部分:基石------向量嵌入与语义搜索
- 第二部分:桥梁------大语言模型(LLM)应用开发
- [LLM 的核心能力与局限](#LLM 的核心能力与局限)
- [关键模式:Function Calling](#关键模式:Function Calling)
- [第三部分:框架------LangChain 与智能体(Agent)](#第三部分:框架——LangChain 与智能体(Agent))
- [LangChain 的核心价值](#LangChain 的核心价值)
- [LangChain Agent 的工作原理](#LangChain Agent 的工作原理)
- [第四部分:进阶------LangGraph 与有状态工作流](#第四部分:进阶——LangGraph 与有状态工作流)
- [什么是 LangGraph?](#什么是 LangGraph?)
- 核心概念
- [LangGraph 典型模式:循环 Agent](#LangGraph 典型模式:循环 Agent)
- 总结:技术栈全景图
- 下一步学习建议
引言:从"记忆"到"思考"的演进
人工智能的浪潮正从简单的文本生成,涌向能够理解、推理并执行复杂任务的智能体(Agent)。这一演进的核心,是让模型不仅拥有海量的"知识"(通过向量嵌入实现),更能像人类一样"思考"和"行动"(通过 Agent 框架实现)。
本文将为你梳理这条清晰的技术脉络:从让模型"记住"知识的向量嵌入 ,到连接模型与外部工具的大语言模型(LLM)应用开发 ,再到构建可编排、可复用流程的LangChain ,最终抵达设计复杂、有状态工作流的LangGraph。这是一条从静态知识到动态智能的完整路径。
在阅读本文前,建议你具备以下基础知识:了解 Python 基本语法、熟悉 REST API 概念、对机器学习有初步认识。如果你对上述概念尚不熟悉,也不必担心,本文会尽量用通俗的语言和丰富的示例帮助你理解。
第一部分:基石------向量嵌入与语义搜索
什么是向量嵌入?
向量嵌入(Vector Embedding)是将文本、图像、音频等非结构化数据,转换为计算机可理解的数值向量(一组浮点数)的技术。这个过程捕获了数据的语义信息,使得语义相似的文本在向量空间中的位置也相近。
技术原理简述:嵌入模型通常基于 Transformer 架构,通过在海量语料上进行对比学习训练而成。模型将输入文本编码为一个固定维度的向量(如 OpenAI 的 text-embedding-3-small 输出 1536 维向量),向量中的每个维度都编码了某种语义特征。两个向量的余弦相似度(Cosine Similarity)或欧氏距离(Euclidean Distance)反映了它们对应文本的语义相似程度。
例如,"猫"和"猫咪"的向量距离会很近(余弦相似度 > 0.9),而"猫"和"汽车"的向量距离则较远(余弦相似度 < 0.3)。这种特性使得向量嵌入成为语义搜索、聚类、推荐等任务的基础。
为什么需要向量嵌入?
LLM 本身存在"知识截止日期"和"上下文长度"限制。向量嵌入技术通过以下方式解决了这些问题:
- 知识外挂:将私有、最新的或海量的文档转换为向量存入数据库(向量数据库),作为模型的"外部记忆"。这意味着你不需要重新训练模型就能让它了解你的业务文档。
- 精准召回:当用户提问时,先将问题转换为向量,在向量数据库中快速找到最相关的文档片段。向量数据库使用近似最近邻(ANN)算法,能在毫秒级内从百万级向量中找到最相似的 Top K 个结果。
- 上下文优化:只将最相关的信息作为上下文喂给 LLM,节省 Token,提升回答质量与速度。相比将整篇文档塞入上下文,RAG 方式通常能节省 90% 以上的 Token 消耗。
实际应用场景:
- 企业知识库问答:将公司内部文档(产品手册、技术规范、政策文件)向量化,员工可以自然语言提问获取答案。
- 智能客服:将常见问题 FAQ 和产品文档向量化,结合 LLM 生成个性化回答。
- 内容推荐:将用户历史行为向量化,在向量空间中寻找相似内容进行推荐。
- 代码搜索:将代码库中的函数和注释向量化,支持语义级别的代码搜索。
核心工作流:RAG
检索增强生成(Retrieval-Augmented Generation, RAG)是向量嵌入最典型的应用范式。RAG 的核心思想是:在 LLM 生成回答之前,先从外部知识库中检索与问题最相关的信息,然后将这些信息作为上下文提供给 LLM,从而生成更准确、更有依据的回答。
#mermaid-svg-lt8pDQw8FRJa1q41{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lt8pDQw8FRJa1q41 .error-icon{fill:#552222;}#mermaid-svg-lt8pDQw8FRJa1q41 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lt8pDQw8FRJa1q41 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lt8pDQw8FRJa1q41 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lt8pDQw8FRJa1q41 .marker.cross{stroke:#333333;}#mermaid-svg-lt8pDQw8FRJa1q41 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lt8pDQw8FRJa1q41 p{margin:0;}#mermaid-svg-lt8pDQw8FRJa1q41 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster-label text{fill:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster-label span{color:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster-label span p{background-color:transparent;}#mermaid-svg-lt8pDQw8FRJa1q41 .label text,#mermaid-svg-lt8pDQw8FRJa1q41 span{fill:#333;color:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 .node rect,#mermaid-svg-lt8pDQw8FRJa1q41 .node circle,#mermaid-svg-lt8pDQw8FRJa1q41 .node ellipse,#mermaid-svg-lt8pDQw8FRJa1q41 .node polygon,#mermaid-svg-lt8pDQw8FRJa1q41 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lt8pDQw8FRJa1q41 .rough-node .label text,#mermaid-svg-lt8pDQw8FRJa1q41 .node .label text,#mermaid-svg-lt8pDQw8FRJa1q41 .image-shape .label,#mermaid-svg-lt8pDQw8FRJa1q41 .icon-shape .label{text-anchor:middle;}#mermaid-svg-lt8pDQw8FRJa1q41 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lt8pDQw8FRJa1q41 .rough-node .label,#mermaid-svg-lt8pDQw8FRJa1q41 .node .label,#mermaid-svg-lt8pDQw8FRJa1q41 .image-shape .label,#mermaid-svg-lt8pDQw8FRJa1q41 .icon-shape .label{text-align:center;}#mermaid-svg-lt8pDQw8FRJa1q41 .node.clickable{cursor:pointer;}#mermaid-svg-lt8pDQw8FRJa1q41 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lt8pDQw8FRJa1q41 .arrowheadPath{fill:#333333;}#mermaid-svg-lt8pDQw8FRJa1q41 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lt8pDQw8FRJa1q41 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lt8pDQw8FRJa1q41 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lt8pDQw8FRJa1q41 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lt8pDQw8FRJa1q41 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lt8pDQw8FRJa1q41 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster text{fill:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 .cluster span{color:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lt8pDQw8FRJa1q41 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lt8pDQw8FRJa1q41 rect.text{fill:none;stroke-width:0;}#mermaid-svg-lt8pDQw8FRJa1q41 .icon-shape,#mermaid-svg-lt8pDQw8FRJa1q41 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lt8pDQw8FRJa1q41 .icon-shape p,#mermaid-svg-lt8pDQw8FRJa1q41 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lt8pDQw8FRJa1q41 .icon-shape .label rect,#mermaid-svg-lt8pDQw8FRJa1q41 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lt8pDQw8FRJa1q41 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lt8pDQw8FRJa1q41 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lt8pDQw8FRJa1q41 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "原始文档
(PDF/Word/网页等)"
"文本分割
与清洗"
"向量嵌入模型
(如 text-embedding-3-small)"
"向量数据库
(如 Pinecone, Weaviate)"
"用户提问"
"问题向量化"
"相似度检索"
"Top K 相关片段"
"组合成提示词
(Prompt)"
"大语言模型
(LLM)"
"精准、有依据的回答"
RAG 的两种主要模式:
- 朴素 RAG(Naive RAG):每次用户提问时,只检索一次,将检索结果直接拼入提示词。实现简单,但可能遗漏多步推理所需的信息。
- 高级 RAG(Advanced RAG):引入查询重写、多轮检索、重排序(Re-ranking)等优化。例如,先对用户问题进行改写以提升检索质量,检索后使用交叉编码器(Cross-Encoder)对结果重排序,确保最相关的片段排在前面。
关键技术栈:
- 嵌入模型 :OpenAI
text-embedding-3-*(性价比高),Cohere Embed(支持多语言),开源模型(BGE, Jina, E5)。 - 向量数据库:Pinecone(全托管,易上手),Weaviate(支持混合搜索),Qdrant(Rust 实现,性能优异),Milvus(大规模场景),或 PostgreSQL 的 pgvector 扩展(适合已有 PostgreSQL 基础设施的团队)。
- 文本处理 :LangChain 的
RecursiveCharacterTextSplitter等,通常按 500-1000 字符分块,块间重叠 50-200 字符以保持上下文连贯性。
第二部分:桥梁------大语言模型(LLM)应用开发
掌握了"记忆"(向量检索)后,我们需要让模型学会"使用工具"。这就是 LLM 应用开发的核心。
LLM 的核心能力与局限
- 能力:强大的文本生成、总结、翻译、代码编写和逻辑推理能力。现代 LLM(如 GPT-4、Claude 3)在多项基准测试中已接近或超越人类水平。
- 局限 :
- 知识可能过时(训练数据截止到某个时间点)。
- 无法直接操作外部系统(如数据库、API、文件系统)。
- 可能产生"幻觉"(Hallucination),即编造看似合理但实际错误的信息。
- 上下文窗口有限(即使 GPT-4 支持 128K Token,处理超长文档时仍可能遗漏细节)。
- 缺乏精确计算能力(如复杂的数学运算、精确的日期计算)。
如何克服这些局限? 答案就是 Function Calling 和工具使用------让 LLM 学会调用外部工具来弥补自身不足。
关键模式:Function Calling
为了让 LLM 突破局限,我们需要赋予它调用外部函数(工具)的能力。主流模型(如 GPT-4, Claude)都支持 Function Calling。
工作原理:
- 开发者定义一系列工具(函数)及其描述(名称、参数、说明)。
- 在调用 LLM 时,将这些工具定义连同用户问题一起发送。
- LLM 分析问题,决定是否需要调用工具,并生成符合工具参数要求的 JSON 格式调用请求。
- 应用代码执行该函数,将结果返回给 LLM。
- LLM 结合函数执行结果,生成最终回答给用户。
示例场景:"今天北京天气怎么样?"
- LLM 识别出需要调用
get_weather(location: string)工具。 - 生成
{"name": "get_weather", "arguments": {"location": "北京"}}。 - 代码执行天气查询 API,返回"北京,晴,25℃"。
- LLM 生成回答:"北京今天天气晴朗,气温 25 摄氏度。"
第三部分:框架------LangChain 与智能体(Agent)
当工具变多、流程变复杂时,手动管理 LLM 调用、工具选择、状态维护变得极其困难。LangChain 应运而生,它是一个用于开发 LLM 应用的框架。
LangChain 的核心价值
- 组件化:将 LLM、提示词、记忆、索引、链、工具等抽象为可互换的组件。
- 链(Chain):将多个组件按顺序组合,实现复杂逻辑(如:检索 -> 问答 -> 格式化)。
- 智能体(Agent):LangChain 的灵魂。一个 Agent = LLM + 工具集 + 决策逻辑。Agent 可以自主决定何时、使用何种工具来完成任务。
LangChain Agent 的工作原理
#mermaid-svg-yoPYraAyZnccPJNQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yoPYraAyZnccPJNQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yoPYraAyZnccPJNQ .error-icon{fill:#552222;}#mermaid-svg-yoPYraAyZnccPJNQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yoPYraAyZnccPJNQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yoPYraAyZnccPJNQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yoPYraAyZnccPJNQ .marker.cross{stroke:#333333;}#mermaid-svg-yoPYraAyZnccPJNQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yoPYraAyZnccPJNQ p{margin:0;}#mermaid-svg-yoPYraAyZnccPJNQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yoPYraAyZnccPJNQ .cluster-label text{fill:#333;}#mermaid-svg-yoPYraAyZnccPJNQ .cluster-label span{color:#333;}#mermaid-svg-yoPYraAyZnccPJNQ .cluster-label span p{background-color:transparent;}#mermaid-svg-yoPYraAyZnccPJNQ .label text,#mermaid-svg-yoPYraAyZnccPJNQ span{fill:#333;color:#333;}#mermaid-svg-yoPYraAyZnccPJNQ .node rect,#mermaid-svg-yoPYraAyZnccPJNQ .node circle,#mermaid-svg-yoPYraAyZnccPJNQ .node ellipse,#mermaid-svg-yoPYraAyZnccPJNQ .node polygon,#mermaid-svg-yoPYraAyZnccPJNQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yoPYraAyZnccPJNQ .rough-node .label text,#mermaid-svg-yoPYraAyZnccPJNQ .node .label text,#mermaid-svg-yoPYraAyZnccPJNQ .image-shape .label,#mermaid-svg-yoPYraAyZnccPJNQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-yoPYraAyZnccPJNQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yoPYraAyZnccPJNQ .rough-node .label,#mermaid-svg-yoPYraAyZnccPJNQ .node .label,#mermaid-svg-yoPYraAyZnccPJNQ .image-shape .label,#mermaid-svg-yoPYraAyZnccPJNQ .icon-shape .label{text-align:center;}#mermaid-svg-yoPYraAyZnccPJNQ .node.clickable{cursor:pointer;}#mermaid-svg-yoPYraAyZnccPJNQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yoPYraAyZnccPJNQ .arrowheadPath{fill:#333333;}#mermaid-svg-yoPYraAyZnccPJNQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yoPYraAyZnccPJNQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yoPYraAyZnccPJNQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yoPYraAyZnccPJNQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yoPYraAyZnccPJNQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yoPYraAyZnccPJNQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yoPYraAyZnccPJNQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yoPYraAyZnccPJNQ .cluster text{fill:#333;}#mermaid-svg-yoPYraAyZnccPJNQ .cluster span{color:#333;}#mermaid-svg-yoPYraAyZnccPJNQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yoPYraAyZnccPJNQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yoPYraAyZnccPJNQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-yoPYraAyZnccPJNQ .icon-shape,#mermaid-svg-yoPYraAyZnccPJNQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yoPYraAyZnccPJNQ .icon-shape p,#mermaid-svg-yoPYraAyZnccPJNQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yoPYraAyZnccPJNQ .icon-shape .label rect,#mermaid-svg-yoPYraAyZnccPJNQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yoPYraAyZnccPJNQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yoPYraAyZnccPJNQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yoPYraAyZnccPJNQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 选择工具
最终答案
"用户输入问题"
"Agent Executor"
"LLM 思考
(选择工具或结束)"
"执行工具调用"
"获取工具结果"
"输出最终结果给用户"
关键概念:
- 工具(Tool):Agent 可以调用的函数。
- 代理类型(AgentType) :如
ZERO_SHOT_REACT_DESCRIPTION,定义了提示词模板和决策逻辑。 - 执行器(AgentExecutor):驱动 Agent 进行"思考-行动-观察"循环的运行时。
一个简单的 LangChain Agent 示例:
python
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
from langchain.utilities import SerpAPIWrapper
# 1. 定义工具
search = SerpAPIWrapper()
tools = [
Tool(
name="Search",
func=search.run,
description="用于回答关于当前事件的问题"
),
]
# 2. 初始化 LLM 和 Agent
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
# 3. 运行
agent.run("谁是2023年诺贝尔文学奖得主?")
运行结果可能为:Agent 会先"思考"需要搜索,然后调用 Search 工具,最后给出答案。
第四部分:进阶------LangGraph 与有状态工作流
LangChain Agent 适用于线性任务。但对于需要循环、分支、并行、持久化状态等复杂逻辑的 Agent(如客服机器人、游戏 NPC、自动化工作流),我们就需要 LangGraph。
什么是 LangGraph?
LangGraph 是建立在 LangChain 之上的一个库,用于构建有状态、多参与的图工作流。它将工作流建模为一张图(Graph),节点(Node)是函数或工具,边(Edge)定义了执行流向。
核心概念
- 状态(State):一个共享的字典,在所有节点间传递和更新。这是与简单 Chain 最大的区别。
- 节点(Node):一个函数,接收当前状态,执行操作(如调用 LLM、工具),并返回更新后的状态。
- 边(Edge) :根据节点的输出或状态条件,决定下一个执行哪个节点。支持条件边(
conditional_edge)。 - 编译与运行:将定义好的图编译成可执行对象,然后传入初始状态运行。
LangGraph 典型模式:循环 Agent
这是对基础 LangChain Agent 的增强,使其能更好地处理复杂对话和任务。
#mermaid-svg-SPOWrRmRP5RI7ZE7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .error-icon{fill:#552222;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .marker.cross{stroke:#333333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 p{margin:0;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster-label text{fill:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster-label span{color:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster-label span p{background-color:transparent;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .label text,#mermaid-svg-SPOWrRmRP5RI7ZE7 span{fill:#333;color:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .node rect,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node circle,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node ellipse,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node polygon,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .rough-node .label text,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node .label text,#mermaid-svg-SPOWrRmRP5RI7ZE7 .image-shape .label,#mermaid-svg-SPOWrRmRP5RI7ZE7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .rough-node .label,#mermaid-svg-SPOWrRmRP5RI7ZE7 .node .label,#mermaid-svg-SPOWrRmRP5RI7ZE7 .image-shape .label,#mermaid-svg-SPOWrRmRP5RI7ZE7 .icon-shape .label{text-align:center;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .node.clickable{cursor:pointer;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .arrowheadPath{fill:#333333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SPOWrRmRP5RI7ZE7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SPOWrRmRP5RI7ZE7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster text{fill:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .cluster span{color:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SPOWrRmRP5RI7ZE7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .icon-shape,#mermaid-svg-SPOWrRmRP5RI7ZE7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .icon-shape p,#mermaid-svg-SPOWrRmRP5RI7ZE7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .icon-shape .label rect,#mermaid-svg-SPOWrRmRP5RI7ZE7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SPOWrRmRP5RI7ZE7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SPOWrRmRP5RI7ZE7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SPOWrRmRP5RI7ZE7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "需要调用工具"
"直接回答用户"
开始
"Agent Node
(LLM决定行动)"
"LLM 判断"
"Tool Node
(执行工具)"
"Update State
(更新结果到状态)"
"Final Node
(整理并输出答案)"
结束
示例:一个能持续对话并调用工具的客服 Agent
python
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from langchain_core.messages import HumanMessage, AIMessage
import operator
# 1. 定义状态
class AgentState(TypedDict):
messages: Annotated[list, operator.add] # 消息历史
needs_tool: bool # 是否需要调用工具
# 2. 定义节点函数
def call_llm(state: AgentState):
# 模拟 LLM 调用,这里简化为逻辑判断
last_msg = state['messages'][-1]['content']
if "天气" in last_msg:
return {"needs_tool": True, "messages": [("assistant", "我将为您查询天气。")]}
else:
return {"needs_tool": False, "messages": [("assistant", f"我收到您的消息:'{last_msg}'")]}
def call_weather_tool(state: AgentState):
# 模拟调用天气工具
return {"messages": [("assistant", "北京今天天气晴朗,25℃。")]}
# 3. 构建图
workflow = StateGraph(AgentState)
workflow.add_node("agent", call_llm)
workflow.add_node("tool", call_weather_tool)
# 4. 设置边
workflow.set_entry_point("agent")
workflow.add_conditional_edges(
"agent",
lambda state: "tool" if state.get("needs_tool") else END,
{"tool": "tool", END: END}
)
workflow.add_edge("tool", "agent") # 工具执行完回到 agent 节点
# 5. 编译并运行
app = workflow.compile()
initial_state = {"messages": [("user", "北京天气怎么样?")], "needs_tool": False}
result = app.invoke(initial_state)
print(result["messages"][-1]) # 输出最终助理消息
总结:技术栈全景图
让我们将这四个部分串联起来,看看一个现代 AI 应用可能的技术架构:
渲染错误: Mermaid 渲染失败: Lexical error on line 2. Unrecognized text. ...aph TB subgraph "数据与记忆层" A[" ----------------------^
如何选择?
- 从 RAG 开始:如果你的核心需求是让模型基于特定知识库问答,优先掌握向量嵌入和 LangChain 的检索链。
- 增加工具调用:当需要模型操作现实世界(查数据、发邮件、控制设备)时,学习 LangChain 的 Agent。
- 迈向复杂系统:当 Agent 需要记忆长对话、处理多步骤审批、实现游戏逻辑时,就是 LangGraph 的用武之地。
这条路从赋予模型"记忆",到教会它"使用工具",再到让它"自主规划与协作",最终构建出真正智能、实用的 AI 应用。希望这篇科普能为你指明方向。
下一步学习建议
- 动手实践:在 LangChain 官网跟着教程搭建第一个 RAG 应用和简单 Agent。
- 深入原理:阅读 OpenAI Function Calling 和 ReAct 论文,理解 Agent 的决策逻辑。
- 探索生态:关注 LangChain/LangGraph 的更新,以及 Weaviate、Pinecone 等向量数据库的最佳实践。
- 构建项目:尝试用 LangGraph 设计一个个性化的学习助手或自动化工作流。