Files
lcel-teacher/eval/eval.csv
2024-01-27 17:48:21 -08:00

14 KiB

1questionanswer
2How can I use a prompt and model to create a chain in LCEL that returns raw ChatMessages?Here is an example of a prompt and LLM chain using LCEL without any output parsing to return ChatMessages: \nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts import ChatPromptTemplate\n\nprompt = ChatPromptTemplate.from_template(\'tell me a joke about {foo}\')\nmodel = ChatOpenAI()\nchain = prompt | model\n\nchain.invoke({\'foo\': \'bears\'})
3How can I add memory to an arbitrary chain using LCEL?Here is an example adding memory to a chain: \nfrom operator import itemgetter\n\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.memory import ConversationBufferMemory\nfrom langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\nfrom langchain_core.runnables import RunnableLambda, RunnablePassthrough\n\nmodel = ChatOpenAI()\nprompt = ChatPromptTemplate.from_messages(\n[\n(\'system\',\'You are a helpful chatbot\'),\n MessagesPlaceholder(variable_name=\'history\'),\n('human', '{input}'),\n ]\n)\n\nmemory = ConversationBufferMemory(return_messages=True)\n\nchain = (\n RunnablePassthrough.assign(\n history=RunnableLambda(memory.load_memory_variables) | itemgetter('history')\n )\n | prompt\n | model\n)\n\ninputs = {'input': 'hi im bob'}\nresponse = chain.invoke(inputs)
4I've defined a LCEL runnable chain = prompt | model. How can I look at the input schema?All runnables expose input and output schemas to inspect the inputs and outputs. input_schema is an input Pydantic model auto-generated from the structure of the Runnable. You can call .schema() on it to obtain a JSONSchema representation of any runnable: # The input schema of the chain is the input schema of its first part, the prompt. chain.input_schema.schema()
5I have a LCEL runnable, chain, and am passing in a map w/ {'question' 'where did harrison work', 'language': 'italian'}. How can I extract the value of 'language' to pass to my prompt?For this example, we can use itemgetter to extract specific values from the map. Here is an example: from operator import itemgetter from langchain.chat_models import ChatOpenAI from langchain.embeddings import OpenAIEmbeddings from langchain.prompts import ChatPromptTemplate from langchain.vectorstores import FAISS from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough vectorstore = FAISS.from_texts(['harrison worked at kensho'], embedding=OpenAIEmbeddings()) retriever = vectorstore.as_retriever() template = 'Answer the question based only on the following context: {context} Question: {question} Answer in the following language: {language}' prompt = ChatPromptTemplate.from_template(template) chain = ( { 'context': itemgetter('question') | retriever, 'question': itemgetter('question'), 'language': itemgetter('language'), } | prompt | model | StrOutputParser() ) chain.invoke({'question': 'where did harrison work', 'language': 'italian'})
6I am passing text key 'foo' to my prompt and want to process it with a function, process_text(...), prior to the prompt. How can I do this using LCEL?You can use a RunnableLambda to apply a function to the value of foo: chain = ( { 'a': itemgetter('foo') | RunnableLambda(process_text), | RunnableLambda(multiple_length_function), } | prompt | model )
7My LCEL map contains the key 'question'. What is the difference between using itemgetter('question'), lambda x: x['question'], and x.get('question')?Itemgetter can be used as shorthand to extract specific keys from the map. In the context of a map operation, the lambda function is applied to each element in the input map and the function returns the value associated with the key 'question'. (get) is safer for accessing values in a dictionary because it handles the case where the key might not exist.
8I'm invoking a LCEL chain with a map that contain {'question': 'how do I use Anthropic?'}. The full chain definition is full_chain = {'question': lambda x: x['question']} | sub_chain. Why is a lambda used?The lambda function is an anonymous function that takes one argument, x, and returns x['question']. In the context of a map operation, this function is applied to each element in the input iterable. If the input is a dictionary (map), as in this case, x would be this map, and the function returns the value associated with the key 'question'.
9I’m passing {'a':1} and want to create an output map of {'a':1,'b':2, 'c':3}. How can I do this in LCEL?Use RunnablePassthrough: Use RunnableParallel with lambdas: \n from langchain_core.runnables import RunnableParallel, RunnablePassthrough; runnable = RunnableParallel(a=lambda x: x['a'], b=lambda x: x['a']+1, c=lambda x: x['a']+2); runnable.invoke({'num': 1}). Also you can use RunnablePassthrough: from langchain_core.runnables import RunnablePassthrough; original_input = {'a': 1}; chain = RunnablePassthrough.assign(b=lambda x: 2, c=lambda x: 3); output = chain.invoke(original_input); print(output)
10How can I make the output of my LCEL chain a string?Use StrOutputParser. from langchain_openai import ChatOpenAI; from langchain_core.prompts import ChatPromptTemplate; from langchain_core.output_parsers import StrOutputParser; prompt = ChatPromptTemplate.from_template('Tell me a short joke about {topic}'); model = ChatOpenAI(model='gpt-3.5-turbo') #gpt-4 or other LLMs can be used here; output_parser = StrOutputParser(); chain = prompt | model | output_parser
11How can I apply a custom function to one of the inputs of an LCEL chain?Use RunnableLambda with itemgetter to extract the relevant key. from operator import itemgetter; from langchain_core.prompts import ChatPromptTemplate; from langchain_core.runnables import RunnableLambda; from langchain_openai import ChatOpenAI; def length_function(text): return len(text); chain = ({'prompt_input': itemgetter('foo') | RunnableLambda(length_function),} | prompt | model); chain.invoke({'foo':'hello world'})
12With a RAG chain in LCEL, why are documents retrieved automatically when we construct the prompt like {'context': retriever, 'question': RunnablePassthrough()} and invoke it using chain.invoke('where did harrison work?')When we create the chain, get_relevant_documents is invoked automatically. vectorstore = FAISS.from_texts(['harrison worked at kensho'], embedding=OpenAIEmbeddings()); retriever = vectorstore.as_retriever(); chain = ({'context': retriever, 'question': RunnablePassthrough()} | prompt | model | StrOutputParser()); chain.invoke('where did harrison work?')
13I am passing a map with {'num': 1} to a LCEL chain. How can I add an extra key num2 to this map that adds 1 to the value of num. Then I want to assign this new map to a new key named output?We can use RunnablePassthrough with a lambda function. from langchain_core.runnables import RunnableParallel, RunnablePassthrough; runnable = RunnableParallel(output=RunnablePassthrough.assign(num2=lambda x: x['num'] + 1),); runnable.invoke({'num': 1})
14How can I configure the temperature of an LLM when invoking the LCEL chain?Use configuration fields. 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', )); model.with_config(configurable={'llm_temperature': 0.9}).invoke('pick a random number')
15How can we apply a function call to an LLM in an LCEL chain?We can attach a function call to the model using bind: functions = [{'name': 'joke', 'description': 'A joke', 'parameters': {'type': 'object', 'properties': {'setup': {'type': 'string', 'description': 'The setup for the joke'}, 'punchline': {'type': 'string', 'description': 'The punchline for the joke'}}, 'required': ['setup', 'punchline']}]; chain = prompt | model.bind(function_call={'name': 'joke'}, functions=functions)
16How can I run two LCEL chains in parallel and write their output to a map?We can use RunnableParallel: from langchain_core.prompts import ChatPromptTemplate; from langchain_core.runnables import RunnableParallel; from langchain_openai import ChatOpenAI; model = ChatOpenAI(); joke_chain = ChatPromptTemplate.from_template('tell me a joke about {topic}') | model; poem_chain = (ChatPromptTemplate.from_template('write a 2-line poem about {topic}') | model); map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain); map_chain.invoke({'topic': 'bear'})
17How can I directly pass a string to a runnable and use it to construct the input needed for my prompt?Use RunnablePassthrough. from langchain_core.runnables import RunnableParallel, RunnablePassthrough; from langchain_core.prompts import ChatPromptTemplate; from langchain_openai import ChatOpenAI; prompt = ChatPromptTemplate.from_template('Tell a joke about: {input}'); model = ChatOpenAI(); runnable = ({'input' : RunnablePassthrough()} | prompt | model); runnable.invoke('flowers')
18How can I use a custom function to route between 2 chains in LCEL?Use a RunnableLambda with custom routing logic. from langchain.prompts import PromptTemplate; from langchain_community.chat_models import ChatAnthropic; from langchain_core.output_parsers import StrOutputParser; chain = (PromptTemplate.from_template('Given the user question below, classify it as either being about `LangChain`, `Anthropic`, or `Other`. Do not respond with more than one word. <question> {question} </question> Classification:') | ChatAnthropic() | StrOutputParser()); def route(info): if 'anthropic' in info['topic'].lower(): return anthropic_chain; elif 'langchain' in info['topic'].lower(): return langchain_chain; langchain_chain = (PromptTemplate.from_template('You are an expert in langchain. Always answer questions starting with 'As Harrison Chase told me'. Respond to the following question: Question: {question} Answer:') | ChatAnthropic()); anthropic_chain = (PromptTemplate.from_template('You are an expert in anthropic. Always answer questions starting with 'As Dario Amodei told me'. Respond to the following question: Question: {question} Answer:') | ChatAnthropic()); from langchain_core.runnables import RunnableLambda; full_chain = {'topic': chain, 'question': lambda x: x['question']} | RunnableLambda(route)
19How do I set up a retrieval-augmented generation chain using LCEL that accepts a string as input?Use RunnablePassthrough to pass the input to the retriever and build a prompt to pass to the LLM: ! pip install langchain langchain-openai faiss-cpu; from operator import itemgetter; from langchain_community.vectorstores import FAISS; from langchain_core.output_parsers import StrOutputParser; from langchain_core.prompts import ChatPromptTemplate; from langchain_core.runnables import RunnablePassthrough; from langchain_openai import ChatOpenAI, OpenAIEmbeddings; vectorstore = FAISS.from_texts(['harrison worked at kensho'], embedding=OpenAIEmbeddings()); retriever = vectorstore.as_retriever(); template = 'Answer the question based only on the following context:{context}Question: {question}'; prompt = ChatPromptTemplate.from_template(template); model = ChatOpenAI(); chain = ({'context': retriever, 'question': RunnablePassthrough()} | prompt | model | StrOutputParser()); response = chain.invoke('where did harrison work?'); print(response)
20How can I create a LCEL chain that queries a SQL database?Follow these steps to create an LCEL chain that can query a SQL DB: from langchain_core.prompts import ChatPromptTemplate; template = 'Based on the table schema below, write a SQL query that would answer the user's question: {schema} Question: {question} SQL Query:'; prompt = ChatPromptTemplate.from_template(template); from langchain_community.utilities import SQLDatabase; db = SQLDatabase.from_uri('sqlite:///./Chinook.db'); def get_schema(_): return db.get_table_info(); def run_query(query): return db.run(query); from langchain_core.output_parsers import StrOutputParser; from langchain_core.runnables import RunnablePassthrough; from langchain_openai import ChatOpenAI; model = ChatOpenAI(); sql_response = (RunnablePassthrough.assign(schema=get_schema) | prompt | model.bind(stop=['\nSQLResult:']) | StrOutputParser()); template = 'Based on the table schema below, question, sql query, and sql response, write a natural language response: {schema} Question: {question} SQL Query: {query} SQL Response: {response}'; prompt_response = ChatPromptTemplate.from_template(template); full_chain = (RunnablePassthrough.assign(query=sql_response).assign(schema=get_schema, response=lambda x: db.run(x['query']), ) | prompt_response | model); full_chain.invoke({'question': 'How many employees are there?'})
21How to structure output of an LCEL chain as a Pydantic object with prefix and code_block?We can use PydanticOutputParser. from langchain.output_parsers import PydanticOutputParser; from langchain.prompts import PromptTemplate; from langchain.pydantic_v1 import BaseModel, Field; class FunctionOutput(BaseModel): prefix: str = Field(description='The prefix of the output'); code_block: str = Field(description='The code block of the output'); parser = PydanticOutputParser(pydantic_object=FunctionOutput); format_instructions = parser.get_format_instructions(); prompt = PromptTemplate(template='Output format instructions:\n{format_instructions}\n\nQuery: {query}\n', input_variables=['query'], partial_variables={'format_instructions': format_instructions}); model = ChatOpenAI(model_name='gpt-4'); prompt_and_model = prompt | model; output = prompt_and_model.invoke({'query': 'Give me a function that will add two numbers:'}); parsed_output = parser.invoke(output); prefix = parsed_output.prefix; code_block = parsed_output.code_block