目标 模型入门
Langchain 2.0 都找不到下面这个图了,藏到了1.0 里面…
语言模型 是核心,我们需要熟悉跟语言模型相关的消息:系统消息、AI消息、Human消息、工具消息…
llm vs chatModel
百度千帆
对话
1 2 3 4 5 6 7 chat_comp = qianfan.ChatCompletion(access_key="..." , secret_key="..." ) resp = chat_comp.do(messages=[{ "role" : "user" , "content" : "你好" }])
完成
1 2 3 4 5 6 7 8 9 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
完成
1 2 3 4 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)
对话
1 2 3 4 5 6 7 8 9 response = openai.ChatCompletion.create( engine="gpt-35-turbo" , 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 为不同的角色提供了不同的消息类。内容属性描述了消息的内容。这可以是以下几种不同的东西:
一个字符串(大多数模型都是这种方式)
一个字典列表(这用于多模态输入,其中字典包含有关该输入类型和位置的信息) 此外,消息还有一个 additional_kwargs 属性。这是传递关于消息的额外信息的地方。这主要用于特定于提供商的输入参数,而不是通用的。最著名的例子是 OpenAI 的 function_call。
人类消息(HumanMessage) 这代表用户的消息。通常只包含内容。
AI消息(AIMessage) 这代表模型的消息。这可能有 additional_kwargs ——例如,如果使用 OpenAI 函数调用,则可能有 functional_call。
系统消息(SystemMessage) 这代表系统消息。只有一些模型支持这个。这告诉模型如何表现。这通常只包含内容。
函数消息(FunctionMessage) 这代表函数调用的结果。除了角色和内容之外,这个消息还有一个 name 参数,它传达了产生这个结果的函数的名称。
工具消息(ToolMessage) 这代表工具调用的结果。这与 FunctionMessage 是不同的,以匹配 OpenAI 的函数和工具消息类型。除了角色和内容之外,这个消息还有一个 tool_call_id 参数,它传达了产生这个结果的工具调用的 id。
函数调用 function call
定义函数: 将2个数相加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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" ] }, }
绑定模型
1 2 3 4 chat_with_tools = azure_chat.bind( function_call={"name" : "add_two_int" }, functions=[function] ) res = chat_with_tools.invoke("3加18等于多少" )
结果
1 2 {'function_call' : {'arguments' : '{\n "int_a": "3",\n "int_b": "18"\n}' , 'name' : 'add_two_int' }}
绑定运行时参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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_chat, ) chain = prompt | llm res_ = chain.with_config(configurable={"llm" : "baidu4" }).invoke({"product" : "铅笔" }) res_ = chain.with_config(configurable={"llm" : "azure_openai" }).invoke({"product" : "铅笔" })
聊天模型接受消息作为输入,并返回一个消息作为输出。 LangChain 有一些内置的消息类型: 系统消息(SystemMessage):用于引导 AI 行为,通常作为输入消息序列中的第一个消息传递。 人类消息(HumanMessage):代表与聊天模型互动的人的消息。 AI消息(AIMessage):代表聊天模型的消息。这可以是文本或调用工具的请求。 函数消息/工具消息(FunctionMessage / ToolMessage):用于将工具调用的结果传递回模型的消息。
让chat 有记忆:维护一个消息列表
1 2 3 4 5 6 7 8 9 response = openai.ChatCompletion.create( engine="gpt-35-turbo" , 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?" } ] )
在提示词中保存对话内容
1 2 3 4 5 6 7 8 9 10 11 12 13 prompt = ChatPromptTemplate.from_messages( [ ("system" , "你是AI助手" ), MessagesPlaceholder(variable_name="history" ), <---虚位以待 ("human" , "{input}" ), ] ) memory = ConversationBufferMemory(return_messages=True ) <-- 想象成一个list res = memory.load_memory_variables({}) ------
保存对话记录
1 2 3 4 5 6 inputs = {"input" : "你好!我是茉卷" } response = chain.invoke(inputs) memory.save_context(inputs, {"output" : response.content}) res = memory.load_memory_variables({})
1 2 3 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 数量
1 2 3 4 5 6 from langchain.callbacks import get_openai_callbackwith get_openai_callback() as cb: result = azure_chat.invoke("Tell me a joke" ) print (cb) pass
结果
1 2 3 4 5 Tokens Used: 34 Prompt Tokens: 11 Completion Tokens: 23 Successful Requests: 1 Total Cost (USD): $6.25e-05 ($0.0000625 )
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 import osimport uuidfrom langchain.memory import ConversationBufferMemoryfrom langchain_community.chat_models.azure_openai import AzureChatOpenAIfrom langchain_community.chat_models.baidu_qianfan_endpoint import QianfanChatEndpointfrom langchain_community.embeddings import QianfanEmbeddingsEndpointfrom langchain_community.llms.baidu_qianfan_endpoint import QianfanLLMEndpointfrom langchain_community.vectorstores.chroma import Chromafrom langchain_core.messages import HumanMessage, SystemMessagefrom langchain_core.output_parsers import StrOutputParser, CommaSeparatedListOutputParserfrom langchain_core.prompt_values import ChatPromptValuefrom langchain_core.prompts import ChatPromptTemplate, PromptTemplate, MessagesPlaceholderfrom langchain_core.runnables import RunnablePassthrough, RunnableParallel, RunnableLambda, ConfigurableFieldfrom operator import itemgetterfrom langchain_core.pydantic_v1 import BaseModel, Fieldif __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_model = QianfanChatEndpoint( model="ERNIE-Bot-4" ) llm = QianfanLLMEndpoint(model="ERNIE-Bot-4" ) text = "讲一个狗熊的笑话" messages = [HumanMessage(content=text)] llm_res = llm.invoke(text) prompt = PromptTemplate.from_template("生产 {product} 的公司在哪里?" ) prompt.format (product="袜子" ) 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="今天有什么新闻?" ), ] res = chat_model.invoke(messages) for chunk in chat_model.stream(messages): print (chunk.content, end="" , flush=True ) class Multiply (BaseModel ): """ 将2个数相加""" a: int = Field(..., description="第一个整数" ) b: int = Field(..., description="第二个整数" ) 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] ) 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_chat, ) chain = prompt | llm 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 from langchain.callbacks import get_openai_callback with get_openai_callback() as cb: result = azure_chat.invoke("Tell me a joke" ) print (cb) pass