From b77345f0a3ef901779f54a6148191149e1687593 Mon Sep 17 00:00:00 2001 From: Aditya Vikram Thoomati Date: Tue, 8 Aug 2023 08:29:57 +0530 Subject: [PATCH 1/4] gpt model addn to conversation and seperate trimmed history + formatting --- README.md | 4 +-- agentai/conversation.py | 32 +++++++++++++++++------ docs/04_Evaluating_OpenAI_Functions.ipynb | 1 + docs/05_Conversation_History.ipynb | 9 ++++--- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3e2ff24..57506e2 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Note that `agentai` automatically parses the Python Enum type (TemperatureUnit) 3. **Create a Conversation object and add messages** ```python -conversation = Conversation() +conversation = Conversation(model=GPT_MODEL) conversation.add_message("user", "what is the weather like today?") ``` @@ -152,7 +152,7 @@ agent_system_message = """You are ChinookGPT, a helpful assistant who gets answe Provide as many details as possible to your users Begin!""" -sql_conversation = Conversation() +sql_conversation = Conversation(model=GPT_MODEL) sql_conversation.add_message(role="system", content=agent_system_message) sql_conversation.add_message("user", "Hi, who are the top 5 artists by number of tracks") assistant_message = chat_complete_execute_fn( diff --git a/agentai/conversation.py b/agentai/conversation.py index c1caa1a..93e35e3 100644 --- a/agentai/conversation.py +++ b/agentai/conversation.py @@ -13,8 +13,11 @@ class Message(BaseModel): class Conversation: - def __init__(self, history: List[Message] = [], id: Optional[str] = None, max_history_tokens: int = 200): + def __init__( + self, history: List[Message] = [], id: Optional[str] = None, max_history_tokens: int = 200, model: str = "gpt2" + ): self.history: List[Message] = history + self.trimmed_history: List[Message] = [] self.role_to_color = { "system": "red", "user": "green", @@ -23,6 +26,7 @@ def __init__(self, history: List[Message] = [], id: Optional[str] = None, max_hi } self.id = id self.max_history_tokens = max_history_tokens + self.model = model def add_message(self, role: str, content: str, name: Optional[str] = None) -> None: message_dict = {"role": role, "content": content} @@ -30,6 +34,7 @@ def add_message(self, role: str, content: str, name: Optional[str] = None) -> No message_dict["name"] = name message = Message(**message_dict) self.history.append(message) + self.trim_history() def display_conversation(self) -> None: for message in self.history: @@ -40,25 +45,36 @@ def display_conversation(self) -> None: ) ) - def get_history(self) -> List[Message]: + def trim_history(self) -> None: """Function to get the conversation history based on the number of tokens""" + local = threading.local() try: - enc = local.gpt2enc + enc = local.encoder except AttributeError: - enc = tiktoken.get_encoding("gpt2") - local.gpt2enc = enc + enc = tiktoken.encoding_for_model(self.model) + local.encoder = enc total_tokens = 0 # Iterate 2 at a time to avoid cutting in between a (prompt, response) pair - for i in range(len(self.history) -1, -1, -2): + for i in range(len(self.history) - 1, -1, -2): # Iterate over the messages in reverse order - from the latest to the oldest messages message = self.history[i] # Message(role='User', content='I appreciate that. Take care too!', name=None) content = message.content tokens = len(enc.encode(content)) total_tokens += tokens if total_tokens > self.max_history_tokens: - # Trim the history inplace to keep the total tokens under max_tokens - self.history = self.history[i + 1 :] + # Trim the history to keep the total tokens under max_tokens + # and store the trimmed history in self.trimmed_history + # to have a faster access to it later + self.trimmed_history = self.history[i + 1 :] break + + def get_history(self, trimmed: bool = False) -> List[Message]: + # Return the trimmed history if it exists and trimmed is True + if trimmed: + if not self.trimmed_history: + self.trim_history() + return self.trimmed_history + # Return the full history otherwise return self.history diff --git a/docs/04_Evaluating_OpenAI_Functions.ipynb b/docs/04_Evaluating_OpenAI_Functions.ipynb index 8b0e97d..8de2d64 100644 --- a/docs/04_Evaluating_OpenAI_Functions.ipynb +++ b/docs/04_Evaluating_OpenAI_Functions.ipynb @@ -23667,6 +23667,7 @@ ], "source": [ "import json\n", + "\n", "with open(\"evaluation_resuls.json\", \"w\") as f:\n", " json.dump(evaluation_results, f, indent=4)\n", "\n", diff --git a/docs/05_Conversation_History.ipynb b/docs/05_Conversation_History.ipynb index 3c0d2a1..e6522f1 100644 --- a/docs/05_Conversation_History.ipynb +++ b/docs/05_Conversation_History.ipynb @@ -9,7 +9,7 @@ "from agentai.conversation import Conversation\n", "\n", "# Create a conversation object with a maximum history length of 100 tokens\n", - "conversation = Conversation(max_history_tokens=100)" + "conversation = Conversation(max_history_tokens=100, model=\"gpt-3.5-turbo\")" ] }, { @@ -18,7 +18,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "# Chatgpt Simulated conversations of different length\n", "conversation.add_message(\"User\", \"Hello!\")\n", "conversation.add_message(\"Assistant\", \"Hi there!\")\n", @@ -77,7 +76,7 @@ " \"You're welcome! I hope these tips help you find some relief from stress. If you have any more questions or need further assistance, don't hesitate to ask. Take care!\",\n", ")\n", "conversation.add_message(\"User\", \"I appreciate that. Take care too!\")\n", - "conversation.add_message(\"Assistant\", \"Thank you! Have a fantastic day!\")\n" + "conversation.add_message(\"Assistant\", \"Thank you! Have a fantastic day!\")" ] }, { @@ -115,7 +114,9 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "trimmed_history = conversation.get_history(trimmed=True)" + ] } ], "metadata": { From 9086f49a4a5f87d5e42a6be2aa6837c5d7602ef7 Mon Sep 17 00:00:00 2001 From: adivik2000 Date: Wed, 9 Aug 2023 16:41:20 +0530 Subject: [PATCH 2/4] defaulting model for conversation to "gpt-3.5-turbo" --- agentai/conversation.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/agentai/conversation.py b/agentai/conversation.py index 93e35e3..52359d7 100644 --- a/agentai/conversation.py +++ b/agentai/conversation.py @@ -14,7 +14,11 @@ class Message(BaseModel): class Conversation: def __init__( - self, history: List[Message] = [], id: Optional[str] = None, max_history_tokens: int = 200, model: str = "gpt2" + self, + history: List[Message] = [], + id: Optional[str] = None, + max_history_tokens: int = 200, + model: str = "gpt-3.5-turbo", ): self.history: List[Message] = history self.trimmed_history: List[Message] = [] From 1f8d9781077e295ebcc407c29295650521383616 Mon Sep 17 00:00:00 2001 From: adivik2000 Date: Wed, 9 Aug 2023 16:58:28 +0530 Subject: [PATCH 3/4] max_history_tokens and model defaulting to none and optional --- agentai/conversation.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/agentai/conversation.py b/agentai/conversation.py index 52359d7..f7d0315 100644 --- a/agentai/conversation.py +++ b/agentai/conversation.py @@ -17,9 +17,9 @@ def __init__( self, history: List[Message] = [], id: Optional[str] = None, - max_history_tokens: int = 200, - model: str = "gpt-3.5-turbo", - ): + max_history_tokens: Optional[int] = None, + model: Optional[str] = None, + ) -> None: self.history: List[Message] = history self.trimmed_history: List[Message] = [] self.role_to_color = { @@ -38,7 +38,8 @@ def add_message(self, role: str, content: str, name: Optional[str] = None) -> No message_dict["name"] = name message = Message(**message_dict) self.history.append(message) - self.trim_history() + if self.max_history_tokens and self.model: + self.trim_history() def display_conversation(self) -> None: for message in self.history: @@ -52,6 +53,12 @@ def display_conversation(self) -> None: def trim_history(self) -> None: """Function to get the conversation history based on the number of tokens""" + # raise an error if max_history_tokens or model is not set + if not self.max_history_tokens: + raise ValueError("max_history_tokens is not set in Conversation") + if not self.model: + raise ValueError("model is not set in Conversation") + local = threading.local() try: enc = local.encoder From 682dbfa1aa0f795e3f94131f38697575d26c09fa Mon Sep 17 00:00:00 2001 From: adivik2000 Date: Wed, 9 Aug 2023 17:18:16 +0530 Subject: [PATCH 4/4] added a note to conversation history notebook --- docs/05_Conversation_History.ipynb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/05_Conversation_History.ipynb b/docs/05_Conversation_History.ipynb index e6522f1..e5c5d3d 100644 --- a/docs/05_Conversation_History.ipynb +++ b/docs/05_Conversation_History.ipynb @@ -9,7 +9,10 @@ "from agentai.conversation import Conversation\n", "\n", "# Create a conversation object with a maximum history length of 100 tokens\n", - "conversation = Conversation(max_history_tokens=100, model=\"gpt-3.5-turbo\")" + "conversation = Conversation(max_history_tokens=100, model=\"gpt-3.5-turbo\")\n", + "# Note: max_history_tokens allows you to control the length of the conversation history in your prompt.\n", + "# Specify the 'model' being used if you're using the 'max_history_tokens'.\n", + "# 'model' here is used to pick the tokenizer for trimming the conversation history. " ] }, { @@ -135,7 +138,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.16" + "version": "3.11.4" }, "orig_nbformat": 4 },