diff --git a/django_ai_assistant/helpers/assistants.py b/django_ai_assistant/helpers/assistants.py index ae2bf5e..a4010d2 100644 --- a/django_ai_assistant/helpers/assistants.py +++ b/django_ai_assistant/helpers/assistants.py @@ -8,10 +8,6 @@ DEFAULT_DOCUMENT_SEPARATOR, ) from langchain.tools import StructuredTool -from langchain_core.chat_history import ( - BaseChatMessageHistory, - InMemoryChatMessageHistory, -) from langchain_core.language_models import BaseChatModel from langchain_core.messages import ( AIMessage, @@ -81,8 +77,6 @@ class AIAssistant(abc.ABC): # noqa: F821 """Whether the assistant uses RAG (Retrieval-Augmented Generation) or not.\n Defaults to `False`. When True, the assistant will use a retriever to get documents to provide as context to the LLM. - For this to work, the `instructions` should contain a placeholder for the context, - which is `{context}` by default. Additionally, the assistant class should implement the `get_retriever` method to return the retriever to use.""" _user: Any | None @@ -257,58 +251,6 @@ def get_model_kwargs(self) -> dict[str, Any]: """ return {} - def get_prompt_template(self) -> ChatPromptTemplate: - """Get the `ChatPromptTemplate` for the Langchain chain to use.\n - The system prompt comes from the `get_instructions` method.\n - The template includes placeholders for the instructions, chat `{history}`, user `{input}`, - and `{agent_scratchpad}`, all which are necessary for the chain to work properly.\n - The chat history is filled by the chain using the message history from `get_message_history`.\n - If the assistant uses RAG, the instructions should contain a placeholder - for the context, which is `{context}` by default, defined by the `get_context_placeholder` method. - - Returns: - ChatPromptTemplate: The chat prompt template for the Langchain chain. - """ - instructions = self.get_instructions() - context_placeholder = self.get_context_placeholder() - if self.has_rag and f"{context_placeholder}" not in instructions: - raise AIAssistantMisconfiguredError( - f"{self.__class__.__name__} has_rag=True" - f"but does not have a {{{context_placeholder}}} placeholder in instructions." - ) - - return ChatPromptTemplate.from_messages( - [ - ("system", instructions), - MessagesPlaceholder(variable_name="history"), - ("human", "{input}"), - ("placeholder", "{agent_scratchpad}"), - ] - ) - - @with_cast_id - def get_message_history(self, thread_id: Any | None) -> BaseChatMessageHistory: - """Get the chat message history instance for the given `thread_id`.\n - The Langchain chain uses the return of this method to get the thread messages - for the assistant, filling the `history` placeholder in the `get_prompt_template`.\n - - Args: - thread_id (Any | None): The thread ID for the chat message history. - If `None`, an in-memory chat message history is used. - - Returns: - BaseChatMessageHistory: The chat message history instance for the given `thread_id`. - """ - - # DjangoChatMessageHistory must be here because Django may not be loaded yet elsewhere: - from django_ai_assistant.langchain.chat_message_histories import ( - DjangoChatMessageHistory, - ) - - if thread_id is None: - return InMemoryChatMessageHistory() - return DjangoChatMessageHistory(thread_id) - def get_llm(self) -> BaseChatModel: """Get the Langchain LLM instance for the assistant. By default, this uses the OpenAI implementation.\n @@ -359,15 +301,6 @@ def get_document_prompt(self) -> PromptTemplate: """ return DEFAULT_DOCUMENT_PROMPT - def get_context_placeholder(self) -> str: - """Get the RAG context placeholder to use in the prompt when `has_rag=True`.\n - Defaults to `"context"`. Override this method to use a different placeholder. - - Returns: - str: the RAG context placeholder to use in the prompt. - """ - return "context" - def get_retriever(self) -> BaseRetriever: """Get the RAG retriever to use for fetching documents.\n Must be implemented by subclasses when `has_rag=True`.\n @@ -455,15 +388,23 @@ def as_graph(self, thread_id: Any | None = None) -> Runnable[dict, dict]: Returns: the compiled graph """ + # DjangoChatMessageHistory must be here because Django may not be loaded yet elsewhere. + # DjangoChatMessageHistory was used in the context of langchain, now that we are using + # langgraph this can be further simplified by just porting the add_messages logic. + from django_ai_assistant.langchain.chat_message_histories import ( + DjangoChatMessageHistory, + ) + + message_history = DjangoChatMessageHistory(thread_id) if thread_id else None + llm = self.get_llm() tools = self.get_tools() llm_with_tools = llm.bind_tools(tools) if tools else llm - message_history = self.get_message_history(thread_id) def custom_add_messages(left: list[BaseMessage], right: list[BaseMessage]): result = add_messages(left, right) - if thread_id: + if message_history: messages_to_store = [ m for m in result @@ -504,7 +445,7 @@ def retriever(state: AgentState): } def history(state: AgentState): - history = message_history.messages if thread_id else [] + history = message_history.messages if message_history else [] return {"messages": [*history, HumanMessage(content=state["input"])]} def agent(state: AgentState): @@ -551,23 +492,23 @@ def record_response(state: AgentState): @with_cast_id def invoke(self, *args: Any, thread_id: Any | None, **kwargs: Any) -> dict: - """Invoke the assistant Langchain chain with the given arguments and keyword arguments.\n + """Invoke the assistant Langchain graph with the given arguments and keyword arguments.\n This is the lower-level method to run the assistant.\n - The chain is created by the `as_graph` method.\n + The graph is created by the `as_graph` method.\n Args: - *args: Positional arguments to pass to the chain. + *args: Positional arguments to pass to the graph. Make sure to include a `dict` like `{"input": "user message"}`. thread_id (Any | None): The thread ID for the chat message history. If `None`, an in-memory chat message history is used. - **kwargs: Keyword arguments to pass to the chain. + **kwargs: Keyword arguments to pass to the graph. Returns: - dict: The output of the assistant chain, + dict: The output of the assistant graph, structured like `{"output": "assistant response", "history": ...}`. """ - chain = self.as_graph(thread_id) - return chain.invoke(*args, **kwargs) + graph = self.as_graph(thread_id) + return graph.invoke(*args, **kwargs) @with_cast_id def run(self, message: str, thread_id: Any | None = None, **kwargs: Any) -> str: @@ -578,7 +519,7 @@ def run(self, message: str, thread_id: Any | None = None, **kwargs: Any) -> str: message (str): The user message to pass to the assistant. thread_id (Any | None): The thread ID for the chat message history. If `None`, an in-memory chat message history is used. - **kwargs: Additional keyword arguments to pass to the chain. + **kwargs: Additional keyword arguments to pass to the graph. Returns: str: The assistant response to the user message. diff --git a/django_ai_assistant/helpers/use_cases.py b/django_ai_assistant/helpers/use_cases.py index d41ba9f..b494808 100644 --- a/django_ai_assistant/helpers/use_cases.py +++ b/django_ai_assistant/helpers/use_cases.py @@ -120,7 +120,7 @@ def create_message( content (Any): Message content, usually a string request (HttpRequest | None): Current request, if any Returns: - dict: The output of the assistant chain, + dict: The output of the assistant, structured like `{"output": "assistant response", "history": ...}` Raises: AIUserNotAllowedError: If user is not allowed to create messages in the thread diff --git a/docs/tutorial.md b/docs/tutorial.md index 6a96bda..53692e4 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -1,6 +1,6 @@ --- search: - boost: 2 + boost: 2 --- # Tutorial @@ -17,8 +17,8 @@ The tutorial below uses OpenAI's gpt-4o model, so make sure you have `OPENAI_API You can also use other models, keep reading to learn more. Just make sure their keys are properly set. !!! note - An easy way to set environment variables is to use a `.env` file in your project's root directory and use `python-dotenv` to load them. - Our [example project](https://github.com/vintasoftware/django-ai-assistant/tree/main/example#readme) uses this approach. +An easy way to set environment variables is to use a `.env` file in your project's root directory and use `python-dotenv` to load them. +Our [example project](https://github.com/vintasoftware/django-ai-assistant/tree/main/example#readme) uses this approach. ## What AI Assistants can do @@ -90,8 +90,8 @@ AI: The weather in NYC is sunny with a temperature of 25°C. ``` !!! note - State of the art models such as gpt-4o can process JSON well. - You can return a `json.dumps(api_output)` from a tool method and the model will be able to process it before responding the user. +State of the art models such as gpt-4o can process JSON well. +You can return a `json.dumps(api_output)` from a tool method and the model will be able to process it before responding the user. ### Tool parameters @@ -131,7 +131,7 @@ class WeatherAIAssistant(AIAssistant): ``` !!! note - It's important to provide a `description` for each field from `args_schema`. This improves the LLM's understanding of the tool's arguments. +It's important to provide a `description` for each field from `args_schema`. This improves the LLM's understanding of the tool's arguments. ### Using Django logic in tools @@ -173,8 +173,8 @@ class IssueManagementAIAssistant(AIAssistant): ``` !!! warning - Make sure you only return to the LLM what the user can see, considering permissions and privacy. - Code the tools as if they were Django views. +Make sure you only return to the LLM what the user can see, considering permissions and privacy. +Code the tools as if they were Django views. ### Using pre-implemented tools @@ -219,8 +219,8 @@ class MovieSearchAIAssistant(AIAssistant): ``` !!! note - As of now, Django AI Assistant is powered by [LangChain](https://python.langchain.com/v0.2/docs/introduction/), - but previous knowledge on LangChain is NOT necessary to use this library, at least for the main use cases. +As of now, Django AI Assistant is powered by [LangChain](https://python.langchain.com/v0.2/docs/introduction/), +but previous knowledge on LangChain is NOT necessary to use this library, at least for the main use cases. ## Using an AI Assistant @@ -274,7 +274,7 @@ urlpatterns = [ path("ai-assistant/", include("django_ai_assistant.urls")), ... ] -``` +``` The built-in API supports retrieval of Assistants info, as well as CRUD for Threads and Messages. It has a OpenAPI schema that you can explore at `http://localhost:8000/ai-assistant/docs`, when running your project locally. @@ -415,15 +415,13 @@ shows an example of a composed AI Assistant that's able to recommend movies and ### Retrieval Augmented Generation (RAG) You can use RAG in your AI Assistants. RAG means using a retriever to fetch chunks of textual data from a pre-existing DB to give -context to the LLM. This context goes into the `{context}` placeholder in the `instructions` string, namely the system prompt. -This means the LLM will have access to a context your retriever logic provides when generating the response, +context to the LLM. This means the LLM will have access to a context your retriever logic provides when generating the response, thereby improving the quality of the response by avoiding generic or off-topic answers. For this to work, your must do the following in your AI Assistant: -1. Add a `{context}` placeholder in the `instructions` string; -2. Add `has_rag = True` as a class attribute; -3. Override the `get_retriever` method to return a [Langchain Retriever](https://python.langchain.com/v0.2/docs/how_to/#retrievers). +1. Add `has_rag = True` as a class attribute; +2. Override the `get_retriever` method to return a [Langchain Retriever](https://python.langchain.com/v0.2/docs/how_to/#retrievers). For example: @@ -436,10 +434,6 @@ class DocsAssistant(AIAssistant): instructions = ( "You are an assistant for answering questions related to the provided context. " "Use the following pieces of retrieved context to answer the user's question. " - "\n\n" - "---START OF CONTEXT---\n" - "{context}" - "---END OF CONTEXT---\n" ) model = "gpt-4o" has_rag = True diff --git a/example/rag/ai_assistants.py b/example/rag/ai_assistants.py index 82806c7..83254a5 100644 --- a/example/rag/ai_assistants.py +++ b/example/rag/ai_assistants.py @@ -14,10 +14,6 @@ class DjangoDocsAssistant(AIAssistant): "Use the following pieces of retrieved context from Django's documentation to answer " "the user's question. If you don't know the answer, say that you don't know. " "Use three sentences maximum and keep the answer concise." - "\n\n" - "---START OF CONTEXT---\n" - "{context}" - "---END OF CONTEXT---\n" ) model = "gpt-4o" has_rag = True diff --git a/tests/test_helpers/cassettes/test_assistants/test_AIAssistant_with_rag_invoke.yaml b/tests/test_helpers/cassettes/test_assistants/test_AIAssistant_with_rag_invoke.yaml index 1bffb2f..c163a43 100644 --- a/tests/test_helpers/cassettes/test_assistants/test_AIAssistant_with_rag_invoke.yaml +++ b/tests/test_helpers/cassettes/test_assistants/test_AIAssistant_with_rag_invoke.yaml @@ -1024,4 +1024,743 @@ interactions: status: code: 200 message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "I''m at Central Park + W & 79st, New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", + "n": 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '920' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1SRQW/aQBCF7/4Voz3jyjYYCJeqSlupUoqokogmUYXW6zHest6xdoY2UcR/r9YQ + SC8+vG/f05vn1wRA2VotQJlWi+l6l36aLvn6a/Vj9eXqeXn3c3b3iDffb76tp59Xa6NG0UHVbzTy + 5vpgqOsdiiV/xCagFoyp+ayYZvMyz7IBdFSji7ZtL+mE0iIrJmlWpvn4ZGzJGmS1gKcEAOB1+MaK + vsZntYAhZlA6ZNZbVIvzIwAVyEVFaWbLor2o0QUa8oJ+aL1utYAOCEwdgkcdqhfQIkGbeAWDEPyx + bAW0wDV6CdrBSocdrJEFtK9hdiUt3EpAFLAelvgXHijsRrB8gDzLiskI7r0VrOFWtCB/fF8lYLNn + HZfwe+dO+uF8m6NtH6jiEz/rjfWW201AzeTjHSzUq4EeEoBfw4b7/2ZRfaCul43QDn0MzMv5MU9d + /tqFFm9QSLR755pPk1NDxS8s2G0a67cY+mCPkzb9Ji9n1Xg+zptSJYfkHwAAAP//AwDTLoRgWwIA + AA== + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", "n": + 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '745' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//VJJPb9pAEMXv/hTTvfRiEJg/QdyithJKRFSpl1ZRhZZlbC/YO9bMmMSJ + +O7VGgLpZQ/vt2/2ad6+JwDG78wSjCuturqpBvfzJ/n+az3fVfg7PKzeHnXx+GZpWx/X+5VJo4O2 + e3T64Ro6qpsK1VM4Y8doFePU8V02Hy1m49G4BzXtsIq2otHBlAbZKJsORrPBeHIxluQdilnCcwIA + 8N6fMWLY4atZwij9UGoUsQWa5fUSgGGqomKsiBe1QU16g46CYuhT/6H2KyOwL0qFbQffMCjbCn5a + PqTQIOfoFHJisCAOg3fwYqsDEEPjXfBuCA+tKFjHJAJaIogyoqbQUQvOBjh68dqT+xrZR2ndCrY1 + UA5PVtv43sqLEncpvJTelUB5jiyQW3E+WPWhAHwt/darAAXAI3KnZZRzphp2PpDYlgWUgFpFBmms + wyH8CHvqYhQG9TV++bwGxrwVG1sIbVVd9NN1rxUVDdNWLvyq5z54KTeMVijEHYpSY3p6SgD+9v21 + /1ViGqa60Y3SAUMcOM4W53nm9mNudDq7QCW11SfX3SS5JDTSiWK9yX0okBv25zrzZpPN5tnU4sTO + THJK/gEAAP//AwC6ETmv1wIAAA== + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "11 W 53rd St, New York, + NY 10019, United States.", "role": "user"}], "model": "gpt-4o", "n": 1, "stream": + false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '904' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//VJFLa8MwEITv/hWLznaxnLpNcimhBPqAXEopoZQg22tbqa0V0qZP8t+L + HCdtLzrMp1nNrL4jAKErMQdRtorL3nbJ4mLll+9r9bVazhZ3i4+iaW/f7q+3X5W+YREHBxVbLPno + Oiuptx2yJnPApUPFGKbKy+wineYyzQbQU4VdsDWWk3NKsjQ7T9I8kZPR2JIu0Ys5PEcAAN/DGSKa + Cj/EHNL4qPTovWpQzE+XAISjLihCea89K3OIO8KSDKMZUj+1ikE5BG4RDCpXfIJidqoMJTwoRztT + gZTwBPnEVfDAMazwHdbkXmNYrUGmqZzF8Gg0Y8CK0V/9fc1hvfMqlDW7rhv1/Sl+R411VPiRn/Ra + G+3bjUPlyYSonsmKge4jgJdhTbt/zYV11FveML2iCQNlnh/mid+P+aXZETKx6v64pmk0JhT+0zP2 + m1qbBp11+rC12m5kfllMphNZ5yLaRz8AAAD//wMA0Ofn4T4CAAA= + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}, {"content": "You''re right + by Central Park, perfect for a scenic walk or picnic. Just across the street, + you can visit the American Museum of Natural History, which offers fascinating + exhibits on everything from dinosaurs to outer space. Enjoy your time!", "role": + "assistant"}, {"content": "11 W 53rd St, New York, NY 10019, United States.", + "role": "user"}], "model": "gpt-4o", "n": 1, "stream": false, "temperature": + 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '1104' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1RSy44TQQy85ytMXwBpssprAptbFgHiEF4nHkJRp8eT6aSn3dieXaJV/h31JJvA + pQ9VLrvs6scBgPGVWYBxjVXXpjBczj/K+3d69/bLLI1+6PTzBynn9bfbT91u+tsUWUGbHTp9Ut04 + alNA9RRPtGO0irnr+NVkPnpdjkeznmipwpBl26TDGQ0no8lsOCqH4+lZ2JB3KGYBPwcAAI/9my3G + Cv+YBYyKJ6RFEbtFs7gUARimkBFjRbyojWqKK+koKsbe9XfqnjNCRMugDcKqE+xaoBpWVCFHWLLC + ixWtli8LeGi8a6BGqx2jgI3g28Qo4u8RHIWALq+e1f2INhFbPoCNFbSndpb1BpZV5XOhDeFQwOFk + wQUSBCX4Sm6PNYaADG8wKnKejIy5EpyNgHFHB5CGkhRQ+ejjtuiH5A1oI8j3tjdSodtDTQw+OsbK + bwKC83qAe48PcgN3pA1YVba9cQHLCG0nOhREefbvzRjrTmyOLHYhnPHjJYRA28S0kTN/wWsfvTRr + RisU88FFKZmePQ4AfvVhd//lZxJTm3SttMeYG45vb0/9zPV7XdlydiaV1IYrPimng7NDIwdRbNe1 + j1vkxP6UfZ3Wk3I+mVmc2tIMjoO/AAAA//8DAOKObt8EAwAA + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "I''m at Central Park + W & 79st, New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", + "n": 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '920' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1SRwW7bMBBE7/qKBc9SITGS7PhSBLkkF7dBELhBEBhraW2xpkiWXNUJAv97QVmx + 0wsP83YWs8OPBECoVixANB1y0zud3dTLwc4OdJ8/DA+Fe7oNv/7e9z8Od3L1x4k0OuzmNzX86frW + 2N5pYmXNCTeekCluLWayzueVrOUIetuSjrad46y0mcxlmeVVVlxNxs6qhoJYwEsCAPAxvjGiaelN + LCBPP5WeQsAdicV5CEB4q6MiMAQVGA2L9AIba5jMmHrVIQN6Au4IjGXcaAJk9tjEKwIYQg+3ZNij + hp/o97CiwICmhdk1d/DInohTWNIBnq3fp7B8hiLPZZnCk1FMLTwyMoXvXxN42g4BYwFm0HrSj+eT + tN05bzdh4md9q4wK3doTBmti/MDWiZEeE4DXsbrhvzaE87Z3vGa7JxMXFtX8tE9cPutCZT1Btoz6 + i2teJlNCEd4DU7/eKrMj77w6Nbl1a1nVskS6wkokx+QfAAAA//8DAENg4sRSAgAA + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", "n": + 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '745' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//VFJNb1oxELzzK1a+9AIRPD6CuEWVqkoRaW5RW1Vo8dv3nouf1/KuW2jE + f68MBJKLDzM7O6Mdvw4AjKvNCoztUG0f/ehh8ZTj7vHlZd21P9bTZsld+pYeJ//a7ZdshkXB299k + 9U11Z7mPntRxONM2ESqVrZP7ajFezqvF9ET0XJMvsjbqaMajalzNRuP5aDK9CDt2lsSs4OcAAOD1 + 9JaIoaa9WcF4+Ib0JIItmdV1CMAk9gUxKOJEMagZ3kjLQSmcUn/n/CkRJNd2CoH2CsqgHcFDT8lZ + DLDOQrkHbuAJNSf08NWJcjoM4W/nbAcNFZwEGhTrAqoLLdC+c1unAhyA/lA6aFfgJnEPtQssmJMU + L4lo6Q6efZYhHM5pUE8RqG6p+H6moMX3GdNuCJFSQ1ah4QQIoom9B06QyOO+eGDvalHYEmZ1Tfbg + MdRiMZLcvb9CoiYLlhJC9v6CH69n9dzGxFu58Fe8ccFJt0mEwqGcUJSjObHHAcCvU335QyMmJu6j + bpR3FMrCSbU87zO3D3NjZ9WFVFb071T348EloZGDKPWbxoWWUkzu3GYTN9V8Uc2Qpjg3g+PgPwAA + AP//AwDQesQS1gIAAA== + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "11 W 53rd St, New York, + NY 10019, United States.", "role": "user"}], "model": "gpt-4o", "n": 1, "stream": + false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '904' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1SRT4/aMBDF7/kUI5+TVZwQoFxWi9pTKxapXVFUVcgkE+KSeFx7opZFfPfK4W8v + Pryf3/i98TECELoSMxBlo7jsbJu8jBe9m3/M5vMvy+p1+d58H32y3VKtfuffPos4OGj7C0u+up5K + 6myLrMmccelQMYapcpKN02mRjYsBdFRhG2w7y8mIkizNRklaJDK/GBvSJXoxgx8RAMBxOENEU+Ff + MYM0viodeq92KGa3SwDCURsUobzXnpVhEd9hSYbRDKlXjWJQDsFTh2BQue0BFLNTZWjhQTnqTQVS + wgqK3FXwlWNY4B9Yk9vHsFiDTFP5IYY3oxkDVoz++fE5h3XvVWhr+ra96Kdb/pZ21tHWX/hNr7XR + vtk4VJ5MyOqZrBjoKQL4Oeyp/6+6sI46yxumPZowUBbFeZ64/8ydZlfIxKp9cE3T6JJQ+INn7Da1 + Njt01unz2mq7kcVkm09zWRciOkX/AAAA//8DACNhDe0/AgAA + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}, {"content": "You''re right + next to the American Museum of Natural History, which features fascinating exhibits + on everything from dinosaurs to space. Plus, you''re at the edge of Central + Park, perfect for a stroll or relaxing amidst beautiful landscapes.", "role": + "assistant"}, {"content": "11 W 53rd St, New York, NY 10019, United States.", + "role": "user"}], "model": "gpt-4o", "n": 1, "stream": false, "temperature": + 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '1103' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//VFJNb9swDL37VxC6bAPsIHGdtM0t2GXDlh2GDdgHhkCRaVu1LAoi3TYo + +t8HOV/bRYf3+MhHPr1kAMrWag3KdFrMEFyxWX0ZhasPm/uPfX+HzeI5fv7+7ZHmn36VP1SeFLR/ + QCNn1czQEByKJX+kTUQtmLoubsvV/G5Zrm4nYqAaXZK1QYqKinJeVsV8WSxuTsKOrEFWa/idAQC8 + TG+y6Gt8VmuY52dkQGbdolpfigBUJJcQpZkti/ai8itpyAv6yfVPGt9EBI86gnQI25FxHIAa2FKN + 0cMmCrzd0nbzLoenzpoO9qRZGLQHO4SIzPYRwZBzaNLiSTsNGAJFHQ+gfQ3DsZmO8kSx5xls6tqm + au3cIYfD0YVxxAhC8JVMjw06hxHeoxeMaThGTJVgtAf0D3QA7ihwDrX11rf5NCkt0eiBRgZrsOBe + i/UtROv72b83iNiMrFMEfnTuhL9ejuqoDZH2fOIveGO95W4XUTP5dEAWCmpiXzOAP1N44395qBBp + CLIT6tGnhov71bGfun6XK1udSSHR7oqXVZmdHCo+sOCwa6xvMYZoj1k2YVcuV2Wl8UYvVfaa/QUA + AP//AwBcbrCW1AIAAA== + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "I''m at Central Park + W & 79st, New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", + "n": 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '920' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1SRQW8aMRCF7/srRj60F7YCL0solwpFapMLqtRDGkUVGswsa/B6LHuWNIn479Uu + G0gvPrzPb/ze+C0DUHarFqBMjWKa4PLlbHV83i9f7/jV/bDHdqP13e/9MbTf5XapRp2DN3sy8u76 + YrgJjsSyP2MTCYW6qZMbPRvPy6LQPWh4S66z7YLkU871WE/zcZlPisFYszWU1AKeMgCAt/7sIvot + /VULGI/elYZSwh2pxeUSgIrsOkVhSjYJelGjKzTshXyf+qFGAYwEiRsCTxg3L4AiEU3XIsE9GPRw + tMkK2AruPzeAArfkJaKDnxgP8EBJ4BPcfJUafkkkErAeVvQMjxwPI1g9fvv4eqSqTdiV961zg366 + 1HG8C5E3aeAXvbLepnodCRP7LnoSDqqnpwzgT7+29r9NqBC5CbIWPpDvBk7K+Xmeun7UlepygMKC + 7oNrXmRDQpVeklCzrqzfUQzRnrdYhbUuZ3qKVGCpslP2DwAA//8DAKfaPTVOAgAA + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}], "model": "gpt-4o", "n": + 1, "stream": false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '745' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1RSy24bMQy8+ytYne3A8auGb+m7BZoWaA8tisLgarle2VpRpajE2yD/XmjtPHoR + hBnOkODwbgRgXG02YGyLarvoJ1er65ujnU17Dp++/InHPsoi7z7+3b//8UbMuCi42pPVB9WF5S56 + UsfhRFshVCquly9nq+l6OZ/PB6LjmnyR7aJOFjyZTWeLyXQ5uZyfhS07S8ls4NcIAOBueMuIoaaj + 2cB0/IB0lBLuyGweiwCMsC+IwZRcUgxqxk+k5aAUhql/cgYUAnG7VqHqQVuCq47EWQzwOSfKHXAD + 16hZ0MMHl5SlH8NtS0LQc4ZSSMfoWQgaTNYFVBd2QMfWVU4TcAC6Iem1LXAj3EHtAifMkkAZOCsJ + pIiWLuA1BS2NvqIcwCVAnxj2OSkkpZgAb7EfAzcNSXGrCLO6JntQQefTGCoe2o8BQw3OcnAWPIa6 + Qzkk8O5A8Iq0pVQjfCcRtDSUflPB24pEenjnyNfpAt6GPfeAEEkasgqVp1CXbYSyjZPMZl/+L57v + V6jJCUu8IXt/xu8fA/O8i8JVOvOPeOOCS+1WCBOHEk5SjmZg70cAv4fDyP9lbaJwF3WrfKBQDC9n + 65OfeTrFJ3b5QCor+meq9Wp0ntCkPil128aFHUkUd7qTJm5ny9VsgTTHpRndj/4BAAD//wMAN+Gj + +zADAAA= + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "Given a chat history and the latest user question + which might reference context in the chat history, formulate a standalone question + which can be understood without the chat history. Do NOT answer the question, + just reformulate it if needed and otherwise return it as is.", "role": "system"}, + {"content": "You are a tour guide assistant offers information about nearby + attractions. The user is at a location and wants to know what to learn about + nearby attractions. Use the following pieces of context to suggest nearby attractions + to the user. If there are no interesting attractions nearby, tell the user there''s + nothing to see where they''re at. Use three sentences maximum and keep your + suggestions concise.", "role": "system"}, {"content": "11 W 53rd St, New York, + NY 10019, United States.", "role": "user"}], "model": "gpt-4o", "n": 1, "stream": + false, "temperature": 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '904' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAA1SRzYvbMBDF7/4rBp3t4o84zeZSSnvYwhJallKWpYSJPXbUtTVCM24blvzvRc7X + 9qLD++mN3hu9JgDGtmYNptmjNqMfso/Lze/Dl8e7VrCvN58fym/Lh/L+ftVh1301aXTw7hc1enG9 + a3j0A6lld8JNIFSKU4v35TJf1VW1mMHILQ3R1nvNFpyVebnI8jorqrNxz7YhMWt4TgAAXuczRnQt + /TVryNOLMpII9mTW10sAJvAQFYMiVhSdmvQGG3ZKbk79CR0ceAKZ+p5EwRGG3QFQNWATewigQlHA + D6ir0MKjprChP/DE4SWFzRMUeV7cpfDdWaWIUUk+vH0sUDcJxq5uGoazfrymH7j3gXdy5le9s87K + fhsIhV1MKsrezPSYAPyctzT9V9z4wKPXrfILuTiwqOvTPHP7lxstL1BZcXjjWuXJOaGRgyiN2866 + noIP9rS0zm/LelkukCqsTXJM/gEAAP//AwAnkigEPQIAAA== + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK +- request: + body: '{"messages": [{"content": "You are a tour guide assistant offers information + about nearby attractions. The user is at a location and wants to know what to + learn about nearby attractions. Use the following pieces of context to suggest + nearby attractions to the user. If there are no interesting attractions nearby, + tell the user there''s nothing to see where they''re at. Use three sentences + maximum and keep your suggestions concise.", "role": "system"}, {"content": + "---START OF CONTEXT---\nCentral Park\n\nAmerican Museum of Natural History---END + OF CONTEXT---\n", "role": "system"}, {"content": "I''m at Central Park W & 79st, + New York, NY 10024, United States.", "role": "user"}, {"content": "You are right + by the American Museum of Natural History, where you can explore fascinating + exhibits on everything from dinosaurs to outer space. Central Park is also just + steps away, offering beautiful trails, boating, and iconic landmarks like Bethesda + Terrace and Strawberry Fields. Enjoy a perfect blend of nature and culture!", + "role": "assistant"}, {"content": "11 W 53rd St, New York, NY 10019, United + States.", "role": "user"}], "model": "gpt-4o", "n": 1, "stream": false, "temperature": + 1.0}' + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - DUMMY + connection: + - keep-alive + content-length: + - '1193' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: !!binary | + H4sIAAAAAAAAAwAAAP//VFLbahsxEH33Vwx6aQtr46wvCX5LSi8QnJZQUtpSzFg761Wt1YjRrF0n + 5N+L1s6lL0LM0TkzR3MeBgDGVWYBxjaoto1+eDm/2d3Hu7sP1z/LaRXj8nYz+Zjur67vP7dfTJEZ + vP5DVp9YI8tt9KSOwxG2QqiUVc/Oy/n4YjaZzHqg5Yp8pm2iDqc8LMfldDieDc8mJ2LDzlIyC/g1 + AAB46M88Yqjor1nAuHiqtJQSbsgsnh8BGGGfKwZTckkxqCleQMtBKfRT/+DujRCggjYEyy5R1wLX + sOSKJMClKLxd8vLyXQH7xtkGakLthBJgANdGoZTcjsCy92Sz8czuG7SRBeUAGCpoj3IoWoAL1neV + CxvYs2wTrA9whwE+8aYp4DtKw77oSV+dxZR4BDeEsj4UcOAOLAZAnxh2LjmFW7Zbqsl7EnhPQUmg + ZgGnCZzl4Cw4S5C2qLmhuLDtpSMGFmydhZ2jfYJauO1/4BvHbCBfszTwOpHssDdWkd2O4Iq1AVQV + 7O0m4LomAYRN3jXYzmsn6IH+RhJHwRK40As2hKL957pKeR9giaFBVQyj19sRqruEORyh8/5Uf3xe + t+dNFF6nE/5cr11wqVkJYeKQV5uUo+nRxwHA7z5W3X9JMVG4jbpS3lLIguVZedQzL0F+Qc+nJ1BZ + 0b9iXcwHpwlNOiSldlW7sCGJ4o4pq+OqnM3LKdIEZ2bwOPgHAAD//wMACpSosW4DAAA= + headers: + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: Sun, 09 Jun 2024 23:39:08 GMT + Server: DUMMY + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + status: + code: 200 + message: OK version: 1 diff --git a/tests/test_helpers/test_assistants.py b/tests/test_helpers/test_assistants.py index e288ef2..70cf7fd 100644 --- a/tests/test_helpers/test_assistants.py +++ b/tests/test_helpers/test_assistants.py @@ -50,10 +50,6 @@ class TourGuideAssistant(AIAssistant): "If there are no interesting attractions nearby, " "tell the user there's nothing to see where they're at. " "Use three sentences maximum and keep your suggestions concise." - "\n\n" - "---START OF CONTEXT---\n" - "{context}" - "---END OF CONTEXT---\n" ) model = "gpt-4o" has_rag = True @@ -176,17 +172,16 @@ def test_AIAssistant_with_rag_invoke(): assert response_0["input"] == "I'm at Central Park W & 79st, New York, NY 10024, United States." assert response_0["output"] == ( - "You can visit the American Museum of Natural History, which is located " - "right next to Central Park. It's a short walk and offers fascinating exhibits " - "on a wide range of natural science topics. Enjoy both the park's natural beauty " - "and the museum's educational wonders." + "You're right by Central Park, perfect for a scenic walk or picnic. Just across the " + "street, you can visit the American Museum of Natural History, which offers fascinating " + "exhibits on everything from dinosaurs to outer space. Enjoy your time!" ) assert response_1["input"] == "11 W 53rd St, New York, NY 10019, United States." assert response_1["output"] == ( - "You're right by the Museum of Modern Art (MoMA). It's a world-renowned " - "museum featuring an extensive collection of contemporary and modern art. " - "Enjoy exploring iconic works from famous artists like Van Gogh, " - "Picasso, and Warhol." + "You're near the Museum of Modern Art (MoMA), which features an impressive collection " + "of contemporary and modern art. Additionally, you're close to Rockefeller Center, " + "where you can enjoy shops, dining, and the observation deck for incredible city " + "views. Both attractions are must-sees!" ) expected_messages = messages_to_dict(