虚拟环境创建
创建虚拟环境
- 语法:
conda create -n <环境名称> [选项]。 - 示例:创建一个名为
myenv且指定Python版本为3.8的虚拟环境,命令为conda create -n myenv python=3.10。
激活虚拟环境
- 激活:使用命令
conda activate <环境名称>,激活后命令行提示符会显示当前环境名称,表示已切换到该环境。
查看虚拟环境列表:使用命令conda env list或conda info -e可以查看已有的虚拟环境列表。
下载内核:pip install ipykernel
内核和环境匹配:python -m ipykernel install --user --name=你虚拟环境的名字
模型API调用
OpenAI接口集成方式
实操代码
环境安装:pip install openai
from openai import OpenAIds_api_key = "YOUR_DS_API_KEY"# 实例化客户端
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")# 调用 deepseek-r1 模型
response = client.chat.completions.create(model="deepseek-reasoner", #调用推理模型deepseek-r1 模型标识/名称,存在推理过程messages=[{"role": "user", "content": "请问,9.8和9.11哪个更大?"}]
)# 最终回复
response.choices[0].message.content
role身份应用
from IPython.display import display, Code, Markdown
from openai import OpenAIds_api_key = "YOUR_DS_API_KEY"
# 实例化客户端
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")response = client.chat.completions.create(model="deepseek-reasoner",messages=[{'role':'system','content':"你是一位滑稽且幽默的小品演员。"},{"role": "user", "content": "请问,你如何理解人生呢?"}]
)
display(Markdown(response.choices[0].message.content))
from IPython.display import display, Code, Markdown
from openai import OpenAIds_api_key = "YOUR_DS_API_KEY"
# 实例化客户端
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")response = client.chat.completions.create(model="deepseek-reasoner", messages=[{"role": "system", "content": "你是一位大学数学系教授"},{"role": "user", "content": "请问,你如何理解人生呢?"}]
)
display(Markdown(response.choices[0].message.content))
长文本上传
from IPython.display import display, Code, Markdown
from openai import OpenAIds_api_key = "YOUR_DS_API_KEY"
# 实例化客户端
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")text = '张三,男,1990年10月25日出生于中国台湾省高雄市。\2013年毕业于北京工业大学的信息工程专业,由于在校表现良好,毕业后被中科院信息技术部破格录取。'
response = client.chat.completions.create(model="deepseek-reasoner", messages=[{"role": "system", "content": text},#请问张三是什么星座的?请问张三毕业后去哪里了?{"role": "user", "content": '请问张三是哪一年毕业的?'}]
)
response.choices[0].message.content
多轮对话
from openai import OpenAIds_api_key = "xxx"
# 实例化客户端
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")def multi_chat_with_model(msg): #msg表示用户提出的问题text = '张三,男,1990年10月25日出生于中国台湾省高雄市。\2013年毕业于北京工业大学的信息工程专业,由于在校表现良好,毕业后被中科院信息技术部破格录取。'messages=[{"role": "system", "content": text},{"role": "user", "content": msg}]while True:response = client.chat.completions.create(model="deepseek-reasoner", messages=messages)# 获取模型回答answer = response.choices[0].message.contentprint(f"模型回答: {answer}")# 询问用户是否还有其他问题user_input = input("您还有其他问题吗?(输入退出以结束对话): ")if user_input == "退出":break# 记录用户回答messages.append({"role": "assistant", "content": answer})messages.append({"role": "user", "content": user_input})#多轮对话测试
multi_chat_with_model('张三哪一年毕业的?')
Functioncalling(底层技术:大致理解)
本质作用:用来给模型进行额外能力的拓展!可以将某个额外能力封装到一个函数中,然后使得模型可以基于该函数功能实现来进行能力的补充!
天气查询
外部函数定义
环境安装:pip install requests
def get_weather(loc):"""查询即时天气函数:param loc: 必要参数,字符串类型,用于表示查询天气的具体城市名称,\注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询北京市天气,则loc参数需要输入'Beijing';:return:OpenWeather API查询即时天气的结果,具体URL请求地址为:https://api.openweathermap.org/data/2.5/weather\返回结果对象类型为解析之后的JSON格式对象,并用字符串形式进行表示,其中包含了全部重要的天气信息"""# Step 1.构建请求url = "https://api.openweathermap.org/data/2.5/weather"# Step 2.设置查询参数params = {"q": loc, "appid": 'xxx', # 输入API key"units": "metric", # 使用摄氏度而不是华氏度"lang":"zh_cn" # 输出语言为简体中文}# Step 3.发送GET请求response = requests.get(url, params=params)# Step 4.解析响应data = response.json()return json.dumps(data)
外部函数完整描述
函数==工具
外部函数的完整描述 == 工具的使用说明书
get_weather_function = {'name': 'get_weather','description': '查询即时天气函数,根据输入的城市名称,查询对应城市的实时天气','parameters': {'type': 'object', #json对象类型'properties': { #参数成员描述'loc': {'description': "城市名称,注意,中国的城市需要用对应城市的英文名称代替,例如如果需要查询北京市天气,则loc参数需要输入'Beijing'",'type': 'string'}},'required': ['loc']}
}
工具箱封装
tools = [{"type": "function", "function":get_weather_function}
]
First response
from openai import OpenAI
#硅基流动API
ds_api_key = "xxx"
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")
messages = [{"role": "user", "content": "请帮我查询北京地区今日天气情况"}]
response = client.chat.completions.create(model="deepseek-chat", messages=messages,tools=tools
)response_message = response.choices[0].message
response_message
外部函数手动解析与调用
# 解析函数名称
function_name = response_message.tool_calls[0].function.name
function_name
#解析函数对象
available_functions = {"get_weather": get_weather,}
fuction_to_call = available_functions[function_name]
fuction_to_call
#解析函数参数
function_args = json.loads(response_message.tool_calls[0].function.arguments)
function_args
#函数调用
function_response = fuction_to_call(**function_args)
function_response
Second response
消息追加
#将模型第一次返回的结果转换成字典类型,目的是为了将其追加到messages列表中
response_message.model_dump()
# 向messages追加第一次模型返回结果消息
messages.append(response_message.model_dump())
# 追加function返回消息
messages.append({"role": "tool","content": function_response,"tool_call_id":response_message.tool_calls[0].id})
模型调用
from openai import OpenAI
ds_api_key = "xxx"
client = OpenAI(api_key=ds_api_key, base_url="https://api.deepseek.com")second_response = client.chat.completions.create(model="deepseek-chat", messages=messages
)second_response.choices[0].message.content
langchain快速入门
基本介绍
LangChain可以称之为自2022年底大模型技术爆火以来的第一个真正意义上的大模型开发框架。大模型本质上无法直接解决实际的问题,仅仅是一个能够分析、推理和生成文本的黑盒。直到现在,所有的开发者们仍然在不断探索如何把大模型的强大能力与实际应用场景结合起来,而当时LangChain的出现,直接让大模型开发变得简单起来,它将大模型开发过程中常用的功能、工具、流程等等全部封装成一个个的组件,使开发者可以像搭乐高积木一样,快速的组合出适用于不同场景需求的大模型应用。
其官方Github地址为:https://github.com/langchain-ai/langchain
LangChain抽象出最重要的核心模块如下:
模型(Model I/O)
LangChain支持主流的大型语言模型哦,像DeepSeek这种,它都能轻松对接并进行接口调用。并且langchain还合理规范了大模型的输入(提示词)和输出(输出解析器)。
提示模板(Prompts)
这个提示模板功能可不得了!它可以动态地生成提示词哦。比如说,我们可以根据具体的任务需求,让系统自动生成合适的提示词来引导模型进行回答或者操作。
链(Chains)
想象一下,我们要把多个任务步骤连接起来,形成一个完整的工作流程,就像搭建一条流水线一样,这就是链(Chains)的作用啦。比如说,我们可以把“用户输入 → 检索知识库 → 模型生成 → 结果解析”这样一个流程串联起来,形成一个高效的工作流。这样一来,每个步骤都能有条不紊地进行,大大提高了工作效率。
记忆(Memory)
记忆这个组件也很关键哦。它可以帮助我们管理对话历史呢。这里面又分为短时记忆和长时记忆。短时记忆就像是我们的短期记忆,主要是会话上下文,能让我们记住当前这次对话的一些关键信息;长时记忆呢,就像是长期存储在大脑里的知识一样,它会把数据存储到数据库里,方便我们以后随时查阅和使用。
代理(Agents)
代理这个组件就像一个聪明的小助手,它可以动态地调用外部工具哦。比如说,当我们需要计算一些复杂的数学问题时,它可以调用计算器这个外部工具来帮忙;要是我们需要查找一些特定的信息,它还能调用搜索引擎为我们寻找答案呢。这样一来,就大大扩展了模型的功能,让它能做更多的事情啦。
数据检索(Indexes)
最后再给大家介绍一下数据检索这个组件哈。它能集成向量数据库,然后构建本地知识库哦。这就好比是为模型建立了一个专属的知识宝库,当模型需要回答问题的时候,就可以从这个宝库里获取更准确、更丰富的信息,从而提高回答的准确性。
环境安装
LangChain可以使用pip 或者 conda直接安装,适用于仅使用的场景,即不需要了解其源码构建过程。这种安装方法十分简洁明了,只需执行一条命令,就可以在当前的虚拟环境中迅速完成LangChain的安装。具体操作如下:
pip install langchain==0.3.21
或者
pip install langchain
验证LangChain的安装情况,执行命令如下:
import langchainprint(langchain.__version__)
如果能正常输出LangChain的版本,说明在当前环境下的安装成功。
LangChain接入大模型
安装OpenAI的集成依赖包langchain-openai,执行如下命令: pip install langchain-openai
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
#消息列表定义
messages = [SystemMessage(content="你是个取名大师,你擅长为创业公司取名字"),HumanMessage(content="帮我给新公司取个名字,要包含AI")
]
#创建模型客户端
chat = ChatOpenAI(model_name="deepseek-chat",api_key='xxxxxx',base_url="https://api.deepseek.com"
)
#模型调用
reponse = chat.invoke(messages) #处理单条输入reponse.content
提示词模版
提示工程这个概念是指在与大语言模型进行交互时,精心设计输入文本(即提示)的过程,以获得更精准、相关或有创造性的输出。目前,提示工程已经发展成为一个专业领域,非常多的公司设立了专门的职位,负责为特定任务编写精确且具有创造力的提示。
以使用DeepSeek等网页端对话交互应用中,大部分人常见的做法是将提示(Prompt)做硬编码,例如将一段提示文本固定在Messages中。而在应用开发领域,开发者往往无法预知用户的具体输入内容,同时又希望大模型能够根据不同的应用任务以一种较为统一的逻辑来处理用户输入。所以,LangChain通过提供指定的提示词模版功能,优雅地解决了这个问题。提示词模版功能就是将用户输入到完整格式化提示的转换逻辑进行封装,使得模型能够更灵活、高效地处理各种输入。
LangChain 提供了创建和使用提示模板的各种工具。
PromptTemplate
PromptTemplate 是 LangChain 提示词组件的核心类,其构造提示词的过程本质上就是实例化这个类。在实例化 PromptTemplate 类时,需要提供两个关键参数:template 和 input_variables。
- template: 这是一个字符串,表示你想要生成的提示词模板。例如,如果你想要一个用于生成故事的提示词,你的模板可能是 "Once upon a time in {location}, there was a {character}..."。
- input_variables: 这是一个字典,包含了所有你希望在提示词中出现的变量。这些变量会在
template字符串中被替换。例如,对于上面的模板,你可能需要提供一个包含location和character键的字典。
以下是一个简单的示例代码,展示了如何实例化和使用 PromptTemplate 类:
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI # 创建一个提示词模版
template_str = ("你是一个专业的翻译助手,擅长将{input_language}文本准确翻译成{output_language}。""请翻译以下内容:'{text}'"
)#创建提示词模版工具对象:负责将提示词模版形成完整的提示词
input_language = input("enter input_language:")
output_language = input("enter output_language:")
text = input("enter text:")input_vars = {"input_language": input_language,"output_language": output_language,"text": text
}
prompt_template = PromptTemplate(template=template_str, #提示词模版input_variables=input_vars)#生成完整提示词
full_prompt = prompt_template.format(**input_vars)
full_prompt
这个提示模板⽤于格式化单个字符串,通常⽤于更简单的输⼊。
结合模型使用
# 创建语言模型实例(这里以 ChatOpenAI 为例)
API_KEY = "xxxx"
llm = ChatOpenAI(model_name="deepseek-chat",api_key=API_KEY,base_url="https://api.deepseek.com")# 向语言模型发送请求并获取响应
response = llm.invoke(full_prompt)# 打印模型的响应
print("模型回复:", response.content)
输出解析器
前提:模型本身输出的结果一定是字符串形式!
输出解析器作用:可以将模型输出的结果固定成指定格式或类型!
输出解析器本质:通过设计合适的提示词要求模型返回指定格式的数据!
CommaSeparatedListOutputParser列表输出解析器示例
from langchain_openai import ChatOpenAI
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
#构造列表解析器
output_parser = CommaSeparatedListOutputParser()
#返回解析器的解析格式
output_parser.get_format_instructions()
注意:所有解析器的解析格式都是英文的,上述列表解析器解析格式的英文翻译是:您的响应应该是逗号分隔的值列表,例如:foo,bar,baz或foo,bar,baz`。也就是通过解析器的该种解析格式作为提示词的部分内容,约束模型按照指定格式进行内容的输出。
-
解析器作用在PromptTemplate模版中
#构造输入模版,这里的区别是:在输入的Prompt Template中,加入了OutPut Parse的内容 template = """用户发起的提问:{question}{format_instructions}"""#实例化输出解析器(用于解析以逗号分隔的列表类型的输出) output_parser = CommaSeparatedListOutputParser()#创建提示词模版,将输出解析器的解析格式作为提示词模版的部分内容 prompt = PromptTemplate.from_template(template,partial_variables={"format_instructions":output_parser.get_format_instructions()}, )#最后,使用LangChain中的`chain`的抽象,合并最终的提示、大模型实例及OutPut Parse共同执行。 API_KEY = "xxxxxxx"model = ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base="https://api.deepseek.com")chain = prompt | model | output_parser output = chain.invoke({"question": "列出北京的三个景点"}) output- LCEL: LangChain Execution Language(LangChain 表达语⾔)是⼀种声明性的⽅式来链接 LangChain 组件(工作流)。
DatetimeOutputParser时间输出解析器示例
from langchain.output_parsers import DatetimeOutputParser#日期输出解析器
from langchain.prompts import PromptTemplate#制定输出解析器
output_parser = DatetimeOutputParser()#制定提示词模版
template = """回答用户的问题:
{question}{format_instructions}"""#时间解析器的解析格式
format_instructions = output_parser.get_format_instructions()#补充提示词模版
prompt = PromptTemplate.from_template(template,partial_variables={"format_instructions":format_instructions}
)API_KEY = "xxxxxxx"
model = ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base="https://api.deepseek.com")chain = prompt | model | output_parser
output = chain.invoke("周杰伦是什么时候出道的?")
output
EnumOutputParser枚举输出解析器示例
from langchain.output_parsers.enum import EnumOutputParser
from enum import Enum#定义枚举类型
class Colors(Enum):RED = "红色"BROWN = "棕色"BLACK = "黑色"WHITE = "白色"YELLOW = "黄色"#制定输出解析器
parse = EnumOutputParser(enum=Colors)#制定提示词模版
promptTemplate = PromptTemplate.from_template("""{person}的皮肤主要是什么颜色?{instructions}"""
)
#解析器的解析格式:原本解析器的英文解析格式会报错
# instructions = parse.get_format_instructions()
instructions = "响应结果请选择以下选项之一:红色、棕色、黑色、白色和黄色。"
#提示词部分补充
prompt = promptTemplate.partial(instructions=instructions)chain = prompt | model | parse
chain.invoke({"person":"亚洲人"})
注意:直接使用输出解析器原始的英文的解析格式作用到提示词中可能由于中英文掺杂和中英文语义的区别导致模型报错,因此,可以适当将输出解析器的解析格式手动翻译成英文后再用!
记忆模块Memory
在最开始我们就通过实验知道LLM 本身是没有记忆的,每一次LLM的API调用都是一个全新的会话。但在某些应用程序中,如:聊天机器人,让LLM记住以前的历史交互是非常重要,无论是在短期的还是长期的。langchain中的“Memory”即对话历史(message history)就是为了实现这一点。
#用于创建对话链
from langchain.chains import ConversationChain
#用于存储对话历史,以便在后续对话中参考
from langchain.memory import ConversationBufferMemoryfrom langchain_openai import ChatOpenAI
import warnings
warnings.filterwarnings("ignore")# 初始化大模型(需配置OPENAI_API_KEY)
API_KEY = "xxxxxxxxx"
llm = ChatOpenAI(model="deepseek-chat",openai_api_key=API_KEY,openai_api_base="https://api.deepseek.com")#实例化一个对话缓冲区,用于存储对话历史
memory = ConversationBufferMemory()
#创建一个对话链,将大语言模型和对话缓冲区关联起来。
conversation = ConversationChain(llm=llm,memory=memory,
)conversation.invoke("今天早上猪八戒吃了2个人参果。")
print("记忆1: ", conversation.memory.buffer)
print()conversation.invoke("下午猪八戒吃了1个人参果。")
print("记忆2: ", conversation.memory.buffer)
print()conversation.invoke("晚上猪八戒吃了3个人参果。")
print("记忆3: ", conversation.memory.buffer)
print()conversation.invoke("猪八戒今天一共吃了几个人参果?")
print("记忆4: ", conversation.memory.buffer)
功能设计:多轮对话
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
import warnings
warnings.filterwarnings("ignore")# 实例化一个对话缓冲区,用于存储对话历史
memory = ConversationBufferMemory()
# 创建一个对话链,将大语言模型和对话缓冲区关联起来。
conversation = ConversationChain(llm=llm,memory=memory,
)print("欢迎使用对话系统!输入 '退出' 结束对话。")while True:user_input = input("你: ")if user_input.lower() in ['退出', 'exit', 'quit']:print("再见!")breakresponse = conversation.predict(input=user_input)print(f"AI: {response}")# 打印出对话历史,即 memory.buffer 的内容
print("对话历史:", memory.buffer)
多轮对话Token限制解决
在了解了ConversationBufferMemory记忆类后,我们知道了它能够无限的将历史对话信息填充到History中,从而给大模型提供上下文的背景。但问题是:每个大模型都存在最大输入的Token限制,且过久远的对话数据往往并不能够对当前轮次的问答提供有效的信息,这种我们大家都能非常容易想到的问题,LangChain的开发人员自然也能想到,那么他们给出的解决方式是:ConversationBufferWindowMemory模块。该记忆类会保存一段时间内对话交互的列表,仅使用最后 K 个交互。所以它可以保存最近交互的滑动窗口,避免缓存区不会变得太大。
from langchain.memory import ConversationBufferWindowMemory
import warnings
warnings.filterwarnings("ignore")#实例化一个对话缓冲区,用于存储对话历史#k=1,所以在读取时仅能提取到最近一轮的记忆信息#return_messages=True参数,将对话转化为消息列表形式
memory = ConversationBufferWindowMemory(k=1, return_messages=True)conversation = ConversationChain(llm=llm,memory=memory,
)# 示例对话
response1 = conversation.predict(input="你好")
response2 = conversation.predict(input="你在哪里?")
print("对话历史:", memory.buffer)