LangChain 与大模型技术全链路详解
一、通信协议
1. SSE 流式输出(主流):单向通信,属于 HTTP 原生协议
完美契合 AI 对话场景:用户发 1 次请求,服务端持续单向推送流式结果,无需客户端频繁交互。
- 响应头特征 :
Content-Type: text/event-stream,与普通 JSON 响应区分 - 前端通过
EventSourceAPI 接收 ,浏览器原生支持自动重连(默认固定间隔,由服务端retry字段控制)、心跳等基础机制
数据格式示例:
kotlin
data: {"token": "你"}\n\n
data: {"token": "好"}\n\n
data: [DONE]\n\n
前端实现:
kotlin
const source = new EventSource('/api/chat/stream')
source.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data === '[DONE]') {
source.close()
return
}
appendToken(data.token) // 逐 token 追加,实现打字机效果
}
SSE 的局限:
- 单向通信,客户端无法通过同一连接向服务端发数据
- 不支持二进制传输
- HTTP/1.1 下同域最多 6 个并发连接(HTTP/2 无此限制)
2. WebSocket:双向通信,比如打视频电话
WebSocket 是全双工(Full-Duplex,即双方可以同时互相发送数据) 双向通信协议,建立在 TCP 之上,通过 HTTP 握手(Handshake,协议升级请求)升级连接。
握手成功后,客户端和服务端可以随时互相发消息,无需等待对方。
适用场景对比:
| 场景 | 推荐协议 | 原因 |
|---|---|---|
| AI 对话流式输出 | SSE | 单向推流,HTTP 原生,实现简单 |
| 遥操作指令下发 + 状态回传 | WebSocket | 需要双向实时通信 |
| 实时协作编辑 | WebSocket | 多端双向同步 |
| 服务端事件通知推送 | SSE | 单向推送足够 |
WebSocket 重连策略(指数退避,Exponential Backoff):
javascript
let retryCount = 0
function connect() {
const ws = new WebSocket('ws://server/endpoint')
ws.onclose = () => {
// 指数退避:1s → 2s → 4s → 8s → 16s,避免同时大量重连压垮服务器
setTimeout(connect, Math.pow(2, retryCount++) * 1000)
}
ws.onopen = () => { retryCount = 0 }
}
二、LangChain:大模型应用编排框架
LangChain 解决的核心问题是:如何将大模型与外部工具、数据源、业务逻辑编排(Orchestrate,即按顺序组织调度)成一个可靠的 Agent 系统。
核心组件
Chain(调用链): 将多个组件顺序串联,每个组件的输出作为下一个组件的输入:
用户输入 → 提示词模板(Prompt Template)→ 大模型 → 输出解析器 → 结构化结果
Agent Executor(智能体执行器): Agent 的调度核心,负责:
- 接收用户输入
- 调用大模型进行意图理解与任务规划(Task Planning)
- 决定调用哪个 Tool(工具)、传入什么参数
- 将 Tool 返回结果注入上下文(Context)
- 继续调用大模型直到生成最终回复
Tool(工具): 封装外部能力,Agent 通过 Tool 与外部世界交互:
python
@tool
def query_salary(employee_id: str) -> str:
"""查询员工薪酬信息"""
return salary_service.get(employee_id)
大模型通过 Function Calling(函数调用)决定何时调用哪个 Tool------这就是 tool_calling 阶段。
Memory(记忆): 维护多轮对话上下文,常见实现:
ConversationBufferMemory:保留全部历史ConversationBufferWindowMemory:保留最近 k 轮ConversationSummaryMemory:对历史进行摘要压缩,解决上下文窗口(Context Window,模型一次能处理的最大文本长度)限制
Agent 执行流程
用户输入
↓
Agent Executor
↓
大模型(意图理解 + 规划)→ thinking(思考)阶段
↓
Tool 选择 + 参数生成 → tool_calling(工具调用)阶段
↓
Tool 执行(查数据库 / 调接口)
↓
结果注入上下文
↓
大模型生成最终回复 → responding(响应)阶段
↓
SSE 流式推送至前端
三、FastAPI
Python 高性能异步(Async,即非阻塞式,多个任务可以同时进行)Web 框架,LangChain 后端常用它暴露接口(API Endpoint)。天然支持 SSE 流式响应,配合 StreamingResponse 实现逐 token 推送。
python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
@app.get("/chat/stream")
async def chat_stream(query: str):
async def generate():
async for chunk in llm.astream(query):
yield f"data: {chunk.content}\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
四、RAG(Retrieval-Augmented Generation,检索增强生成)
为什么需要 RAG
大模型存在两个核心问题:
- 幻觉(Hallucination) :模型会自信地生成错误信息
- 私有知识缺失:企业内部数据不在训练集中,模型无法感知
RAG 的思路:先检索,再生成------优先检索企业私有库中的数据,将相关知识片段拼接进提示词,让模型基于真实数据生成回答,从而减少幻觉。
完整流程
原理:分词切片 → 向量化存入向量库 → 用户提问 → 检索相似内容 → 拼接进提示词 → 大模型生成回答
离线阶段(知识入库):
原始文档(PDF / Word / 网页)
↓
文档切片(Chunking,按固定长度或语义段落切分)
↓
向量化(Embedding,调用模型将文本转为高维浮点向量)
↓
存入向量库(如 Milvus / Chroma / Faiss)
在线阶段(检索生成):
swift
用户提问
↓
问题向量化(同一 Embedding 模型)
↓
向量相似度检索,返回 Top-K 相似片段
↓
拼接进提示词:
"基于以下上下文回答问题:\n{检索结果}\n\n问题:{用户问题}"
↓
大模型生成回答
分级检索(先检索本地向量库,再检索外层数据)
企业场景下通常采用分级检索策略:
- 优先检索私有向量库(企业内部文档、业务数据)→ 减少幻觉,保护数据安全
- 私有库置信度(Confidence Score,模型对结果的把握程度)不足时,回退到通用知识库或联网检索
- 多路召回后重排序(Reranker,对多个检索结果按相关度重新排列),选出最相关的片段
五、向量库
存储原理
向量库存储的是高维浮点向量(High-Dimensional Float Vector,用一组数字表示文本的语义) ,每条记录包含:
- 向量:文本的语义表示(如 1536 维浮点数组)
- 元数据(Metadata) :原始文本、文档来源、时间戳等
注意:向量库不是"按概率存储",而是将语义信息编码为向量空间中的坐标点,语义相近的文本在向量空间中距离更近。
相似度计算
余弦相似度(Cosine Similarity):
<math xmlns="http://www.w3.org/1998/Math/MathML"> cos ( θ ) = A ⋅ B ∣ A ∣ ∣ B ∣ \cos(\theta) = \frac{A \cdot B}{|A||B|} </math>cos(θ)=∣A∣∣B∣A⋅B
值域 [-1, 1],越接近 1 表示语义越相似,与向量长度无关,适合文本语义匹配。
检索时通过该算法计算用户问题与库中内容的相似程度,返回最相关的片段。
数据量大时使用近似最近邻算法(ANN,Approximate Nearest Neighbor) (如 HNSW、IVF)在召回率和速度之间取得平衡,避免对全库精确搜索的高开销。
常见向量库对比:
| 向量库 | 特点 | 适用场景 |
|---|---|---|
| Faiss | Meta 开源,纯内存,速度极快 | 离线 / 研究 |
| Milvus | 分布式,生产级,支持持久化 | 企业生产 |
| Chroma | 轻量,易集成 LangChain | 快速原型 |
| Pinecone | 云托管,开箱即用 | SaaS 场景 |
六、Transformer 原理
"Attention Is All You Need"怎么理解
2017 年谷歌 8 位研究员发表了论文《Attention Is All You Need》,提出了 Transformer 架构。OpenAI 在此基础上受益,GPT(Generative Pre-trained Transformer,基于 Transformer 架构的预训练生成式大语言模型)系列由此诞生。
Transformer 解决了什么问题:
- 残差连接(Residual Connection) 解决深层网络的梯度消失(Gradient Vanishing,深层网络训练时梯度越来越小导致无法更新的问题)
- 自注意力机制解决传统 RNN(循环神经网络)的长距离依赖和串行计算问题
- 只有清爽的矩阵计算(Matrix Computation),可以大规模并行,训练效率极高
编码器-解码器架构(Encoder-Decoder):
- 编码器(Encoder) :理解输入序列,提取语义
- 解码器(Decoder) :基于编码器输出,逐步生成目标序列
- 现代大语言模型(如 GPT)只用解码器部分
注意力机制分类
交叉注意力机制(Cross-Attention): Q 来自一个序列,K/V 来自另一个序列,用于跨模态或跨序列的信息融合。
- 典型应用:文生图(文本引导图像生成)、图生图、英译中翻译
自注意力机制(Self-Attention)✅ Transformer 核心: Q、K、V 均来自同一序列,序列内每个词都能直接关注到其他所有词。
多头自注意力机制(Multi-Head Attention)✅ 现代大语言模型标配: 将自注意力并行拆分为多个"头",每个头从不同角度理解语义,最终融合。
自注意力计算流程
第一步:生成 QKV(Query 查询、Key 键、Value 值)
句子里每一个词,都通过线性变换(Linear Transformation,矩阵乘法),分别生成自己的 Q、K、V 向量:
- Q(Query) :当前词"想查询什么"
- K(Key) :每个词"能提供什么标签"
- V(Value) :每个词"实际携带的信息内容"
第二步:Q 和 K 点积计算
用当前词的 Q ,去和全局所有词的 K 做点积(Dot Product,向量对应元素相乘后求和),算出两个词的相似度、关联程度。
第三步:除以 √d_k 缩放(Scale)
将点积结果除以 √d_k(d_k 为向量维度),防止点积过大导致 Softmax 进入饱和区(梯度接近 0,无法有效训练)。
第四步:Softmax 归一化
把算出来的相似度转成 0~1 的概率权重(Probability Weight),关系越近权重越大,模型越关注它。
注意:最终输出不是权重最大的那个值,而是所有 token 的加权求和,保留了全局信息。
第五步:权重 × V 加权求和
用注意力权重对所有词的 V 向量加权求和,得到当前词融合了全局上下文的新表示。
公式总结:
<math xmlns="http://www.w3.org/1998/Math/MathML"> Attention ( Q , K , V ) = Softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V </math>Attention(Q,K,V)=Softmax(dk QKT)V
多头注意力(Multi-Head Attention)
将 QKV 分裂为 h 个子空间(Subspace)并行计算,每个头关注不同语义维度,最后拼接融合:
erlang
输入 X
↓ 分裂为 h 组 QKV
Head_1 → 关注句法关系
Head_2 → 关注语义相似性
...
Head_h → 关注位置关系
↓ 拼接(Concatenate)
↓ 线性变换
MultiHead Output
残差连接与层归一化
每个子层后都有:
<math xmlns="http://www.w3.org/1998/Math/MathML"> Output = LayerNorm ( x + Sublayer ( x ) ) \text{Output} = \text{LayerNorm}(x + \text{Sublayer}(x)) </math>Output=LayerNorm(x+Sublayer(x))
- 残差连接(Residual Connection) :梯度可以直接跳过子层回传,缓解梯度消失
- 层归一化(Layer Normalization) :稳定训练过程,加速收敛(使每层输出的数值分布保持稳定)
自回归文本生成(Autoregressive Generation)
大模型以 token(最小文本单元,可以是一个字、一个词或一个标点)为单位,每次基于上文的所有 token,预测下一个 token 的概率分布,选择概率最高的 token 输出;再将新生成的 token 加入上文,继续预测后续内容,直到生成结束标记(EOS,End of Sequence)为止。
因此,大模型本质上是一个概率模型,其生成过程就是不断根据上文计算下一个 token 出现概率的过程。
实际生成时还有采样策略控制随机性:
- Greedy(贪心) :每次选概率最高的 token,确定性强但容易重复
- Temperature(温度) :调整概率分布的尖锐程度,温度↑ → 输出更随机多样,温度↓ → 输出更确定
- Top-p Sampling(核采样) :只从累积概率超过 p 的候选词中采样,平衡多样性与质量
七、CV 方向延伸
多模态语义对齐(Multimodal Semantic Alignment)
多模态(Multimodal,指同时处理文本、图像、语音等多种数据形式)模型的核心挑战是:将不同模态映射到同一语义空间(Semantic Space,用向量表示语义的数学空间),使语义相近的文本和图像在向量空间中距离相近,没有歧义。
CLIP(Contrastive Language-Image Pretraining,对比语言-图像预训练):
- 用对比学习(Contrastive Learning)训练:匹配的图文对拉近距离,不匹配的推远
- 实现了文本和图像的语义空间统一
- 是 Stable Diffusion 等文生图模型的文本编码器基础
文生图架构(Stable Diffusion):
css
文本输入 → CLIP 文本编码器 → 文本语义向量
↓ 交叉注意力引导
随机噪声 → UNet 去噪网络(Denoising,多步迭代去除噪声)→ 潜空间图像
↓ VAE 解码器(将压缩的潜空间还原为像素图像)
最终图像
文生视频、AIGC 图片识别均基于上述多模态对齐能力延伸。
3D 高斯重建(3D Gaussian Splatting,3DGS)
相比 NeRF(Neural Radiance Field,神经辐射场,一种用神经网络隐式表示 3D 场景的方法),3DGS 用显式的 3D 高斯椭球体表示场景:
- 每个高斯体有位置、旋转、缩放、颜色、透明度等属性
- 通过可微分渲染(Differentiable Rendering,支持梯度回传的渲染方式)优化参数,拟合多视角图片
- 渲染速度比 NeRF 快 10~100 倍,支持实时渲染
- 是具身智能(Embodied AI,让 AI 具备感知和操作物理世界能力的方向)场景理解、数字孪生重建的重要底层技术
总结
| 技术 | 核心作用 | 关键词 |
|---|---|---|
| SSE | AI 对话流式推送 | 单向、HTTP 原生、EventSource、逐 token 渲染 |
| WebSocket | 双向实时通信 | 全双工、指令下发、状态回传 |
| LangChain | Agent 编排框架 | Chain、Agent Executor、Tool、Memory |
| FastAPI | 后端接口框架 | 异步、StreamingResponse、SSE |
| RAG | 私有知识检索增强 | 切片、向量化、相似度检索、减少幻觉 |
| 向量库 | 语义相似度存储与检索 | 高维向量、余弦相似度、ANN |
| Transformer | 大模型基础架构 | 自注意力、多头注意力、自回归生成 |
| 多模态对齐 | 跨模态语义统一 | CLIP、对比学习、语义空间 |
| 3DGS | 3D 场景重建 | 高斯椭球体、可微分渲染、实时渲染 |