如何用Python LangChain十分钟玩转阿里通义千问?
摘要:本文全程基于 Python + LangChain 框架,带你从0 到 1搭建基于阿里通义千问大模型的应用,从最简单的一次性对话,逐步进阶到循环对话、上下文记忆、工具调用、企业级知识库,完整覆盖大模型应用的核心能力。 前置
本文全程基于 Python + LangChain 框架,带你从0 到 1搭建基于阿里通义千问大模型的应用,从最简单的一次性对话,逐步进阶到循环对话、上下文记忆、工具调用、企业级知识库,完整覆盖大模型应用的核心能力。
前置准备
环境配置
安装依赖包
pip install langchain langchain-community langchain-core python-dotenv
获取阿里通义千问 API Key
登录阿里云百炼平台
创建 API-KEY,保存备用
项目根目录创建 .env 文件,存放密钥:
DASHSCOPE_API_KEY=你的阿里通义千问API_KEY
一、基础入门:一次性对话(无记忆、无交互)
这是大模型应用的最小单元,仅实现单次提问、单次回答,无任何额外能力。
核心代码
from langchain_community.chat_models import ChatTongyi
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
load_dotenv()
llm = ChatTongyi()
message = [HumanMessage(content="介绍下你自己")]
print(llm.invoke(message).content)
测试效果
核心知识点
ChatTongyi:langchain_community 封装的阿里通义千问对话大模型调用类
invoke():同步调用大模型的核心方法
适用场景:简单的一次性问答、批量文本处理
二、进阶交互:循环对话(控制台持续聊天)
在基础上实现控制台持续对话,用户可以反复提问,直到主动退出。
核心代码
from langchain_community.chat_models import ChatTongyi
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage
load_dotenv()
llm = ChatTongyi()
print("循环对话: 输入exit推出!\n")
while True:
user_input = input("你:")
if user_input == "exit":
break
message = [HumanMessage(content=user_input)]
aimessage = llm.invoke(message)
print(f"AI:{aimessage.content}\n")
测试效果
核心知识点
实现了交互式终端,贴近真实聊天工具的使用体验
缺陷:无记忆能力,模型不知道你上一轮说了什么(上次对话告诉了大模型我的名字,下次对话再问它它就不知道了)
三、核心能力:上下文记忆(记住历史对话)
大模型应用的核心能力:让模型记住多轮对话历史,实现连贯聊天。
简版上下文记忆
核心代码(记录每次对话 + 请求大模型时将所有历史会话扔给大模型)
from langchain_community.chat_models import ChatTongyi
from dotenv import load_dotenv
from langchain_core.messages import HumanMessage, AIMessage
load_dotenv()
llm = ChatTongyi()
messages = []
print("循环对话(带上下文记忆): 输入exit推出!\n")
while True:
user_input = input("你:")
if user_input == "exit":
break
messages.append(HumanMessage(content=user_input))
aimessage = llm.invoke(messages)
messages.append(AIMessage(content=aimessage.content))
print(f"AI:{aimessage.content}\n")
测试效果
核心知识点
messages:简化板记忆组件,就是一个数组,存储完整对话历史(输入信息HumanMessage,AI的回复AIMessage)
后面我们会再使用LangChain中封装的记忆类型扩展以及对话连(可以实时总结记忆,节省token)
四、高级扩展:工具调用(让大模型会查天气、查时间)
大模型本身无法联网、无法计算,通过工具调用赋予模型实时能力。
示例:给大模型添加「查询时间、获取天气」
import datetime
import requests
from dotenv import load_dotenv
from langchain_community.chat_models import ChatTongyi
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_core.tools import tool
load_dotenv()
# ===== 1. 定义工具函数 =====
@tool
def get_current_time() -> str:
"""获取当前日期和时间"""
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@tool
def get_weather(city):
"""获取天气信息"""
url = f"https://uapis.cn/api/v1/misc/weather?city={city}"
response = requests.get(url)
data = response.json()
return data
tools = [get_current_time, get_weather]
# ===== 2. 初始化 LLM 并绑定工具 =====
llm = ChatTongyi(model="tongyi-xiaomi-analysis-pro", temperature=0.7)
llm_with_tools = llm.bind_tools(tools) # 👈 关键:启用工具调用能力
# ===== 3. 手动维护对话历史 =====
messages = [] # 扁平消息列表:HumanMessage / AIMessage / ToolMessage
print("欢迎使用带工具的 AI 助手!输入 exit 退出:")
while True:
user_input = input("你: ")
if user_input == "exit":
break
# 添加用户消息
messages.append(HumanMessage(content=user_input))
# 第一次调用:可能返回 tool_calls
ai_response = llm_with_tools.invoke(messages)
# 如果模型要求调用工具
if hasattr(ai_response, 'tool_calls') and ai_response.tool_calls:
# 保存模型的 tool_call 请求(用于上下文)
messages.append(ai_response)
# 执行所有工具调用
for tool_call in ai_response.tool_calls:
tool_name = tool_call["name"]
tool_args = tool_call["args"]
# 查找对应工具
func = next((t for t in tools if t.name == tool_name), None)
if func:
result = func.invoke(tool_args) # 执行工具
else:
result = f"工具 '{tool_name}' 未找到"
# 将工具结果作为 ToolMessage 加入上下文
messages.append(ToolMessage(
content=str(result),
tool_call_id=tool_call["id"]
))
# 再次调用 LLM,让它基于工具结果生成最终回答
ai_response = llm.invoke(messages)
# 添加到记忆中
messages.append(ai_response)
print(f"AI: {ai_response.content}\n")
测试效果
具体流程
先来看下 messages 变量的值,根据这个值我们可以看到整个对话的流程
流程图:
第一轮对话:查询日期
用户输入:HumanMessage(content='今天的日期是多少')
LLM 决策:识别到需要实时信息,生成 AIMessage 并携带 tool_calls,请求调用 get_current_time() 工具
工具执行:执行 get_current_time(),返回 ToolMessage(content='2026-03-29 11:06:05')
生成回答:LLM 结合工具结果,生成最终 AIMessage(content='2026-03-29')
第二轮对话:查询天气(上下文延续)
用户输入:HumanMessage(content='今天北京的天气怎么样')(基于上一轮对话的上下文)
LLM 决策:识别到需要外部天气数据,生成 AIMessage 并携带 tool_calls,请求调用 get_weather(city="北京")
工具执行:执行 get_weather("北京"),返回包含详细天气数据的 ToolMessage
生成回答:LLM 整理工具结果,生成最终 AIMessage 自然语言回答
🧠 核心机制说明
上下文记忆:所有 HumanMessage / AIMessage / ToolMessage 都被追加到 messages 列表中,LLM 每次调用都基于完整历史上下文进行推理
工具调用流程:
LLM 判断是否需要工具
生成结构化 tool_calls 指令
执行工具并返回 ToolMessage
LLM 结合工具结果生成最终回答
消息类型:
HumanMessage:用户输入
AIMessage:AI 回复或工具调用指令
ToolMessage:工具执行结果
五、企业级应用:私有知识库问答(RAG)
大模型的终极落地形态:基于私有文档回答问题,不泄露数据,不依赖模型固有知识。
新增依赖
pip install langchain-text-splitters faiss-cpu pypdf
核心代码(RAG 知识库)
import datetime
import requests
from dotenv import load_dotenv
from langchain_community.chat_models import ChatTongyi
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_core.tools import tool
from langchain_text_splitters import RecursiveCharacterTextSplitter
load_dotenv()
# ===== 1. 构建向量知识库 =====
class VectorKnowledgeBase:
"""基于 FAISS 的向量知识库"""
def __init__(self, embedding_model="multimodal-embedding-v1"):
self.embedding_model = DashScopeEmbeddings(model=embedding_model)
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
length_function=len
)
self.vectorstore = None
self.documents = []
# 初始化知识库数据
self._load_mock_data()
self._build_vectorstore()
def _load_mock_data(self):
"""加载模拟数据"""
mock_data = [
# 公司信息
Document(
page_content="未来科技有限公司成立于 2020 年,位于北京市海淀区中关村,是一家专注于人工智能、云计算、大数据分析的高新技术企业。公司现有员工 500 人,CEO 是张三先生。",
metadata={"category": "company", "type": "overview"}
),
Document(
page_content="公司联系方式:邮箱 contact@futuretech.com,电话 400-888-9999,地址:北京市海淀区中关村科技园 88 号。",
metadata={"category": "company", "type": "contact"}
),
# 产品信息
Document(
page_content="智能客服系统 v3.0:基于大模型的智能客服解决方案,支持自然语言理解、多轮对话、情感分析等功能,可帮助企业提升客服效率 80%。价格:¥99,999/年。",
metadata={"category": "products", "type": "customer_service"}
),
Document(
page_content="数据分析平台 v2.5:企业级大数据分析平台,支持实时数据处理、可视化报表、机器学习建模等功能,已服务超过 1000 家企业客户。价格:¥199,999/年。",
metadata={"category": "products", "type": "analytics"}
),
Document(
page_content="云存储系统 v1.8:安全可靠的云存储解决方案,提供 99.99% 的数据持久性,支持自动备份、版本控制、权限管理等功能。价格:¥49,999/年起。",
metadata={"category": "products", "type": "cloud_storage"}
),
# 政策制度
Document(
page_content="工作时间制度:工作日为周一至周五,上班时间为 7:00-19:00,中午休息 1 小时。弹性工作制,核心工作时间为 10:00-16:00。",
metadata={"category": "policies", "type": "work_hours"}
),
Document(
page_content="休假政策:员工享有带薪年假 15 天,带薪病假 7 天,以及国家法定节假日。工作满一年后每年增加 1 天年假。",
metadata={"category": "policies", "type": "vacation"}
),
Document(
page_content="福利保障:公司为员工缴纳五险一金(养老保险、医疗保险、失业保险、工伤保险、生育保险、住房公积金),并提供补充商业保险。",
metadata={"category": "policies", "type": "insurance"}
),
Document(
page_content="培训发展:公司提供专业技能培训补贴,每人每年最高 5000 元。支持在职深造和职业资格认证考试。",
metadata={"category": "policies", "type": "training"}
),
# 常见问题
Document(
page_content="密码重置问题:登录系统后,在个人中心点击忘记密码按钮,通过注册邮箱接收验证邮件,点击邮件中的链接即可重置密码。如未收到邮件,请联系客服。",
metadata={"category": "faq", "type": "account"}
),
Document(
page_content="发票申请:在订单详情页点击申请发票,填写开票信息(公司名称、税号等),电子发票将在 3 个工作日内发送到指定邮箱。",
metadata={"category": "faq", "type": "invoice"}
),
Document(
page_content="退款政策:产品购买后 7 天内可申请无理由退款。超过 7 天需提供相关证明材料,根据具体情况处理。退款将在 5-10 个工作日内原路返回。",
metadata={"category": "faq", "type": "refund"}
),
Document(
page_content="技术支持:提供 7x24 小时技术支持服务,可通过在线客服、电话 400-888-9999、邮件 support@futuretech.com 联系我们。",
metadata={"category": "faq", "type": "support"}
),
]
self.documents = mock_data
def _build_vectorstore(self):
"""构建向量索引"""
try:
# 分割文档
all_splits = self.text_splitter.split_documents(self.documents)
# 创建 FAISS 向量库
self.vectorstore = FAISS.from_documents(
documents=all_splits,
embedding=self.embedding_model
)
print(f"✓ 向量知识库构建完成,共 {len(all_splits)} 个文档片段\n")
except Exception as e:
print(f"✗ 向量知识库构建失败:{e}")
print("⚠ 将使用备用方案(基于关键词搜索)\n")
self.vectorstore = None
def search(self, query: str, k: int = 3) -> list:
"""
向量相似度搜索
:param query: 查询文本
:param k: 返回最相关的 k 条结果
:return: 相关文档列表
"""
if not self.vectorstore:
return self._keyword_search(query, k)
results = self.vectorstore.similarity_search(query, k=k)
return results
def search_with_score(self, query: str, k: int = 3) -> list:
"""
带分数的向量搜索
:param query: 查询文本
:param k: 返回结果数量
:return: (文档,相似度分数) 列表
"""
if not self.vectorstore:
results = self._keyword_search(query, k)
# 转换为带分数的格式 (关键词搜索没有分数,默认为 0)
return [(doc, 0.0) for doc in results]
results = self.vectorstore.similarity_search_with_score(query, k=k)
return results
def _keyword_search(self, query: str, k: int = 3) -> list:
"""
备用方案:基于关键词的搜索
:param query: 查询文本
:param k: 返回结果数量
:return: 相关文档列表
"""
results = []
query_words = set(query.lower())
for doc in self.documents:
content_words = set(doc.page_content.lower())
# 计算词重叠度
overlap = len(query_words & content_words)
if overlap > 0:
results.append((doc, overlap))
# 按重叠度排序
results.sort(key=lambda x: x[1], reverse=True)
return [doc for doc, _ in results[:k]]
def add_document(self, content: str, metadata: dict = None):
"""添加新文档到知识库"""
if not self.vectorstore:
print("⚠ 向量库未初始化,无法添加文档")
return
doc = Document(page_content=content, metadata=metadata or {})
splits = self.text_splitter.split_documents([doc])
self.vectorstore.add_documents(splits)
print(f"✓ 已添加新文档,当前共 {len(self.vectorstore.docstore._dict)} 个文档片段")
# 初始化向量知识库
vector_kb = VectorKnowledgeBase()
# ===== 2. 定义工具函数 =====
@tool
def get_current_time() -> str:
"""获取当前日期和时间"""
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@tool
def get_weather(city: str):
"""获取天气信息"""
url = f"https://uapis.cn/api/v1/misc/weather?city={city}"
response = requests.get(url)
data = response.json()
return data
@tool
def search_knowledge_base(query: str):
"""
使用向量搜索查询私有知识库
:param query: 搜索问题或关键词
"""
results = vector_kb.search_with_score(query, k=3)
if not results:
return "未在知识库中找到相关信息"
# 格式化结果
formatted = ""
for i, (doc, score) in enumerate(results, 1):
formatted += f"{i}. {doc.page_content}\n"
# 添加元数据信息
if doc.metadata:
category = doc.metadata.get("category", "unknown")
doc_type = doc.metadata.get("type", "unknown")
formatted += f"(分类:{category}, 类型:{doc_type})\n\n"
return formatted if formatted else "未找到相关信息"
@tool
def get_weather_forecast(city: str):
"""获取天气预报"""
url = f"https://uapis.cn/api/v1/misc/weather?city={city}"
response = requests.get(url)
data = response.json()
return data
tools = [get_current_time, get_weather, search_knowledge_base, get_weather_forecast]
# ===== 3. 初始化 LLM 并绑定工具 =====
llm = ChatTongyi(model="tongyi-xiaomi-analysis-pro", temperature=0.7)
llm_with_tools = llm.bind_tools(tools)
# ===== 4. 手动维护对话历史 =====
messages = []
print("🚀 欢迎使用基于 FAISS 向量知识库的 AI 助手!")
print("💡 我可以回答关于公司信息、产品、政策等问题")
print("输入 exit 退出\n")
while True:
user_input = input("你:")
if user_input == "exit":
break
messages.append(HumanMessage(content=user_input))
ai_response = llm_with_tools.invoke(messages)
if hasattr(ai_response, 'tool_calls') and ai_response.tool_calls:
messages.append(ai_response)
for tool_call in ai_response.tool_calls:
tool_name = tool_call["name"]
tool_args = tool_call["args"]
func = next((t for t in tools if t.name == tool_name), None)
if func:
result = func.invoke(tool_args)
else:
result = f"工具 '{tool_name}' 未找到"
messages.append(ToolMessage(
content=str(result),
tool_call_id=tool_call["id"]
))
ai_response = llm.invoke(messages)
messages.append(ai_response)
print(f"AI: {ai_response.content}\n")
测试结果
核心知识点
RAG(检索增强生成):大模型应用落地标准方案
流程:文档加载 → 文本分块 → 向量嵌入 → 向量存储 → 检索问答
适用场景:企业文档助手、产品手册、学术论文问答
总结
这篇博客带你完成了大模型应用的完整进化路径:
基础:一次性调用阿里通义千问大模型
交互:实现控制台循环对话
核心:添加上下文记忆,实现连贯聊天
扩展:通过 FunctionCall 调用工具,赋予模型实时能力
落地:基于 RAG 构建私有知识库问答系统
所有代码可直接运行、可直接扩展,是 Python + LangChain 开发阿里大模型应用的最佳入门实践。
关键点回顾
核心依赖:langchain + langchain-community 提供阿里模型封装
记忆能力:定义记忆数组 messages 实现对话上下文留存
工具调用:Tool 让模型具备执行能力
知识库:RAG 是大模型私有化落地的最优解
全程基于阿里通义千问,适配国内生产环境
