add example of memory and returning retrieved docs (#8830)

pull/8840/head
Harrison Chase 1 year ago committed by GitHub
parent 4a7ebb7184
commit 2bb1d256f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,7 +22,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 1,
"id": "466b65b3",
"metadata": {},
"outputs": [],
@ -202,7 +202,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 10,
"id": "f799664d",
"metadata": {},
"outputs": [],
@ -347,7 +347,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 12,
"id": "5d3d8ffe",
"metadata": {},
"outputs": [],
@ -368,7 +368,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 2,
"id": "33be32af",
"metadata": {},
"outputs": [],
@ -380,7 +380,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 3,
"id": "df3f3fa2",
"metadata": {},
"outputs": [],
@ -515,7 +515,7 @@
},
{
"cell_type": "code",
"execution_count": 66,
"execution_count": 4,
"id": "3f30c348",
"metadata": {},
"outputs": [],
@ -526,7 +526,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 5,
"id": "64ab1dbf",
"metadata": {},
"outputs": [],
@ -544,7 +544,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 6,
"id": "7d628c97",
"metadata": {},
"outputs": [],
@ -559,7 +559,7 @@
},
{
"cell_type": "code",
"execution_count": 68,
"execution_count": 7,
"id": "f60a5d0f",
"metadata": {},
"outputs": [],
@ -572,7 +572,7 @@
},
{
"cell_type": "code",
"execution_count": 69,
"execution_count": 8,
"id": "7d007db6",
"metadata": {},
"outputs": [],
@ -589,25 +589,29 @@
},
{
"cell_type": "code",
"execution_count": 70,
"execution_count": 16,
"id": "5c32cc89",
"metadata": {},
"outputs": [],
"source": [
"conversational_qa_chain = RunnableMap({\n",
" \"standalone_question\": {\n",
" \"question\": lambda x: x[\"question\"],\n",
" \"chat_history\": lambda x: _format_chat_history(x['chat_history'])\n",
" } | CONDENSE_QUESTION_PROMPT | ChatOpenAI(temperature=0) | StrOutputParser(),\n",
"}) | {\n",
"_inputs = RunnableMap(\n",
" {\n",
" \"standalone_question\": {\n",
" \"question\": lambda x: x[\"question\"],\n",
" \"chat_history\": lambda x: _format_chat_history(x['chat_history'])\n",
" } | CONDENSE_QUESTION_PROMPT | ChatOpenAI(temperature=0) | StrOutputParser(),\n",
" }\n",
")\n",
"_context = {\n",
" \"context\": itemgetter(\"standalone_question\") | retriever | _combine_documents,\n",
" \"question\": lambda x: x[\"standalone_question\"]\n",
"} | ANSWER_PROMPT | ChatOpenAI()"
"}\n",
"conversational_qa_chain = _inputs | _context | ANSWER_PROMPT | ChatOpenAI()"
]
},
{
"cell_type": "code",
"execution_count": 71,
"execution_count": 17,
"id": "135c8205",
"metadata": {},
"outputs": [
@ -624,7 +628,7 @@
"AIMessage(content='Harrison was employed at Kensho.', additional_kwargs={}, example=False)"
]
},
"execution_count": 71,
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@ -638,7 +642,7 @@
},
{
"cell_type": "code",
"execution_count": 62,
"execution_count": 15,
"id": "424e7e7a",
"metadata": {},
"outputs": [
@ -655,7 +659,7 @@
"AIMessage(content='Harrison worked at Kensho.', additional_kwargs={}, example=False)"
]
},
"execution_count": 62,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@ -667,6 +671,149 @@
"})"
]
},
{
"cell_type": "markdown",
"id": "c5543183",
"metadata": {},
"source": [
"### With Memory and returning source documents\n",
"\n",
"This shows how to use memory with the above. For memory, we need to manage that outside at the memory. For returning the retrieved documents, we just need to pass them through all the way."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "e31dd17c",
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import ConversationBufferMemory"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "d4bffe94",
"metadata": {},
"outputs": [],
"source": [
"memory = ConversationBufferMemory(return_messages=True, output_key=\"answer\", input_key=\"question\")"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "733be985",
"metadata": {},
"outputs": [],
"source": [
"# First we add a step to load memory\n",
"# This needs to be a RunnableMap because its the first input\n",
"loaded_memory = RunnableMap(\n",
" {\n",
" \"question\": itemgetter(\"question\"),\n",
" \"memory\": memory.load_memory_variables,\n",
" }\n",
")\n",
"# Next we add a step to expand memory into the variables\n",
"expanded_memory = {\n",
" \"question\": itemgetter(\"question\"),\n",
" \"chat_history\": lambda x: x[\"memory\"][\"history\"]\n",
"}\n",
"\n",
"# Now we calculate the standalone question\n",
"standalone_question = {\n",
" \"standalone_question\": {\n",
" \"question\": lambda x: x[\"question\"],\n",
" \"chat_history\": lambda x: _format_chat_history(x['chat_history'])\n",
" } | CONDENSE_QUESTION_PROMPT | ChatOpenAI(temperature=0) | StrOutputParser(),\n",
"}\n",
"# Now we retrieve the documents\n",
"retrieved_documents = {\n",
" \"docs\": itemgetter(\"standalone_question\") | retriever,\n",
" \"question\": lambda x: x[\"standalone_question\"]\n",
"}\n",
"# Now we construct the inputs for the final prompt\n",
"final_inputs = {\n",
" \"context\": lambda x: _combine_documents(x[\"docs\"]),\n",
" \"question\": itemgetter(\"question\")\n",
"}\n",
"# And finally, we do the part that returns the answers\n",
"answer = {\n",
" \"answer\": final_inputs | ANSWER_PROMPT | ChatOpenAI(),\n",
" \"docs\": itemgetter(\"docs\"),\n",
"}\n",
"# And now we put it all together!\n",
"final_chain = loaded_memory | expanded_memory | standalone_question | retrieved_documents | answer"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "806e390c",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Number of requested results 4 is greater than number of elements in index 1, updating n_results = 1\n"
]
},
{
"data": {
"text/plain": [
"{'answer': AIMessage(content='Harrison was employed at Kensho.', additional_kwargs={}, example=False),\n",
" 'docs': [Document(page_content='harrison worked at kensho', metadata={})]}"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"inputs = {\"question\": \"where did harrison work?\"}\n",
"result = final_chain.invoke(inputs)\n",
"result"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "977399fd",
"metadata": {},
"outputs": [],
"source": [
"# Note that the memory does not save automatically\n",
"# This will be improved in the future\n",
"# For now you need to save it yourself\n",
"memory.save_context(inputs, {\"answer\": result[\"answer\"].content})"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "f94f7de4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'history': [HumanMessage(content='where did harrison work?', additional_kwargs={}, example=False),\n",
" AIMessage(content='Harrison was employed at Kensho.', additional_kwargs={}, example=False)]}"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"memory.load_memory_variables({})"
]
},
{
"cell_type": "markdown",
"id": "0f2bf8d3",
@ -1397,7 +1544,9 @@
"id": "179d3c03",
"metadata": {},
"outputs": [],
"source": []
"source": [
"## Conversational Retrieval With Memory"
]
}
],
"metadata": {
@ -1416,7 +1565,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
"version": "3.10.1"
}
},
"nbformat": 4,

Loading…
Cancel
Save