前端转agent-【python】-12 LangChain 入门实战:RAG + LCEL 链式调用

前端转agent-【python】-12 LangChain 集成:用框架快速搭建 RAG 与链

之前我们用纯 Python 手写了记忆管理、语义检索、状态图和工具调用。轮子造得爽,但生产环境总该有更快的办法。

LangChain 就是这些轮子的"标准化工厂",把常见模式封装成可组合的模块。

今天用 LangChain 重写我们的 RAG 流程,再用 LCEL(LangChain Expression Language)串一条问答链,感受"搭积木"的快感。

为什么学 LangChain?

手写版本(07/09) LangChain 对应 类比 Vue 3
手动管理消息列表 ChatPromptTemplate + MessagesPlaceholder 自己写 reactive 对象 vs 用 useChatMessages
ollama.chat() ChatOllama 直接 fetch vs 用 useFetch
手写 ChromaDB 检索逻辑 Chroma vectorstore + Retriever 手写 IndexedDB 查询 vs 用 useVectorStore
手动拼接上下文 create_stuff_documents_chain 手动拼接 props vs 用 v-bind 自动展开

LangChain 不改变底层原理,只是把"手动拼字符串、手动调 API"变成声明式链式调用。理解原理后用它,事半功倍。

环境准备

bash 复制代码
pip install langchain langchain-ollama langchain-chroma sentence-transformers

模型:

bash 复制代码
ollama pull qwen3:4b

用 LangChain 重写 RAG 流程

RAG(检索增强生成)的核心是:把相关文档片段注入提示词,让 LLM 基于这些内容回答

之前我们用 ChromaDB 手动检索,然后手动拼接 messages。现在用 LangChain 自动化。

第一步:准备文档并建立向量存储

python 复制代码
# rag_with_langchain.py
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_chroma import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.documents import Document

# 模拟产品文档
docs = [
    Document(page_content="智能手表续航7天,支持IP68防水。", metadata={"source": "specs"}),
    Document(page_content="退货政策:7天内无理由退货,30天内质量问题换货。", metadata={"source": "policy"}),
    Document(page_content="客服电话:400-123-4567,工作时间9:00-18:00。", metadata={"source": "contact"}),
]

# 分割文本(正式项目可调整参数)
splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
chunks = splitter.split_documents(docs)

# 嵌入模型(使用 Ollama 本地嵌入,需要先 pull 嵌入模型)
# ollama pull nomic-embed-text   (小型嵌入模型)
embedding_model = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embedding_model,
    persist_directory="./langchain_chroma_db"  # 持久化目录
)

注意 :Ollama 需要一个嵌入模型,这里用 nomic-embed-text,请先拉取:

bash 复制代码
ollama pull nomic-embed-text

第二步:构建检索链

python 复制代码
# rag_with_langchain.py(接上段)
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain

# 定义 LLM
llm = ChatOllama(model="qwen3:4b", temperature=0)

# 提示词模板
prompt = ChatPromptTemplate.from_template("""
你是一个电商客服助手。根据以下已知信息回答问题。
如果找不到答案,请说"暂时没有相关信息"。

已知信息:
{context}

用户问题:{input}
回答:
""")

# 创建"填充文档"链:将检索到的文档填入 prompt 的 {context}
combine_docs_chain = create_stuff_documents_chain(llm, prompt)

# 创建完整的 RAG 链:检索 + 生成
rag_chain = create_retrieval_chain(
    retriever=vectorstore.as_retriever(search_kwargs={"k": 2}),
    combine_docs_chain=combine_docs_chain
)

对比手写版

  • 手写时要 query -> embedding -> search -> 取文档 -> 拼字符串 -> 调 llm
  • LangChain 只需定义 retrieverprompt,一行 create_retrieval_chain 完成。

第三步:测试 RAG

python 复制代码
# 接 rag_with_langchain.py
result = rag_chain.invoke({"input": "手表防水吗?"})
print(result["answer"])
# 输出:是的,智能手表支持IP68防水。

result2 = rag_chain.invoke({"input": "怎么退货?"})
print(result2["answer"])
# 输出:7天内无理由退货,30天内质量问题换货。

用 LCEL 构建更灵活的链

LCEL(LangChain Expression Language)是 LangChain 的"管道操作符" |,让链的定义像 Unix 管道一样直观。

python 复制代码
# lcel_demo.py
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 自定义 prompt
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个幽默的助手,用一句话回答。"),
    ("user", "{input}")
])

# LCEL 链:prompt -> llm -> 解析器
chain = prompt | llm | StrOutputParser()

# 调用
print(chain.invoke({"input": "什么是人工智能?"}))
# 可能输出:人工智能就是让电脑学会偷懒还能领工资(开玩笑啦)。

加上检索的 LCEL 写法

python 复制代码
# lcel_rag.py
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

rag_chain_lcel = (
    {
        "context": vectorstore.as_retriever() | format_docs,
        "input": RunnablePassthrough()
    }
    | prompt
    | llm
    | StrOutputParser()
)

print(rag_chain_lcel.invoke("客服电话多少?"))
# 输出:客服电话是400-123-4567,工作时间9:00-18:00。

Vue 3 类比 :LCEL 就像 Vue 的模板编译,| 操作符如同管道 |RunnablePassthrough() 相当于 props 透传。整个过程是响应式的:输入一变,链自动重跑。

将之前的工具调用改造成 LangChain Agent

LangChain 内置了 create_tool_calling_agent + AgentExecutor,它能自动解析 LLM 输出的工具调用并循环执行。对比如下:

python 复制代码
# tool_agent_langchain.py
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate

@tool
def get_weather(city: str) -> str:
    """查询指定城市的天气"""
    return {"北京":"晴","上海":"雨"}.get(city, "未知")

@tool
def calculator(expression: str) -> str:
    """计算数学表达式"""
    try:
        return str(eval(expression, {"__builtins__": {}}))
    except:
        return "计算错误"

llm = ChatOllama(model="qwen3:4b")
tools = [get_weather, calculator]
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个助手,可以使用工具。"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}")  # 工具调用的中间步骤
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)

result = agent_executor.invoke({"input": "北京天气和 3*9 是多少?"})
print(result["output"])

自动循环AgentExecutor 内部就是一个 while 循环,直到 LLM 不再调用工具,完全替代了之前我们手写的 LangGraph 循环。

Vue 3 横向总结

| LangChain 概念 | Vue 3 类比 |
|--------------------------------|------------------------------------|-----------------------------------------------|
| ChatPromptTemplate | 组件模板,{{ variable }} 占位 |
| create_stuff_documents_chain | 一个组合式函数,内部处理文档拼接 |
| create_retrieval_chain | 封装了异步检索和生成的 useQuery |
| LCEL ` | ` 管道 | Vue 的 computed(() => ...)transform 函数链 |
| @tool 装饰器 | 定义一个 action 方法,框架自动暴露给 LLM |
| AgentExecutor | 内置 while 循环的状态机,类似我们之前写的 LangGraph |

什么时候用 LangChain,什么时候用 LangGraph?

  • LangChain:适合标准流程(RAG、普通链、简单工具调用),开箱即用。
  • LangGraph:适合复杂状态机、多分支、需要检查点和中断的自定义流程。

两者来自同一团队,可以无缝混用。

总结

  • LangChain 把之前我们手写的逻辑封装成了模块,代码量减少 50% 以上。
  • 核心还是消息列表、检索、提示词、工具调用------理解原理后用它,如虎添翼。
  • 对于 Vue 3 开发者来说,LangChain 就是 AI 领域的"VueUse + 状态管理",让你快速搭建可靠的应用。
  • 建议先学原理再学框架,现在你可以自信地说:我不只会用 LangChain,我知道它下面怎么跑。

开始你的"搭积木"之旅吧:

bash 复制代码
python rag_with_langchain.py
相关推荐
水如烟7 分钟前
孤能子视角:智能系统的持续学习——从关系场存续到模块化生长
人工智能
做一个码农都是奢望8 分钟前
0722 LLM及其科研进展
人工智能
饼饼学习空间智能17 分钟前
2026数字孪生国产化进入“交付验证期”:五类头部企业能力与项目选型分析
人工智能
海兰27 分钟前
【高速缓存】RedisVL为文本生成嵌入向量实践指南
人工智能·python·机器学习
user-猴子39 分钟前
让网页“活”过来 —— 用AI打造会自主学习的动态知识图谱
人工智能·学习·知识图谱
苦瓜小生39 分钟前
AI名词大扫盲!最全的面试ai名词集合
人工智能·面试
KaMeidebaby40 分钟前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
晚笙coding40 分钟前
KnowFlow Agent Day10:实现文档切片与数据保存
人工智能
Litluecat1 小时前
2026年7月21日科技热点新闻
人工智能·科技·搜索引擎·新闻·每日
千维百策6661 小时前
运用 SRE 原则降低生产事故影响:CRE 实战经验与可靠性优化方法
网络·数据库·人工智能