目标
模型入门
语言模型是核心,我们需要熟悉跟语言模型相关的消息:系统消息、AI消息、Human消息、工具消息…
llm vs chatModel
百度千帆
对话
chat_comp = qianfan.ChatCompletion(access_key="...", secret_key="...")
# 调用默认模型,即 ERNIE-Bot-turbo
resp = chat_comp.do(messages=[{
"role": "user",
"content": "你好"
}])
#完成
comp = qianfan.Completion()
resp = comp.do(model="ERNIE-Bot", prompt="你好")
#输出:你好!有什么我可以帮助你的吗?
#续写功能同样支持流式调用
resp = comp.do(model="ERNIE-Bot", prompt="你好", stream=True)
for r in resp:
print(r['result'])
Azure Openai
完成
start_phrase = 'Write a tagline for an ice cream shop. '
response = openai.Completion.create(engine=deployment_name, prompt=start_phrase, max_tokens=10)
text = response['choices'][0]['text'].replace('\n', '').replace(' .', '.').strip()
print(start_phrase+text)
对话
response = openai.ChatCompletion.create(
engine="gpt-35-turbo", # engine = "deployment_name".
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},
{"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},
{"role": "user", "content": "Do other Azure AI services support this too?"}
]
)
消息ChatModels 接收一个消息列表作为输入,并返回一个消息。消息有几种不同的类型。所有消息都有一个角色(role)和一个内容(content)属性。角色描述了是谁在说话。LangChain 为不同的角色提供了不同的消息类。内容属性描述了消息的内容。这可以是以下几种不同的东西:
- 一个字符串(大多数模型都是这种方式)
- 一个字典列表(这用于多模态输入,其中字典包含有关该输入类型和位置的信息) 此外,消息还有一个 additionalkwargs 属性。这是传递关于消息的额外信息的地方。这主要用于特定于提供商的输入参数,而不是通用的。最著名的例子是 OpenAI 的 functioncall。
人类消息(HumanMessage) 这代表用户的消息。通常只包含内容。
AI消息(AIMessage) 这代表模型的消息。这可能有 additionalkwargs ——例如,如果使用 OpenAI 函数调用,则可能有 functionalcall。
系统消息(SystemMessage) 这代表系统消息。只有一些模型支持这个。这告诉模型如何表现。这通常只包含内容。
函数消息(FunctionMessage) 这代表函数调用的结果。除了角色和内容之外,这个消息还有一个 name 参数,它传达了产生这个结果的函数的名称。
工具消息(ToolMessage) 这代表工具调用的结果。这与 FunctionMessage 是不同的,以匹配 OpenAI 的函数和工具消息类型。除了角色和内容之外,这个消息还有一个 toolcallid 参数,它传达了产生这个结果的工具调用的 id。
函数调用 function call
定义函数: 将2个数相加
function = {
"name": "add_two_int",
"description": "将输入的2个整数相加",
"parameters": {
"type": "object",
"properties": {
"int_a": {
"description": "一个整数",
"type": "string"
},
"int_b": {
"description": "一个整数",
"type": "string"
},
},
"required": ["int_a", "int_b"]
},
}
绑定模型
chat_with_tools = azure_chat.bind(
function_call={"name": "add_two_int"}, functions=[function]
)
res = chat_with_tools.invoke("3加18等于多少")
结果
{'function_call':
{'arguments': '{\n "int_a": "3",\n "int_b": "18"\n}', 'name': 'add_two_int'}}
绑定运行时参数
res = azure_chat.with_config(configurable={"llm_temperature": 0.9}).invoke("给出一个随机数")
配置多个模型,运行时根据需求调用
llm = QianfanChatEndpoint(temperature=0.7).configurable_alternatives(
# 设置可以配置的项目
ConfigurableField(id="llm"),
# 设置缺省值,默认用百度
default_key="baidu4",
# 可以选择 Azure OpenAI
azure_openai=azure_chat,
)
chain = prompt | llm
调用百度
res_ = chain.with_config(configurable={"llm": "baidu4"}).invoke({"product": "铅笔"})
调用 Azure Opena
res_ = chain.with_config(configurable={"llm": "azure_openai"}).invoke({"product": "铅笔"})
聊天模型接受消息作为输入,并返回一个消息作为输出。 LangChain 有一些内置的消息类型: 系统消息(SystemMessage):用于引导 AI 行为,通常作为输入消息序列中的第一个消息传递。 人类消息(HumanMessage):代表与聊天模型互动的人的消息。 AI消息(AIMessage):代表聊天模型的消息。这可以是文本或调用工具的请求。 函数消息/工具消息(FunctionMessage / ToolMessage):用于将工具调用的结果传递回模型的消息。
让chat 有记忆:维护一个消息列表
response = openai.ChatCompletion.create(
engine="gpt-35-turbo", # engine = "deployment_name".
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},
{"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},
{"role": "user", "content": "Do other Azure AI services support this too?"}
]
)
在提示词中保存对话内容
保存对话记录
inputs = {"input": "你好!我是茉卷"}
response = chain.invoke(inputs)
memory.save_context(inputs, {"output": response.content})
res = memory.load_memory_variables({})
inputs = {"input": "我叫什么名字"}
response = chain.invoke(inputs)
content='你叫茉卷。如果你有其他疑问或者需要帮助,请随时告诉我,我会尽力为你服务。' additional_kwargs={'finish_reason': 'normal', 'request_id': 'as-jjdgubp1k9', 'object': 'chat.completion', 'search_info': []} response_metadata={'finish_reason': 'normal', 'id': 'as-jjdgubp1k9', 'object': 'chat.completion', 'created': 1711101413, 'result': '你叫茉卷。如果你有其他疑问或者需要帮助,请随时告诉我,我会尽力为你服务。', 'is_truncated': False, 'need_clear_history': False, 'usage': {'prompt_tokens': 37, 'completion_tokens': 19, 'total_tokens': 56}}
本质是一个list [], 不断往里面增加
{'role':'user', 'content':'…'}
{'role':'assistent', 'content':'…'}
计算token 数量
callback : token 计算
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
result = azure_chat.invoke("Tell me a joke")
print(cb)
pass
结果
Tokens Used: 34
Prompt Tokens: 11
Completion Tokens: 23
Successful Requests: 1
Total Cost (USD): $6.25e-05 ($0.0000625)
完整代码
import os
import uuid
from langchain.memory import ConversationBufferMemory
from langchain_community.chat_models.azure_openai import AzureChatOpenAI
from langchain_community.chat_models.baidu_qianfan_endpoint import QianfanChatEndpoint
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from langchain_community.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint
from langchain_community.vectorstores.chroma import Chroma
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.output_parsers import StrOutputParser, CommaSeparatedListOutputParser
from langchain_core.prompt_values import ChatPromptValue
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough, RunnableParallel, RunnableLambda, ConfigurableField
from operator import itemgetter
from langchain_core.pydantic_v1 import BaseModel, Field
if
name
== '
__main__
':
os.environ["QIANFAN_ACCESS_KEY"] = os.getenv('MY_QIANFAN_ACCESS_KEY')
os.environ["QIANFAN_SECRET_KEY"] = os.getenv('MY_QIANFAN_SECRET_KEY')
unique_id = uuid.uuid4().hex[0:8]
os.environ["LANGCHAIN_PROJECT"] = f" [返回docs]轨迹 - {unique_id}"
os.environ["LANGCHAIN_TRACING_V2"] = 'true'
os.environ["LANGCHAIN_API_KEY"] = os.getenv('MY_LANGCHAIN_API_KEY')
# chat
chat_model = QianfanChatEndpoint(
model="ERNIE-Bot-4"
)
# llm
llm = QianfanLLMEndpoint(model="ERNIE-Bot-4")
text = "讲一个狗熊的笑话"
messages = [HumanMessage(content=text)]
llm_res = llm.invoke(text)
# chat_res = chat_model.invoke(messages)
# 提示词 PromptTemplate
prompt = PromptTemplate.from_template("生产 {product} 的公司在哪里?")
prompt.format(product="袜子")
# ChatPromptTemplate
template = "你是个专业的翻译,你把 {input_language} 翻译到 {output_language}."
human_template = "{text}"
chat_prompt = ChatPromptTemplate.from_messages([
("system", template),
("human", human_template),
])
chat_prompt.format_messages(input_language="English", output_language="Chinese", text="I love programming.")
# 消息
messages = [
SystemMessage(content="你是一个AI助手"),
HumanMessage(content="今天有什么新闻?"),
]
# invoke
res = chat_model.invoke(messages)
# stream
for chunk in chat_model.stream(messages):
print(chunk.content, end="", flush=True)
# function call
class Multiply(BaseModel):
""" 将2个数相加"""
a: int = Field(..., description="第一个整数")
b: int = Field(..., description="第二个整数")
# langchain的百度接口不支持
os.environ["AZURE_OPENAI_API_KEY"] = os.getenv('MY_AZURE_OPENAI_API_KEY')
os.environ["AZURE_OPENAI_ENDPOINT"] = os.getenv('MY_AZURE_OPENAI_ENDPOINT')
DEPLOYMENT_NAME_GPT3P5 = os.getenv('MY_DEPLOYMENT_NAME_GPT3P5')
azure_chat = AzureChatOpenAI(
openai_api_version="2024-02-15-preview",
azure_deployment=DEPLOYMENT_NAME_GPT3P5,
)
function = {
"name": "add_two_int",
"description": "将输入的2个整数相加",
"parameters": {
"type": "object",
"properties": {
"int_a": {
"description": "一个整数",
"type": "string"
},
"int_b": {
"description": "一个整数",
"type": "string"
},
},
"required": ["int_a", "int_b"]
},
}
# 绑定运行时参数
chat_with_tools = azure_chat.bind(
function_call={"name": "add_two_int"}, functions=[function]
)
# res = chat_with_tools.invoke("3加18等于多少")
pass
res = azure_chat.with_config(configurable={"llm_temperature": 0.9}).invoke("给出一个随机数")
llm = QianfanChatEndpoint(temperature=0.7).configurable_alternatives(
# 设置可以配置的项目
ConfigurableField(id="llm"),
# 设置缺省值,默认用百度
default_key="baidu4",
# 可以选择 Azure OpenAI
azure_openai=azure_chat,
)
chain = prompt | llm
# res_ = chain.with_config(configurable={"llm": "baidu4"}).invoke({"product": "铅笔"})
# res_ = chain.with_config(configurable={"llm": "azure_openai"}).invoke({"product": "铅笔"})
pass
#
prompt = ChatPromptTemplate.from_messages(
[
("system", "你是AI助手"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
]
)
memory = ConversationBufferMemory(return_messages=True)
res = memory.load_memory_variables({})
chain = (
RunnablePassthrough.assign(
history=RunnableLambda(memory.load_memory_variables) | itemgetter("history")
)
| prompt
| chat_model
)
inputs = {"input": "你好!我是茉卷"}
response = chain.invoke(inputs)
memory.save_context(inputs, {"output": response.content})
res = memory.load_memory_variables({})
# 测试记忆
inputs = {"input": "我叫什么名字"}
response = chain.invoke(inputs)
pass
memory.save_context(inputs, {"output": response.content})
res = memory.load_memory_variables({})
pass
# callback : token 计算
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
result = azure_chat.invoke("Tell me a joke")
print(cb)
pass