2023-11-03 20:34:44 +00:00
import os
from operator import itemgetter
from typing import List , Tuple
from langchain . chat_models import ChatOpenAI
from langchain . prompts import ChatPromptTemplate , MessagesPlaceholder
from langchain . prompts . prompt import PromptTemplate
from langchain . schema import AIMessage , HumanMessage , format_document
docs[patch], templates[patch]: Import from core (#14575)
Update imports to use core for the low-hanging fruit changes. Ran
following
```bash
git grep -l 'langchain.schema.runnable' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.runnable/langchain_core.runnables/g'
git grep -l 'langchain.schema.output_parser' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.output_parser/langchain_core.output_parsers/g'
git grep -l 'langchain.schema.messages' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.messages/langchain_core.messages/g'
git grep -l 'langchain.schema.chat_histry' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.chat_history/langchain_core.chat_history/g'
git grep -l 'langchain.schema.prompt_template' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.prompt_template/langchain_core.prompts/g'
git grep -l 'from langchain.pydantic_v1' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.pydantic_v1/from langchain_core.pydantic_v1/g'
git grep -l 'from langchain.tools.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.tools\.base/from langchain_core.tools/g'
git grep -l 'from langchain.chat_models.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.chat_models.base/from langchain_core.language_models.chat_models/g'
git grep -l 'from langchain.llms.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.llms\.base\ /from langchain_core.language_models.llms\ /g'
git grep -l 'from langchain.embeddings.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.embeddings\.base/from langchain_core.embeddings/g'
git grep -l 'from langchain.vectorstores.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.vectorstores\.base/from langchain_core.vectorstores/g'
git grep -l 'from langchain.agents.tools' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.agents\.tools/from langchain_core.tools/g'
git grep -l 'from langchain.schema.output' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.output\ /from langchain_core.outputs\ /g'
git grep -l 'from langchain.schema.embeddings' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.embeddings/from langchain_core.embeddings/g'
git grep -l 'from langchain.schema.document' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.document/from langchain_core.documents/g'
git grep -l 'from langchain.schema.agent' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.agent/from langchain_core.agents/g'
git grep -l 'from langchain.schema.prompt ' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.prompt\ /from langchain_core.prompt_values /g'
git grep -l 'from langchain.schema.language_model' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.language_model/from langchain_core.language_models/g'
```
2023-12-12 00:49:10 +00:00
from langchain . vectorstores . zep import CollectionConfig , ZepVectorStore
from langchain_core . documents import Document
from langchain_core . messages import BaseMessage
from langchain_core . output_parsers import StrOutputParser
from langchain_core . pydantic_v1 import BaseModel , Field
from langchain_core . runnables import (
2023-11-03 20:34:44 +00:00
ConfigurableField ,
RunnableBranch ,
RunnableLambda ,
2023-12-01 21:36:40 +00:00
RunnableParallel ,
2023-11-03 20:34:44 +00:00
RunnablePassthrough ,
)
docs[patch], templates[patch]: Import from core (#14575)
Update imports to use core for the low-hanging fruit changes. Ran
following
```bash
git grep -l 'langchain.schema.runnable' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.runnable/langchain_core.runnables/g'
git grep -l 'langchain.schema.output_parser' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.output_parser/langchain_core.output_parsers/g'
git grep -l 'langchain.schema.messages' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.messages/langchain_core.messages/g'
git grep -l 'langchain.schema.chat_histry' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.chat_history/langchain_core.chat_history/g'
git grep -l 'langchain.schema.prompt_template' {docs,templates,cookbook} | xargs sed -i '' 's/langchain\.schema\.prompt_template/langchain_core.prompts/g'
git grep -l 'from langchain.pydantic_v1' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.pydantic_v1/from langchain_core.pydantic_v1/g'
git grep -l 'from langchain.tools.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.tools\.base/from langchain_core.tools/g'
git grep -l 'from langchain.chat_models.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.chat_models.base/from langchain_core.language_models.chat_models/g'
git grep -l 'from langchain.llms.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.llms\.base\ /from langchain_core.language_models.llms\ /g'
git grep -l 'from langchain.embeddings.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.embeddings\.base/from langchain_core.embeddings/g'
git grep -l 'from langchain.vectorstores.base' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.vectorstores\.base/from langchain_core.vectorstores/g'
git grep -l 'from langchain.agents.tools' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.agents\.tools/from langchain_core.tools/g'
git grep -l 'from langchain.schema.output' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.output\ /from langchain_core.outputs\ /g'
git grep -l 'from langchain.schema.embeddings' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.embeddings/from langchain_core.embeddings/g'
git grep -l 'from langchain.schema.document' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.document/from langchain_core.documents/g'
git grep -l 'from langchain.schema.agent' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.agent/from langchain_core.agents/g'
git grep -l 'from langchain.schema.prompt ' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.prompt\ /from langchain_core.prompt_values /g'
git grep -l 'from langchain.schema.language_model' {docs,templates,cookbook} | xargs sed -i '' 's/from langchain\.schema\.language_model/from langchain_core.language_models/g'
```
2023-12-12 00:49:10 +00:00
from langchain_core . runnables . utils import ConfigurableFieldSingleOption
2023-11-03 20:34:44 +00:00
ZEP_API_URL = os . environ . get ( " ZEP_API_URL " , " http://localhost:8000 " )
ZEP_API_KEY = os . environ . get ( " ZEP_API_KEY " , None )
ZEP_COLLECTION_NAME = os . environ . get ( " ZEP_COLLECTION " , " langchaintest " )
collection_config = CollectionConfig (
name = ZEP_COLLECTION_NAME ,
description = " Zep collection for LangChain " ,
metadata = { } ,
embedding_dimensions = 1536 ,
is_auto_embedded = True ,
)
vectorstore = ZepVectorStore (
collection_name = ZEP_COLLECTION_NAME ,
config = collection_config ,
api_url = ZEP_API_URL ,
api_key = ZEP_API_KEY ,
embedding = None ,
)
# Zep offers native, hardware-accelerated MMR. Enabling this will improve
# the diversity of results, but may also reduce relevance. You can tune
# the lambda parameter to control the tradeoff between relevance and diversity.
# Enabling is a good default.
retriever = vectorstore . as_retriever ( ) . configurable_fields (
search_type = ConfigurableFieldSingleOption (
id = " search_type " ,
options = { " Similarity " : " similarity " , " Similarity with MMR Reranking " : " mmr " } ,
default = " mmr " ,
name = " Search Type " ,
description = " Type of search to perform: ' similarity ' or ' mmr ' " ,
) ,
search_kwargs = ConfigurableField (
id = " search_kwargs " ,
name = " Search kwargs " ,
description = (
" Specify ' k ' for number of results to return and ' lambda_mult ' for tuning "
" MMR relevance vs diversity. "
) ,
) ,
)
# Condense a chat history and follow-up question into a standalone question
_template = """ Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language.
Chat History :
{ chat_history }
Follow Up Input : { question }
Standalone question : """ # noqa: E501
CONDENSE_QUESTION_PROMPT = PromptTemplate . from_template ( _template )
# RAG answer synthesis prompt
template = """ Answer the question based only on the following context:
< context >
{ context }
< / context > """
ANSWER_PROMPT = ChatPromptTemplate . from_messages (
[
( " system " , template ) ,
MessagesPlaceholder ( variable_name = " chat_history " ) ,
( " user " , " {question} " ) ,
]
)
# Conversational Retrieval Chain
DEFAULT_DOCUMENT_PROMPT = PromptTemplate . from_template ( template = " {page_content} " )
def _combine_documents (
docs : List [ Document ] ,
document_prompt : PromptTemplate = DEFAULT_DOCUMENT_PROMPT ,
document_separator : str = " \n \n " ,
) :
doc_strings = [ format_document ( doc , document_prompt ) for doc in docs ]
return document_separator . join ( doc_strings )
def _format_chat_history ( chat_history : List [ Tuple [ str , str ] ] ) - > List [ BaseMessage ] :
buffer : List [ BaseMessage ] = [ ]
for human , ai in chat_history :
buffer . append ( HumanMessage ( content = human ) )
buffer . append ( AIMessage ( content = ai ) )
return buffer
_condense_chain = (
RunnablePassthrough . assign (
chat_history = lambda x : _format_chat_history ( x [ " chat_history " ] )
)
| CONDENSE_QUESTION_PROMPT
| ChatOpenAI ( temperature = 0 )
| StrOutputParser ( )
)
_search_query = RunnableBranch (
# If input includes chat_history, we condense it with the follow-up question
(
RunnableLambda ( lambda x : bool ( x . get ( " chat_history " ) ) ) . with_config (
run_name = " HasChatHistoryCheck "
) ,
# Condense follow-up question and chat into a standalone_question
_condense_chain ,
) ,
# Else, we have no chat history, so just pass through the question
RunnableLambda ( itemgetter ( " question " ) ) ,
)
# User input
class ChatHistory ( BaseModel ) :
chat_history : List [ Tuple [ str , str ] ] = Field ( . . . , extra = { " widget " : { " type " : " chat " } } )
question : str
2023-12-01 21:36:40 +00:00
_inputs = RunnableParallel (
2023-11-03 20:34:44 +00:00
{
" question " : lambda x : x [ " question " ] ,
" chat_history " : lambda x : _format_chat_history ( x [ " chat_history " ] ) ,
" context " : _search_query | retriever | _combine_documents ,
}
) . with_types ( input_type = ChatHistory )
chain = _inputs | ANSWER_PROMPT | ChatOpenAI ( ) | StrOutputParser ( )