初识大语言模型LLM基本原理与LangChain、LangGraph框架
对于大语言模型,在当下这个时代也许我们每一个人都不再陌生,但是你真的搞懂了什么是真正的模型,什么是真正的模型应用吗?
1. 认识模型
模型是一个从大量数据中学习规律的”数学函数“或者”程序“,通常模仿人的认知功能,来处理和生成信息,一个模型本身不会处理这些信息,每一个模型都是经过特殊训练的,通过这些例子摸索出一套规则,来完成某个特定任务,举一个例子:
模型有一些特点,就比如:
- 特定任务:一个模型通常只擅长一件事情,eg专门识别图片是否为pretty durby,或者专门预测明天是否下雨,又或者判断一个评论是否为好评;
- 需要标注数据:让模型负责一件事情需要经过训练,需要拿大量标准答案来进行训练;
- 参数较少:参数是模型从数据中学习到的知识点或者规则的数量,参数较少说明模型的复杂度和能力有限;
2. 大语言模型
在介绍大语言模型之前,先来认识几个重要概念:
- 神经网络:神经网络模仿人的工作方式,由大量的神经元(每一个神经元都代表一个规则或者知识点)和神经元之间的连接构成,每一个神经元都是一个小处理单元,只负责处理一小部分信息,无数个神经元分为很多层,前一层输入作为后一层的输入;经过大量数据的训练,神经网络会调整每一个神经元的优先级(根据他们的重要性),形成一个复杂的流水线;神经网络就是一个通过大量数据训练出来的、由大量参数(神经元)组成的复杂决策系统;
- 自监督学习:所有训练数据都没有人工标注的标签,模型的监督信号完全从数据本身的结构、上下文、相关性里自己构造”出来
- 半监督学习:先接触一些有标注的数据,再接触海量的无标注数据,最后对于有标注无标注数据都能够正确处理;
- 语言模型:能够根据你输入的前文,来计算出下一个词最有可能是什么;
那么大语言模型LLM,就是基于大规模神经网络,通过自监督或者半监督的方式,对海量文本进行训练的语言模型;一般具有几个特点:
- 规模巨大,参数很多,思考问题更加全面和复杂;
- 通用性强,训练方式不同,交互方式改变;
2.1 与LLM对话提示词编写技巧
2.1.1 CO-STAR 结构化框架
在目标设定和问题解决的场景下,清晰性和结构性是至关重要的。这个框架可以更好的去撰写提示词。CO-STAR 可以拆解为六个维度:
| 模块 | 说明 | 示例 |
|---|---|---|
| Context | 任务背景与上下文 | “你是电商客服,需解答用户关于iPhone 17的咨询,知识库包含最新价格和库存” |
| Objective | 核心目标 | “准确回答价格、发货时间,推荐适配配件” |
| Steps | 执行步骤 | “1.识别用户问题类型;2.检索知识库;3.用亲切语气整理回复” |
| Tone | 语言风格 | “口语化,避免专业术语,使用‘亲~’‘呢’等语气词” |
| Audience | 目标用户 | “20-35岁年轻消费者,对价格敏感,关注性价比” |
| Response | 输出格式 | “价格:XXX元\n库存:XXX件\n推荐配件:XXX(链接)” |
例如,需要进行健康咨询,希望给出营养建议。那么可以这样构建提示词:
优化前:
我该怎么吃才能更健康?
优化后:
角色:你是一个基于科学证据的AI营养顾问。
重要约束:你提供的所有建议都仅为通用信息,不能替代专业医疗诊断。在给出任何具体建议前,必须首先声明此免责条款。
任务:基于以下用户信息,提供一份个性化的每日饮食原则性建议。
用户信息:
- 年龄:30岁
- 性别:男性
- 目标:减脂增肌
- 日常活动水平:办公室久坐,每周进行3次力量训练
回答要求:
- 首先,输出免责声明:“请注意:以下建议为通用健康信息…”
- 核心原则应围绕“控制总热量摄入,确保充足蛋白质”。
- 分别对早餐、午餐、晚餐和训练加餐提出各1条核心建议(例如:早餐应包含优质蛋白和复合碳水)。
- 推荐2种适合该用户的具体健康零食。
- 避免推荐任何具体的保健品或药物。
输出格式:
【免责声明】
[此处输出声明]【核心原则】
- …
【分餐建议】
- 早餐:…
- 午餐:…
【健康零食推荐】
- …
- …
2.1.2 少样本提示 / 多示例提示
这种方式通过给 AI 提供一两个 输入-输出 的例子,让它“照葫芦画瓢”。适合:格式固定、风格独特、逻辑复杂的任务,如风格仿写、数据提取、复杂格式生成。
例如:
优化前(零样本提示):
2 🍍 9 等于多少?
优化后(少样本提示):
根据以下示例,处理问题。
示例1:2 🍍 3 = 5
示例2:4 🍍 7 = 11
现在请分析这个:2 🍍 9 等于多少?
2.1.3 思维链提示
提示工程的关键目标是让AI更好地理解复杂语义。这种能力的高低,可以直接通过模型处理复杂逻辑推理题的表现来检验。当好的提示词能帮助模型解决原本解决不了的难题时,就说明它确实提升了模型的推理水平。并且,提示词设计得越出色,这种提升效果就越显著。通过设置不同难度的推理测试,可以很清晰地验证这一点。
杂耍者可以杂耍16个球。其中一半的球是高尔夫球,其中一半的高尔夫球是蓝色的。请问总共有多少个蓝色高尔夫球?
推理结果:
8个蓝色高尔夫球(错误)
为了解决类似的逻辑问题,可以使用思维链提示。思维链提示相较于少样本提示是一种更好的提示方法,思维链提示最常用的两种方式:
- Few-shot-CoT:少样本思维链
- Zero-shot-CoT:零样本思维链
相比于少样本提示(Few-shot),少样本思维链(Few-shot-CoT)的不同之处只是在于需要在提示样本中不仅给出问题的答案、还同时需要给出问题推导的过程(即思维链),从而让模型学到思维链的推导过程,并将其应用到新的问题中。此技巧主要用于解决复杂推理问题,如数学、逻辑或多步骤规划。
例如,手动写一个思维链作为少样本提示的示例:
Q:“罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?”
A:“罗杰起初有五个网球,又买了两盒网球,每盒3个,所以,他总共买了2×3=6个网球,将起始的数量和购买的数量相加,可以得到他现在总共的网球数量:5+6=11,所以罗杰现在总共有11个网球”
在获得了一个思维链示例后,就可以以此作为样本进行 Few-shot-CoT 来解决第二个推理问题, 如下所示:
示例1:
Q:“罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?”
A:“罗杰起初有五个网球,又买了两盒网球,每盒3个,所以,他总共买了2×3=6个网球,将起始的数量和购买的数量相加,可以得到他现在总共的网球数量:5+6=11,所以罗杰现在总共有11个网球”问:“食堂总共有23个苹果,如果他们用掉20个苹果,然后又买了6个苹果,请问现在食堂总共有多少个苹果?”
结果如下:
示例1:
Q:“罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?”
A:“罗杰起初有五个网球,又买了两盒网球,每盒3个,所以,他总共买了2×3=6个网球,将起始的数量和购买的数量相加,可以得到他现在总共的网球数量:5+6=11,所以罗杰现在总共有11个网球”问:“食堂总共有23个苹果,如果他们用掉20个苹果,然后又买了6个苹果,请问现在食堂总共有多少个苹果?”
AI推理输出:
食堂起初有23个苹果,用掉20个苹果后,剩余苹果数量为23-20=3个。然后又买了6个苹果,将剩余数量和新买的数量相加,可以得到现在总共的苹果数量:3+6=9个。所以食堂现在总共有9个苹果。
实际上,Few-shot-CoT 的方式虽然有效,但不一定是稳定且准确的。如果想要得到稳定的正确答案,需要更高阶的提示方法。你给的例子越详细,它模仿得就越像。
2.1.4 自动推理与零样本链式思考
零样本思维链(Zero-shot-CoT)这是少样本思维链(Few-shot-CoT)的简化版。只需在提示词末尾加上一句魔法短语,即可激发AI的推理能力。我们只需要在文本末尾通过指令 请一步步进行推理并得出结论,强制AI在给出答案前先进行内部推理。
例如:
罗杰有五个网球,他又买了两盒网球,每盒有3个网球,请问他现在总共有多少个网球?请一步步进行推理并得出结论:
AI的输出可能会变成:
罗杰最初有5个网球。
他买了两盒网球,每盒有3个网球,所以买来的网球数量是:2 × 3 = 6个网球。
因此,他现在总共有网球:5 + 6 = 11个。
答案:11个网球。
请一步步进行推理这个指令,相当于在引导模型的注意力机制。它实际上是在为自己创造一个更丰富、更逻辑化的上下文。其次进行推理,最终得出的结论自然比在贫瘠的上下文中(只有原始问题)更准确。从海量数据的测试结果来看,Few-shot-CoT 比 Zero-shot-CoT 准确率更高。
2.1.5 自我批判与迭代
要求AI在生成答案后,从特定角度对自己的答案进行审查和优化。
核心思想:将“生成”和“评审”两个步骤分离,利用AI的批判性思维来提升内容质量。
适用场景:代码审查、文案优化、论证强化、安全检查。
案例:编写一段代码后进行检查
优化前:
写一个Python函数,计算列表中的最大值。
优化后:
请执行以下两个步骤:
步骤一:编写代码
写一个Python函数 find_max,用于计算一个数字列表中的最大值。
步骤二:自我审查与优化
现在,请从代码健壮性和可读性的角度,审查你上面编写的代码。
请回答:
- 如果输入是空列表,函数会怎样?如何改进?
- 变量命名和代码结构是否清晰?能否让它更易于理解?
- 请根据你的审查,给出一个优化后的最终版本。
3. LLM接入方式
3.1 API 接入
概述
这是目前最主流、最便捷的接入方式,尤其适用于快速开发、集成到现有应用以及不想管理硬件资源的场景。
通过HTTP请求(通常是RESTful API)直接调用模型厂商部署在云端的模型服务。代表厂商:OpenAI(GPT-4o)、Anthropic(Claude)、Google(Gemini)、百度文心一言、阿里通义千问、智谱AI等。
典型流程
- 注册账号并获取API Key:在模型提供商的平台上注册,获得用于身份验证的密钥。
- 查阅API文档:了解接口端点、参数(如模型名称、提示词、温度、最大生成长度等)和返回的数据格式。
- 构建HTTP请求:在你的代码中,使用HTTP客户端(如Python的
requests)构建一个包含API Key认证、请求头和请求体(JSON格式,包含你的提示词)的请求。 - 发送请求并处理响应:将请求发送到提供商指定的API地址,然后解析返回的JSON数据,提取生成的文本。
实操示例(以OpenAI为例)
官网地址:https://platform.openai.com/docs/quickstart
- 登录账号,点击右上角
Settings→API keys配置页面 - 点击「Create new secret key」按钮,新增API密钥,复制保存(仅展示一次,丢失需重新生成)
- 调用方式1:curl命令示例
curl "https://api.openai.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5",
"messages": [{"role": "user", "content": "你好,介绍一下自己"}]
}'
- 调用方式2:HTTP可视化工具(Apifox/Postman)
- 填写请求地址、请求头
Authorization: Bearer 你的Key - 请求体填入标准对话JSON参数,发送后查看完整JSON返回结果
- 填写请求地址、请求头
- 标准返回JSON结构说明
{
"id": "resp-xxxx",
"object": "chat.completion",
"created": 1759120100,
"model": "gpt-5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "你好,我是人工智能助手,有什么可以帮你的吗?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 11,
"completion_tokens": 11,
"total_tokens": 22
},
"temperature": 1.0,
"top_p": 1.0,
"max_tokens": null
}
关键参数说明
model:指定调用的模型名称(gpt-5/gpt-4o等)messages:对话历史,role分user用户、assistant模型、system系统角色设定temperature:温度值0~2,越高生成内容越随机、创造性越强;越低回答越确定、保守top_p:核采样,控制词汇多样性max_tokens:单次输出最大token长度usage:消耗token统计,用于计费
3.2 本地接入
概述
这种方式是将开源的大语言模型(如Llama、Qwen、GLM等)部署在你自己的硬件环境(本地服务器或私有云)中。将模型的文件(权重/配置)部署在私有硬件,使用本地推理框架在本地GPU上加载并运行模型,然后通过类似API的方式进行交互。
典型流程
- 获取模型:从Hugging Face(国外)、魔搭社区(国内)等平台下载开源模型的权重。
- 准备环境:配置具有足够显存(如NVIDIA GPU)的服务器,安装必要的驱动和推理框架。
- 选择推理框架:专门为本地大模型推理优化的框架,例如:
- vLLM:侧重高吞吐、高并发推理,性能极强
- TGIS:Hugging推出的推理框架,功能全面
- Ollama:提供图形化界面,可以一键拉取和运行模型,使用快捷简单
- LM Studio:非常用户友好,本地运行模型,适合快速入门和本地开发
- 启动服务并调用:框架会启动一个本地API服务器(如
http://localhost:8000),你可以像调用云端API一样,向这个本地地址发送请求。
实操示例:Ollama 本地部署
下载并安装 Ollama
- 官网地址:
https://ollama.ai,根据系统选择Windows/macOS/Linux安装包下载 - 一键安装,安装完成后自动后台启动服务
- 验证安装:打开终端执行
ollama --version
# 输出版本号即代表安装成功
- 本地服务默认地址:
http://127.0.0.1:11434
拉取开源模型
- 模型存储路径自定义(可选)
- 方式1:系统环境变量
OLLAMA_MODELS配置存储目录 - 方式2:打开Ollama软件Settings,手动修改模型存储路径,修改后重启Ollama生效
- 方式1:系统环境变量
- 查找模型:官网模型库
https://ollama.com/library
主流模型:Llama3、Qwen(通义千问开源版)、DeepSeek、GLM等,分不同参数量(1.5b/7b/13b/70b)- 参数越小:硬件要求低、推理速度快、理解能力弱
- 参数越大:理解/逻辑能力更强、对显卡显存要求更高
- 终端拉取模型命令示例
# 拉取7B参数DeepSeek大模型
ollama pull deepseek-r1:7b
- 本地对话测试(终端交互)
ollama run deepseek-r1:7b
# 输入提问即可和本地模型对话
本地API调用(兼容OpenAI接口格式)
Ollama本地服务兼容标准Chat Completions接口,curl调用示例:
curl http://127.0.0.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1:7b",
"messages": [{"role": "user", "content": "本地大模型有什么优势?"}],
"stream": false
}'
3.3 SDK 接入
SDK是对HTTP原生API的封装,各大模型厂商会提供对应编程语言SDK(Python/Java/JS等),简化HTTP请求编写。
以OpenAI Python SDK为例:
- 安装依赖
pip install openai
- 极简调用代码
from openai import OpenAI
client = OpenAI(api_key="你的API Key")
response = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": "你好"}]
)
print(response.choices[0].message.content)
优势:自动处理请求头、超时、异常重试、JSON解析,代码更简洁易维护。
4. 嵌入模型
4.1 什么是嵌入模型?
大语言模型是生成式模型。它理解输入并生成新的文本(回答问题、写文章)。它内部实际上也使用嵌入技术来理解输入,但最终目标是“答案”。
而嵌入模型(Embedding Model)是表示型模型。它的目标不是生成文本,而是为输入的文本创建一个最佳的、富含语义的数值表示(向量)。
由于计算机天生擅长处理数字,但不理解文字、图片的含义。嵌入(Embedding)的核心思想就是将人类世界的符号(如单词、句子、产品、用户、图片)转换为计算机能够理解的数值形式(即向量,本质上是一个数字列表),并且要求这种转换能够保留原始符号的语义和关系。
转换流程:文档/单词/句子文本 → Embedding嵌入 → 数字向量 [0.023, 0.487, -0.129, ..., 0.325]
文本经过嵌入模型,都会转换成n维实数向量:
A ⃗ = [ a 1 , a 2 , a 3 , . . . , a n ] , B ⃗ = [ b 1 , b 2 , b 3 , . . . , b n ] \vec{A} = [a_1,a_2,a_3,...,a_n],\quad \vec{B} = [b_1,b_2,b_3,...,b_n] A=[a1,a2,a3,...,an],B=[b1,b2,b3,...,bn]
向量每一个维度代表一层语义特征,两个向量越接近,代表两段文本语义越相似,方向代表含义,长度代表文本的长度,词汇的多少,维度越高,能捕捉的语义复杂度就越强
我们有两种主流数学方法衡量向量远近:欧氏距离、余弦夹角(余弦相似度)。
欧氏距离(Euclidean Distance)
n维空间两点间直线距离:
d ( A ⃗ , B ⃗ ) = ∑ i = 1 n ( a i − b i ) 2 d(\vec{A},\vec{B})=\sqrt{\sum_{i=1}^n (a_i-b_i)^2} d(A,B)=i=1∑n(ai−bi)2
- 数值越小:两个向量空间位置越近 → 语义越相近
- 数值越大:向量相隔越远 → 语义差别越大
- 取值范围: [ 0 , + ∞ ) [0,+\infty) [0,+∞)
- d = 0 d=0 d=0:两段文本完全等价,向量完全重合
但是欧氏距离受向量模长(向量长度)严重干扰。
举个例子:
- 句子1:
今天想吃苹果→ 向量 A ⃗ \vec{A} A - 句子2:
今天想吃苹果、香蕉、西瓜、葡萄、芒果、桃子→ 向量 B ⃗ \vec{B} B
两段文本核心语义完全一致,只是第二句重复叠加同类词汇,向量模长更长。
欧氏距离会算出很大的值,误判二者语义不相似;但余弦相似度会忽略长度、只看方向,正确判定语义接近。
欧氏距离适合:向量模长基本统一、长度没有差异的数据。
嵌入模型输出向量长度各不相同,因此极少单独用欧氏做语义检索。
余弦相似度(Cosine Similarity,RAG/语义搜索标准方案)
余弦相似度计算两个向量夹角的余弦值,只关心向量指向的方向,完全无视向量自身长度。
公式
cos θ = A ⃗ ⋅ B ⃗ ∣ ∣ A ⃗ ∣ ∣ ⋅ ∣ ∣ B ⃗ ∣ ∣ = ∑ i = 1 n a i b i ∑ i = 1 n a i 2 ⋅ ∑ i = 1 n b i 2 \cos\theta = \frac{\vec{A} \cdot \vec{B}}{||\vec{A}|| \cdot ||\vec{B}||} = \frac{\sum_{i=1}^n a_i b_i}{\sqrt{\sum_{i=1}^n a_i^2} \cdot \sqrt{\sum_{i=1}^n b_i^2}} cosθ=∣∣A∣∣⋅∣∣B∣∣A⋅B=∑i=1nai2⋅∑i=1nbi2∑i=1naibi
- A ⃗ ⋅ B ⃗ \vec{A}\cdot\vec{B} A⋅B:向量点积
- ∣ ∣ A ⃗ ∣ ∣ ||\vec{A}|| ∣∣A∣∣:向量 A ⃗ \vec{A} A的模长
取值范围 [ − 1 , 1 ] [-1, 1] [−1,1]
- cos θ = 1 \cos\theta = 1 cosθ=1:夹角0°,向量方向完全相同 → 语义高度一致
- cos θ = 0 \cos\theta = 0 cosθ=0:夹角90°,向量垂直 → 两段文本毫无关联
- cos θ = − 1 \cos\theta = -1 cosθ=−1:夹角180°,向量反向 → 语义完全相反
为什么语义场景优先余弦?
- 消除文本长度干扰
长短不同但核心意思一样的句子,向量模长差距大,但方向一致,余弦相似度依然接近1,完美适配长短不一的文档、问句。 - 匹配嵌入模型特性
主流Embedding模型训练目标就是:语义相近文本向量同向,无关文本向量垂直,天然适配余弦度量。 - RAG、向量库行业标准
Chroma、FAISS、Milvus、PGVector全部默认使用余弦相似度做语义检索。
4.2 嵌入模型应用场景
根据嵌入的特性,由此延伸出了许多嵌入模型在AI应用的使用场景:
语义搜索(Semantic Search)
传统搜索:依赖关键词匹配(搜“苹果”,只能找到包含“苹果”这个词的文档)。
语义搜索:则能将查询和文档都转换为向量,通过计算向量间的相似度来找到相关内容,即使文档中没有查询的确切词汇也能被检索到。
举例:知识库中并未直接出现“笔记本电脑无法充电”这个词组,语义搜索也能通过向量相似度精准地找到相关文档。

检索增强生成(Retrieval-Augmented Generation, RAG)
这是当前大语言模型应用的核心模式。当用户向LLM提问时,系统首先使用嵌入模型在知识库(如公司内部文档)中进行语义搜索,找到最相关的内容,然后将这些内容和问题一起提交给LLM来生成答案。这极大地提高了答案的准确性和时效性。
举例:一家公司的内部客服机器人接到员工提问:“我们今年新增加的带薪育儿假政策具体是怎样的?”
系统首先使用嵌入模型在公司的最新人事制度文档、福利更新备忘录等资料中进行语义搜索,找到关于“今年育儿假规定”的具体条款,后将这些【条款】和【问题】一起提交给LLM,LLM便能生成一个准确、具体的摘要回答,而非仅凭其内部训练数据可能产生的过时或泛泛的答案。

推荐系统(Recommendation Systems)
将用户**(根据其历史行为、偏好)和物品(商品、电影、新闻)**都转换为向量。喜欢相似物品的用户,其向量会接近;相似的物品,其向量也会接近。通过计算用户和物品向量的相似度,就可以进行精准推荐。

异常检测(Anomaly Detection)
正常数据的向量通常会聚集在一起。如果一个新数据的向量远离大多数向量的聚集区,它就可能是一个异常点(如流量异常、欺诈交易)。
4.3 主流的嵌入模型
-
text-embedding-3-large (OpenAI)
OpenAI最强大的英语和非英语任务嵌入模型。默认维度3072,可降维加1024维;输入令牌长度支持为8192。 -
Qwen3-Embedding-8B (阿里通义千问)
开源模型,支持100种语言;上下文长度32k;嵌入维度最高4096,支持自定义的输出维度,范围从32到4096。推理需要一定的GPU计算资源(例如,至少需要16GB以上显存的GPU才能高效运行)。 -
gemini-embedding-001 (Google)
支持100+种语言;默认维度3072,可选降维版本:1536维或768维;输入令牌长度支持为2048。
4.4 嵌入模型接入方式
4.4.1 API 接入
这是最快速、最简单的方式,无需管理任何基础设施。只需要向模型提供商的服务端发送一个 HTTP 请求即可。
适用模型:text-embedding-3-large,gemini-embedding-001 等。
- 注册账号并获取API Key:在对应的云服务平台(如OpenAI Platform, Google AI Studio/Vertex AI)注册账号,获取用于身份验证的API Key。
- 安装SDK或构造HTTP请求:使用官方提供的SDK(如
openai,google-generativeai)或直接构造HTTP请求。 - 调用API并处理响应:发送文本,接收返回的JSON格式的向量数据。
示例1:发起 HTTP 请求
curl https://api.openai.com/v1/embeddings
-H "Content-Type: application/json"
-H "Authorization: Bearer $OPENAI_API_KEY"
-d '{
"input": "Your text string goes here",
"model": "text-embedding-3-small"
}'
响应包含嵌入向量(浮点数列表)以及一些其他元数据:
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
-4.547132266452536e-05,
-0.024047505110502243
],
}
],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 5,
"total_tokens": 5
}
}
示例2:接入 SDK
安装库:
pip install openai
示例代码:
# 使用 OpenAI Python SDK
from openai import OpenAI
import os
# 1. 设置 API Key
client = OpenAI(api_key="your-api-key")
# 2. 准备输入文本
text = "这是一段需要转换为向量的文本。"
# 3. 调用 API
response = client.embeddings.create(
model="text-embedding-3-large", # 指定模型
input=text,
dimensions=1024 # 可选:指定输出维度,例如从3072维降到1024
)
# 4. 获取向量
embedding = response.data[0].embedding
print(f"向量维度: {len(embedding)}")
print(embedding)
4.2 本地部署
这种方式需要自行准备计算资源(通常是带有GPU的机器)来运行模型,适合对数据隐私、成本和控制权有更高要求的场景。
适用模型:Qwen3-Embedding-8B 等。
- 环境准备:准备一台有足够GPU显存的服务器(对于Qwen3-Embedding-8B,需要至少16GB以上显存)。
- 模型下载:从 Hugging Face 等模型仓库下载模型权重文件和配置文件。
- 代码集成:使用像
transformers这样的库来加载模型并进行推理。
无论是通过API还是本地部署获得向量,下一步通常都是将它们存入向量数据库(如Chroma, Milvus, Pinecone等)以供后续检索。为了便于切换不同的嵌入模型,很多项目会使用像LangChain这样的框架,它们提供了统一的嵌入模型接口。
5. LangChain引入
首先需要搞懂,原生的LLM直接调用会产生哪些问题?
- 幻觉问题:回答不合乎情理的答案,在编码中最直接的体现就是调用错误并且致命的借口等;
- 需要统一提示词:完整的提示词可以大幅提高LLM回答的准确度以及质量;
- 不方便切换模型:需要直接更改请求header,这极大影响了开发的便捷性;
- 无法提供结构化数据:LLM直接返回的形式是文字,不能通过返回带有字段的数据格式;
- LLM的知识库往往不是最新的,无法获取实施信息,存在信息落差;
- 单个API请求无状态,每次请求都是独立的,无法实现上下文多轮对话,必须手动拼接历史消息;
- 无法读取私有知识库,进行更加标准、符合事实的向量检索以及回答功能;
下面是langchain对上述问题的解决方案:
- 针对幻觉、提示词规范:采用提示词工程和检索增强生成(RAG)。为医疗助手设计严谨、系统的提示词模板,并强制模型在回答前先从权威、实时的医疗知识库中检索信息,而不是仅凭记忆回答。
- 针对模型切换:使用 LLM API 抽象层(如 LangChain)。这些中间件统一了不同模型的接口,让开发者通过配置而非修改代码来切换模型。
- 针对非结构化输出:采用输出解析技术。强制要求模型以 JSON 等格式输出,并在提示词中严格定义 JSON 的 Schema。一些框架(如 LangChain)可以自动将模型输出解析为预定义的 Pydantic 对象。
- 针对知识陈旧:主要依靠 RAG 来注入实时、外部的知识。
- 针对连接外部工具:采用智能体(Agent)框架。让 LLM 作为大脑,根据用户请求规划步骤、选择工具(如计算器、数据库API、搜索引擎),并执行任务。
做一个小点补充:
RAG的一个详细过程:
以构建一个**“基于公司文档的问答机器人”**为例,展示一个典型的 NLP 任务从数据输入到最终输出的 5 个关键阶段(在业界,这套标准流程通常被称为 RAG,即检索增强生成):
- 文档加载 (Document Loading)
• 目标:收集并读取外部数据。
• 过程:系统首先需要接入各种不同类型的数据源。这些数据源可以是在线的网页链接(URLs)、本地或云端的 PDF 文件(PDFs),也可以是结构化的数据库(Database)。经过加载后,它们被统一转换为系统可处理的“文档(Documents)”。- 文本分割 (Splitting)
• 目标:化整为零,适应模型限制。
• 过程:因为大语言模型通常有单次处理文本长度(上下文窗口)的限制,所以需要将上一步得到的大篇幅文档,按照一定的规则切割成较小的“文本片段(Splits)”,以便后续处理。- 存储 (Storage)
• 目标:将文本转化为计算机能理解的数学形式并保存。
• 过程:“将文本转换为向量(嵌入)”。这些切割好的文本片段会被转化为多维向量,并统一存储在专门的 “向量数据库(Vectorstore)” 中。这种形式非常利于计算机快速计算文本之间的语义相似度。- 检索 (Retrieval)
• 目标:精准定位用户所需的信息。
• 过程:当系统接收到用户的查询问题(Query )后,系统会将问题也转化为向量,并在向量数据库中进行相似度搜索。最终,系统会提取出与用户问题最匹配、最相关的那些文本片段(Relevant Splits)。- 输出 (Output)
• 目标:结合上下文,生成并返回最终答案。
• 过程:系统将“相关的文本片段”与用户最初的“查询问题”组合在一起,构建成一个完整的提示词(Prompt)。这个包含丰富背景知识的提示词被发送给大语言模型(LLM)。LLM 经过阅读和推理,最终生成并向用户返回准确的答案。
5.1 LangChain 常见组件
所有组件都遵循统一抽象基类,独立解耦、可插拔替换,分为十大核心类别:
1. 模型组件(Models)
负责大模型/嵌入向量计算,分两类:
ChatModel:对话大模型(通义千问、OpenAI、Claude、本地Qwen等),输出结构化对话消息Embeddings:嵌入模型(文本向量化,如text-embedding、qwen3-embedding-8b),把文本转为语义向量
2. 文档加载组件(Document Loaders)
读取各类数据源,统一输出标准Document对象(page_content页面文本+metadata元数据)
- 文件:PDFLoader、TextLoader、DocxLoader
- 网页:WebBaseLoader
- 数据库:SQLDatabaseLoader
3. 文本分割组件(Text Splitters)
切割长文档为小块,适配模型上下文长度限制
- RecursiveCharacterTextSplitter(最常用递归分割)
- SemanticChunker(语义分割,按语义断点切分)
4. 向量存储组件(VectorStores)
存放文本向量,提供相似度检索能力
- 轻量本地:Chroma、FAISS
- 生产向量库:Milvus、PGVector、Pinecone
统一提供add_texts()入库、similarity_search()检索接口
5. 检索组件(Retrievers)
封装向量库查询逻辑,做检索增强,上层业务不感知底层向量库
- VectorStoreRetriever(基础相似度检索)
- MultiQueryRetriever(多查询重写优化检索)
- ParentDocumentRetriever(父文档精准检索)
6. 提示词组件(Prompts)
标准化管理输入大模型的提示模板
- ChatPromptTemplate:对话模板,支持变量插值
- SystemMessagePromptTemplate:系统角色提示
- HumanMessagePromptTemplate:用户输入模板
7. 输出解析组件(Output Parsers)
约束LLM输出格式,把自由文本转为结构化数据
- JsonOutputParser:强制输出JSON
- PydanticOutputParser:绑定实体类,自动校验字段
- StrOutputParser:简单提取文本字符串
8. 记忆组件(Memory)
维护多轮对话上下文,解决LLM无状态问题
- ConversationBufferMemory:完整保存全部历史
- ConversationWindowMemory:仅保留最近N轮对话
- RedisChatMessageHistory:持久化对话记录
9. 工具组件(Tools)
外部可调用能力,给Agent使用
- 内置:计算器、搜索引擎、SQL查询工具
- 自定义:企业内部API、业务接口
10. 智能体组件(Agents)
调度LLM自主选择工具、拆解多步骤复杂任务
- AgentExecutor:Agent执行器,循环思考-调用工具-回答
链式执行完整数据流
用户输入问题:今年带薪育儿假政策是什么?
-
第一层:retriever 检索组件
输入:{"question": "今年带薪育儿假政策是什么?"}
内部逻辑:将问题向量化,去向量库匹配3段最相关制度文本
输出:{"context": [文档片段1,文档片段2,文档片段3], "question": "..."} -
第二层:prompt 提示词组件
接收上一层输出的context+question,自动填充模板变量,拼接完整提示消息
输出:格式化后的对话消息列表(系统提示+用户问题+参考资料) -
第三层:llm 大模型组件
接收拼接完成的Prompt消息,调用阿里通义千问API生成回答文本
输出:LLM返回的完整AI回复对象 -
第四层:parser 输出解析组件
提取模型返回内容里的纯文本答案,剔除多余元数据
输出:最终可读答案字符串
6. LangGraph引入
6.1 LangChain的局限性
LangGraph 是 LangChain 生态系统中晚些出现的一个框架,其诞生背景与大型语言模型应用日益增长的复杂性密切相关。随着开发者尝试构建更高级的 AI 代理和多轮对话系统,传统链式结构具有局限性:
- 链式流程通常是线性的、预先定义好的步骤,难以处理需要循环、分支或长期状态维护的复杂场景。
- 此外,在构建多智能体协作、需要人工介入(Human-in-the-loop)或长时间运行的任务时,需要更灵活的工作流管理和状态持久化支持。
用传统的 Chain A -> Chain B -> Chain C 的线性结构来构建,会遇到以下具体问题:难以处理循环和分支(无法动态路由和多次询问);状态维护困难(无法长时间运行和记忆上下文);难以融入人工介入(Human-in-the-loop);僵化的流程(无法根据条件动态跳转)不同的用户意图需要完全不同的子流程。
也就是说,链式流程是单向的,是LangChain的主动行为,并不是人工流程一步一步进行的,如果想要回到走过的流程或者有其他改动,则需要人工干预,这时候就需要额外手动维护系统状态并且人工干预较为困难,LangGraph很好解决了这些问题:
对于简单的线性任务,LangChain的链式结构已经足够高效; 而对于需要复杂控制流、长期状态和多智能体的场景,LangGraph 提供了更强大的支持。
更多推荐


所有评论(0)