##### chat = ChatOpenAI(model_name=model_name) # 实例化一个chat对象 # 消息类型:AIMessage, HumanMessage, SystemMessage(分别对应AI回复,用户输入,系统提示) messages = [ SystemMessage(content="You are a helpful assistant that translates English to French."), HumanMessage(content="Translate this sentence from English to French. I love programming.") ]
from langchain.prompts import PromptTemplate from langchain.prompts import ChatPromptTemplate
if chat_prompt: chat_prompt = ChatPromptTemplate.from_template("What is a good name for a company that makes {product}?") print(chat_prompt.format(product="colorful socks")) return chat_prompt
# 通过 PromptTemplate 类来创建提示模板 prompt = PromptTemplate( input_variables=["product"], # 这是一个可以修改的参数,会被填入下面的template字符串中 template="What is a good name for a company that makes {product}?", ) # 类似string.format()的用法,传入参数填充模板中的变量 print(prompt.format(product="colorful socks")) return prompt
from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser import os
defbasic_chain_usage_test(use_chain_pipe=True): # 基本结构:prompt + model + output parser prompt = ChatPromptTemplate.from_template( "tell me a short joke about {topic}, use {language}" ) model = ChatOpenAI(model_name=model_name, temperature=0.9) output_parser = StrOutputParser()
# output parser类型的invoke函数会处理message对象中返回的信息。这里的StrOutputParser是一个基础输出器,将结果转换为字符串 result = output_parser.invoke(message.content) print(type(result)) print(f"output: {result}") return
# piece together then different components into a single chain using LCEL # use | (unix pipe operator) as the operator to connect the components # 使用 | 作为连接符号,将不同的组件连接起来,以形成一个链式管道 chain = prompt | model | output_parser
result = chain.invoke({"topic": "pigeons", "language": "Chinese"}) print(f"reply: {result}")
prompt1 = ChatPromptTemplate.from_template( "generate a {attribute} color. Return the name of the color and nothing else:" ) prompt2 = ChatPromptTemplate.from_template( "what is a fruit of color: {color}. Return the name of the fruit and nothing else:" ) prompt3 = ChatPromptTemplate.from_template( "what is a country with a flag that has the color: {color}. Return the name of the country and nothing else:" ) prompt4 = ChatPromptTemplate.from_template( "What is the color of {fruit} and the flag of {country}?" )
prompt = ChatPromptTemplate.from_messages( [ ( "system", "Write out the following equation using algebraic symbols then solve it. Use the format\n\nEQUATION:...\nSOLUTION:...\n\n", ), ("human", "{equation_statement}"), ] )
runnable = ( {"equation_statement": RunnablePassthrough()} | prompt | model.bind(stop="SOLUTION") | StrOutputParser() ) print(runnable.invoke("x raised to the third plus seven equals 12"))
from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser from langchain.output_parsers.openai_functions import JsonKeyOutputFunctionsParser from langchain_core.runnables import RunnableParallel, RunnablePassthrough
defprompt_chain_with_input_and_output_handle():
prompt = ChatPromptTemplate.from_template("tell me a joke about {foo}") model = ChatOpenAI(model_name=model_name, temperature=0.9)
from langchain.prompts import PromptTemplate from langchain_core.runnables import ConfigurableField from langchain_openai import ChatOpenAI
model = ChatOpenAI(temperature=0).configurable_fields( temperature=ConfigurableField( id="llm_temperature", name="LLM Temperature", description="The temperature of the LLM", ) )
使用模型时(包括在LCEL中使用时),用函数即可覆盖配置:
1 2 3 4 5
model.with_config( configurable={ "llm_temperature": 0.9 } ).invoke("pick a random number")
deftest_memory_chain(): from operator import itemgetter
from langchain.chat_models import ChatOpenAI from langchain.memory import ConversationBufferMemory from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter( # Set a really small chunk size, just to show. chunk_size=100, chunk_overlap=20, length_function=len, is_separator_regex=False, )
# 这里直接使用字符串作为例子 embeddings = embeddings_model.embed_documents( [ "Hi there!", "Oh, hello!", "What's your name?", "My friends call me World", "Hello World!" ] ) len(embeddings), len(embeddings[0])
可以使用文本-向量编码模型快速比较不同文本直接的相似度,如:
1 2 3 4 5 6 7 8 9
embedded_query = embeddings_model.embed_query("What was the name mentioned in the conversation?") embedded_query[:5] # 输出embed_query传入的文本与embeddings_model中已编码的5个文本之间(各个)的相似度。
from langchain_community.document_loaders import TextLoader from langchain_openai import OpenAIEmbeddings from langchain.text_splitter import CharacterTextSplitter from langchain_community.vectorstores import FAISS
from langchain.embeddings import CacheBackedEmbeddings from langchain.storage import LocalFileStore from langchain.text_splitter import CharacterTextSplitter from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings
from langchain.retrievers.multi_query import MultiQueryRetriever from langchain_openai import ChatOpenAI from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbedding
question = "What are the approaches to Task Decomposition?" unique_docs = retriever_from_llm.get_relevant_documents(query=question)
# 输出示例:这里是log输出,即LLM为查询question生成的相近语义问题 INFO:langchain.retrievers.multi_query:Generated queries: [ '1. How can Task Decomposition be approached?', '2. What are the different methods for Task Decomposition?', '3. What are the various approaches to decomposing tasks?' ]
# 定义一个LLM输出格式解析器,将输出安装换行符分割,存储到一个lines的字典里 classLineList(BaseModel): # "lines" is the key (attribute name) of the parsed output lines: List[str] = Field(description="Lines of text")
# 自定义撰写提示,要求LLM输出5个多查询语句 QUERY_PROMPT = PromptTemplate( input_variables=["question"], template="""You are an AI language model assistant. Your task is to generate five different versions of the given user question to retrieve relevant documents from a vector database. By generating multiple perspectives on the user question, your goal is to help the user overcome some of the limitations of the distance-based similarity search. Provide these alternative questions separated by newlines. Original question: {question}""", ) llm = ChatOpenAI(temperature=0) # 构造LLM Chain llm_chain = LLMChain(llm=llm, prompt=QUERY_PROMPT, output_parser=output_parser)
from langchain.retrievers.document_compressors import DocumentCompressorPipeline from langchain.text_splitter import CharacterTextSplitter from langchain_community.document_transformers import EmbeddingsRedundantFilter
import faiss from langchain.docstore import InMemoryDocstore from langchain.retrievers import TimeWeightedVectorStoreRetriever from langchain.schema import Document from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings from langchain.tools.retriever import create_retriever_tool
# 创建检索器工具 retriever_tool = create_retriever_tool( retriever, "langsmith_search", "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!", )
from langchain_core.messages import AIMessage, HumanMessage
agent_executor.invoke( { "input": "what's my name? Don't use tools to look this up unless you NEED to", "chat_history": [ HumanMessage(content="hi! my name is bob"), AIMessage(content="Hello Bob! How can I assist you today?"), ], } )
# 这是工具调用返回的结果,这行注释是方便你理解内容的,并不在实际的输出中出现 [{'url': 'https://www.ibm.com/topics/langchain', 'content': 'LangChain is essentially a library of abstractions for Python and Javascript...'}] Action:
{
“action”: “Final Answer”,
“action_input”: “LangChain is an open source orchestration framework …”
}
1 2 3 4 5 6
> Finished chain.
{'input': 'what is LangChain?', 'output': 'LangChain is an open source orchestration framework ....'}
<tool>tavily_search_results_json</tool> <tool_input>what is LangChain? <!--这是工具调用返回的结果,这行注释是方便你理解内容的,并不在实际的输出中出现--> [{'url': 'https://aws.amazon.com/what-is/langchain/', 'content': 'What Is LangChain? ......'}] <final_answer>LangChain is an open source framework .....</final_answer>
agent_executor.invoke( { "input": "what's my name? Only use a tool if needed, otherwise respond with Final Answer", # Notice that chat_history is a string, since this prompt is aimed at LLMs, not chat models "chat_history": "Human: Hi! My name is Bob\nAI: Hello Bob! Nice to meet you", } )
I should research LangChain to learn more about it. Action: tavily_search_results_json Action Input: "LangChain" # 这是工具调用返回的结果,这行注释是方便你理解内容的,并不在实际的输出中出现 [{'url': 'https://www.ibm.com/topics/langchain', 'content': 'LangChain is essentially a library of .....'}]
I should read the summary and look at the different features and integrations of LangChain. Action: tavily_search_results_json Action Input: "LangChain features and integrations"[{'url': 'https://www.ibm.com/topics/langchain', 'content': "LangChain provides integrations for over 25 different embedding methods ....."}]
I should take note of the launch date and popularity of LangChain. Action: tavily_search_results_json Action Input: "LangChain launch date and popularity"[{'url': 'https://www.ibm.com/topics/langchain', 'content': "LangChain is an open source orchestration framework for ....."}]
I now know the final answer. Final Answer: LangChain is an open source orchestration framework for building applications using large language models (LLMs) like chatbots and virtual agents .....
from langchain.agents import AgentExecutor, create_self_ask_with_search_agent from langchain_community.llms import Fireworks from langchain_community.tools.tavily_search import TavilyAnswer
from langchain.callbacks.manager import ( AsyncCallbackManagerForToolRun, CallbackManagerForToolRun, )
# 定义Input Model时,参数名称为变量名,参数类型显示指定,使用一个Field对象定义可选的属性(标题,描述等) classCalculatorInput(BaseModel): a: int = Field(description="first number") b: int = Field(description="second number")
classCustomCalculatorTool(BaseTool): # 定义工具的基本属性 name = "Calculator" description = "useful for when you need to answer questions about math" args_schema: Type[BaseModel] = CalculatorInput # 设置参数时需要显示指定类型 return_direct: bool = True
# 重写run函数,实现工具的执行 def_run( self, a: int, b: int, run_manager: Optional[CallbackManagerForToolRun] = None ) -> str: """Use the tool.""" return a * b
# 重写_arun函数,实现工具的异步执行 # 如果工具不需要异步执行,可以直接返回异常 asyncdef_arun( self, a: int, b: int, run_manager: Optional[AsyncCallbackManagerForToolRun] = None, ) -> str: """Use the tool asynchronously.""" raise NotImplementedError("Calculator does not support async")
# 工具参数会默认设为函数参数 search = StructuredTool.from_function( func=search_function, name="Search", description="useful for when you need to answer questions about current events", # coroutine= ... <- 同样可以指定异步执行的方法 )
如果需要自定义参数覆盖函数的参数,可以指定args_schema:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# 自定义参数类 classCalculatorInput(BaseModel): a: int = Field(description="first number") b: int = Field(description="second number")
# 工具要执行的函数 defmultiply(a: int, b: int) -> int: """Multiply two numbers.""" return a * b
from langchain.schema import HumanMessage from langchain_openai import ChatOpenAI from langchain.tools import MoveFileTool, format_tool_to_openai_function
model = ChatOpenAI(model="gpt-3.5-turbo-0613") tools = [MoveFileTool()] functions = [format_tool_to_openai_function(t) for t in tools]
message = model.predict_messages( [HumanMessage(content="move file foo to bar")], functions=functions )
from langchain_openai import ChatOpenAI from langchain.agents import tool from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.messages import AIMessage, HumanMessage from langchain_community.tools.convert_to_openai import format_tool_to_openai_function
@tool defget_word_length(word: str) -> int: """Returns the length of a word.""" returnlen(word)
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # 定义llm # 将工具绑定到llm llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])
MEMORY_KEY = "chat_history" prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are very powerful assistant, but bad at calculating lengths of words.", ), MessagesPlaceholder(variable_name=MEMORY_KEY), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ] )
from langchain.agents.format_scratchpad import format_to_openai_function_messages from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
input1 = "how many letters in the word educa?" result = agent_executor.invoke({"input": input1, "chat_history": chat_history}) chat_history.extend( [ HumanMessage(content=input1), AIMessage(content=result["output"]), ] )
input2 = "is that a real word?" agent_executor.invoke({"input": input2, "chat_history": chat_history})
agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, handle_parsing_errors="Check your output and make sure it conforms, use the Action/Action Input syntax", )
from typing importList from pydantic import BaseModel, Field
classResponse(BaseModel): """Final response to the question being asked"""
answer: str = Field(description="The final answer to respond to the user") sources: List[int] = Field( description="List of page chunks that contain answer to the question. Only include a page chunk if it contains relevant information" )
from langchain_openai import ChatOpenAI from langchain_community.tools.convert_to_openai import format_tool_to_openai_function from langchain.utils.openai_functions import convert_pydantic_to_openai_function