LangChain基础
大约 3 分钟
主要模块
LangChain主要模块包括Model、Prompt、Chain、Retrieval、Agent、Tool,在基础部分可以节省很多时间,但是对于Chain这块的LCEL写法,感觉完全没必要,自己封装反而更容易Debug。
1. Model
Model模块提供了对接不同大模型的功能,主要包括大模型LLM、ChatModel和向量化模型Embedding
1.1 LLM & CHatModel
LLM和ChatModel类似,但是随着技术的演进,基本上只用ChatModel就好了,ChtModel能更好地处理复杂交互、角色设定和上下文管理。
- LLM是早期的模块,设计目的是用来做文本补全、文本生成,所以输入输出都是字符串格式。
- ChatModel,设计目的是用来做多轮对话,输入输出都变成了结构化的消息列表。
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
llm = ChatOpenAI(
model="DeepSeek-V3-0324",
base_url="xxx",
api_key="xxx"
)
messages = [
SystemMessage(content="你是AI助手,名叫多比"),
HumanMessage(content="你好,请问你是谁")
]
res = llm.invoke(messages)
print(res.content)
# 输出
# 你好!我是多比,你的AI助手。随时为你提供帮助和解答问题!有什么可以帮你的吗?😊
这里的输出是Block的,想要打字机效果的话,可以使用stream
for chunk in llm.stream(messages):
print(chunk.content, end="")
# 打字机输出
# 你好!我是多比,你的AI助手,随时为你提供帮助和解答问题。有什么我可以帮你的吗?😊
1.2 Embedding
Embedding模型用来将文本进行向量化。举个例子,“吃饭”和“用餐”在字面上是完全不同的,但是在语义上却非常相近。Embedding模型就是挖掘背后的语义信息,并映射为高维度向量,最后通过计算向量的相似度来判断语义上的相似性。
from langchain.embeddings import OpenAIEmbeddings
embd = OpenAIEmbeddings(
openai_api_key="xxx",
openai_api_base="xxx"
)
res = embd.embed_query("你好")
print(res)
2. Prompt
LangChain的Prompt维护了占位{}、格式化的逻辑,能够动态的填充参数。最后,这个Prompt可以用于之前的Message列表,填充到LLM的上下文中。
from langchain.prompts import ChatPromptTemplate
template = "今天的日期是{date}"
prompt = ChatPromptTemplate.from_messages(
("system", template)
)
final_prompt = template.format(date="2000-01-01")
print(final_prompt)
# 今天的日期是2000-01-01
3. Chain
不建议使用,感觉有点过度封装,可以自己搓一个简单的就行了
from langchain_core.prompts import ChatPromptTemplate
from datetime import datetime, timezone
# 使用模板字符串的方式
prompt = ChatPromptTemplate.from_messages([
("system", "你是AI助手,名叫多比"),
("system", "当前时间: {time}"),
("human", "用户问题: {input}"),
])
def chain(input: str):
format_messages = prompt.format_messages(
time=str(datetime.now(timezone.utc)),
input=input
)
print(format_messages) #这里会看到占位符已经被替换了
return llm.invoke(format_messages).content
4. Retrieval
Retrieval,也就是RAG中的R。这里会用到1.2中的Embedding模型,以及向量数据库,共同组成知识库
from langchain.document_loaders import TextLoader
# load
loader = TextLoader("data.txt")
documents = loader.load()
from langchain.text_splitter import CharacterTextSplitter
# chunk
text_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=10)
docs = text_splitter.split_documents(documents)
for d in docs:
print(d)
from langchain_community.embeddings import XinferenceEmbeddings
embeddings = XinferenceEmbeddings(
server_url="http://172.16.160.4:9998",
model_uid="bge-m3"
)
from langchain.vectorstores import Chroma
# 纯内存, just a test
db = Chroma.from_documents(
documents=docs,
embedding=embeddings,
persist_directory=None
)
query = "LLM模型的关键技术"
docs = db.similarity_search(query, k=2)
print(docs[0].page_content)
# Q: LLM模型的关键技术
# A: 扩展、训练、能力引导、对齐微调、工具操作
5. Agent & Tool
LangChain给的了很多预定义的Agent和Tool,下面是一个查天气的demo。对于更细致的Agent,还是建议用LangGraph来做
from langchain.agents import Tool, initialize_agent, AgentType
import re
def weather(location: str):
location = str(location).strip()
location = re.sub(r'[\'"\n]', '', location)
location = location.strip()
if location == "北京":
return f"{location}阴天,气温14度"
elif location == "天津":
return f"{location}晴天,气温21度"
else:
return f"无法获取'{location}'的天气信息,当前支持:北京、天津"
tools = [
Tool(name="weather",func=weather,description="查询天气")
]
# ReAct模式, 还有很多模式可以在AgentType里看
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True # 打印过程
)
result = agent.run("北京和天津的天气怎么样")
print(result)
# 北京今天是阴天,气温14度;天津今天是晴天,气温21度。