From 97ff1bdfcf58766180cdd66fa1094d45c23340b7 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Thu, 13 Apr 2023 23:09:14 -0700 Subject: [PATCH] Update notebook` --- docs/use_cases/agents/characters.ipynb | 636 +++++++++---------------- 1 file changed, 236 insertions(+), 400 deletions(-) diff --git a/docs/use_cases/agents/characters.ipynb b/docs/use_cases/agents/characters.ipynb index 0bb4bcfc39a..7f74b696bc8 100644 --- a/docs/use_cases/agents/characters.ipynb +++ b/docs/use_cases/agents/characters.ipynb @@ -5,7 +5,11 @@ "id": "e9732067-71c7-46f7-ad09-381b3bf21a27", "metadata": {}, "source": [ - "# LangChain Implementation of Generative Agents: Interactive Simulacra of Human Behavior" + "# Generative Agents in LangChain\n", + "\n", + "This notebook implements a generative agent based on the paper [Generative Agents: Interactive Simulacra of Human Behavior](https://arxiv.org/abs/2304.03442) by Park, et. al.\n", + "\n", + "In it, we leverage a time-weighted Memory object backed by a LangChain Retriever." ] }, { @@ -15,6 +19,7 @@ "metadata": {}, "outputs": [], "source": [ + "# Use termcolor to make it easy to colorize the outputs.\n", "!pip install termcolor > /dev/null" ] }, @@ -29,7 +34,7 @@ "source": [ "import re\n", "from datetime import datetime, timedelta\n", - "from typing import Any, Dict, List, Optional, Tuple\n", + "from typing import List, Optional, Tuple\n", "from termcolor import colored\n", "\n", "from pydantic import BaseModel, Field\n", @@ -44,32 +49,37 @@ "from langchain.vectorstores import FAISS\n" ] }, + { + "cell_type": "code", + "execution_count": 3, + "id": "81824e76", + "metadata": {}, + "outputs": [], + "source": [ + "USER_NAME = \"Person A\" # The name you want to use when interviewing the agent.\n", + "LLM = ChatOpenAI(max_tokens=1500) # Can be any LLM you want." + ] + }, { "cell_type": "markdown", "id": "c3da1649-d88f-4973-b655-7042975cde7e", "metadata": {}, "source": [ - "## Key Components\n", - "- Observational loop\n", - " - Need to connect to some world. Can simulate\n", - "- Memory - 2 types\n", - " 1. Observations - list/stack of observations\n", - " 2. Reflections - Syntheses over recent history\n", - "- Memory Retrieval\n", - " - Weighted sum of recency and saliency\n", - "- Planning / Plan update" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "0a0fe498-da9d-4c17-a815-cd9b49d22a05", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "LLM = ChatOpenAI(max_tokens=1500) # Can be any LLM you want." + "### Generative Agent Memory Components\n", + "\n", + "This tutorial highlights the memory of generative agents and its impact on their behavior. The memory varies from standard LangChain Chat memory in two aspects:\n", + "\n", + "1. **Memory Formation**\n", + "\n", + " Generative Agents have extended memories, stored in a single stream:\n", + " 1. Observations - from dialogues or interactions with the virtual world, about self or others\n", + " 2. Reflections - resurfaced and summarized core memories\n", + "\n", + "2. **Memory Recall**\n", + "\n", + " Memories are retrieved using a weighted sum of salience, recency, and importance.\n", + "\n", + "Review the definition below, focusing on `add_memory` and `summarize_related_memories` methods." ] }, { @@ -178,8 +188,6 @@ " new_insights.extend(insights)\n", " return new_insights\n", " \n", - " \n", - " \n", " def _score_memory_importance(self, memory_content: str) -> float:\n", " \"\"\"Score the absolute importance of the given memory.\"\"\"\n", " prompt = PromptTemplate.from_template(\n", @@ -193,14 +201,23 @@ " )\n", " chain = LLMChain(llm=self.llm, prompt=prompt, verbose=self.verbose)\n", " score = chain.run(memory_content=memory_content).strip()\n", - " return float(score[0]) / 10\n", - " \n", + " match = re.search(r\"^\\D*(\\d+)\", score)\n", + " if match:\n", + " return float(score[0]) / 10\n", + " else:\n", + " return 0.0\n", + "\n", + "\n", " def add_memory(self, memory_content: str) -> List[str]:\n", " \"\"\"Add an observation or memory to the agent's memory.\"\"\"\n", " importance_score = self._score_memory_importance(memory_content)\n", " self.memory_importance += importance_score\n", " document = Document(page_content=memory_content, metadata={\"importance\": importance_score})\n", " result = self.memory_retriever.add_documents([document])\n", + "\n", + " # After an agent has processed a certain amount of memories (as measured by\n", + " # aggregate importance), it is time to reflect on recent events to add\n", + " # more synthesized memories to the agent's memory stream.\n", " if (self.reflection_threshold is not None \n", " and self.memory_importance > self.reflection_threshold\n", " and self.status != \"Reflecting\"):\n", @@ -321,204 +338,80 @@ " action_prediction_chain = LLMChain(llm=self.llm, prompt=prompt)\n", " result = action_prediction_chain.run(**kwargs)\n", " return result.strip()\n", - "\n", - "\n", - " ###############################################################################\n", - " # Below are methods that can be used to generate a daily plan. They are not\n", - " # required for simple conversations, but can be useful for inducing context with\n", - " # a virtual game. This works by\n", - " # 1. Generate a coarse plan of the day based on the agent's \"qualities\",\n", - " # yesterday's activities, and the current day.\n", - " # 2. Refine each step to an hour-by-hour plan.\n", - " # 3. Refine each hourly step to 5-15 minute intervals.\n", - " ###############################################################################\n", - " def _create_coarse_plan(self, verbose: bool = False) -> List[str]:\n", - " previous_day_summary = self.daily_summaries[-1]\n", - " current_date = datetime.now()\n", - " prompt = PromptTemplate.from_template(\n", - " \"Name: {name} (age: {age})\"\n", - " +\"\\nInnate traits: {innate_traits}\"\n", - " + '\\nOn {previous_day}, {name}'\n", - " + \" {previous_day_summary}\"\n", - " + '\\nToday is {current_day}.'\n", - " + \" Here is {name}'s plan today\"\n", - " + \" in broad strokes:\"\n", - " + \"\\n1. \"\n", - " )\n", - " previous_day = (current_date - timedelta(days=1)).strftime(\"%A %B %d\")\n", - " current_day = current_date.strftime(\"%A %B %d\")\n", - " coarse_planner = LLMChain(llm=self.llm, prompt=prompt, verbose=verbose)\n", - " result = coarse_planner.run(name=self.name,\n", - " current_day=current_day,\n", - " age=self.age,\n", - " innate_traits=self.traits,\n", - " previous_day=previous_day,\n", - " previous_day_summary=previous_day_summary\n", - " )\n", - " return self._parse_list(result)\n", - "\n", - " def _decompose_step(self, high_level_plan: List[str], target_granularity: str, verbose: bool = False) -> List[str]:\n", - " prompt = PromptTemplate.from_template(\n", - " \"Today's High Level Plan: {high_level_plan}\"\n", - " + '\\nBelow is a detailed plan for the whole day broken into {target_granularity}'\n", - " + \"-long chunks:\"\n", - " + \"\\n1. \"\n", - " )\n", - " decomposing_planner = LLMChain(llm=self.llm, prompt=prompt, verbose=verbose)\n", - " high_level_plan_str = \" \".join(high_level_plan)\n", - " result = decomposing_planner.run(\n", - " high_level_plan=high_level_plan_str,\n", - " target_granularity=target_granularity,\n", - " )\n", - " return self._parse_list(result)\n", - "\n", - " def _decompose_plan(\n", - " self,\n", - " high_level_plan: List[str],\n", - " granularities: List[str], # hour, 5-15 minute\n", - " verbose: bool = False\n", - " ) -> List[str]:\n", - " result = high_level_plan\n", - " for granularity in granularities:\n", - " # TODO: We could recurse on each step but then there may end up being\n", - " # a need to rectify between windows\n", - " result = self._decompose_step(result, granularity, verbose=verbose)\n", - " result = [task for task in result if task.strip()]\n", - " return result\n", - "\n", - " def generate_full_plan(self, verbose: bool = False) -> List[str]:\n", - " coarse_plan = self._create_coarse_plan()\n", - " today = datetime.now()\n", - " # Save to memory stream\n", - " self.add_memory(f\"{self.name}'s initial plan for {today.strftime('%A %B %d')}: {' '.join(coarse_plan)}\")\n", - " full_plan = self._decompose_plan(\n", - " coarse_plan, \n", - " [\"hour\", \"5-15 minute\"],\n", - " verbose=verbose,\n", - " )\n", - " # Save to memory stream\n", - " # Unsure if this is done\n", - " self.add_memory(f\"{self.name}'s full plan for {today.strftime('%A %B %d')}: {' '.join(full_plan)}\")\n", - " return full_plan\n", " \n", - " def create_daily_plan(self, verbose: bool = False) -> List[str]:\n", - " full_plan = self.generate_full_plan(verbose=verbose)\n", - " self.current_plan = full_plan\n", - " return full_plan\n", - " \n", - " def update_todays_plan(self, observation: str, reaction: str, verbose: bool = False) -> List[str]:\n", - " \"\"\"When the agent makes a reaction to an observation, update their daily plan if needed.\"\"\"\n", - " if self.current_plan is None:\n", - " return self.create_daily_plan(verbose=verbose)\n", - " full_plan = self.current_plan\n", - " prompt = PromptTemplate.from_template(\n", - " \"{agent_summary_description}\"\n", - " +\"\\nIt is {current_time}.\"\n", - " +\"\\n{name} observed {observation} and had the following reaction: {reaction}.\"\n", - " +\"\\n{name}'s original plan for the rest of the day:\\n\"\n", - " +\"{original_plan}\"\n", - " +\"\\nIf this reaction influences the plan, respond with the updated plan at a 5-15 minute granularity. If not, return the original plan unchanged.\\n\"\n", - " +\"(Possibly) Updated Plan:\\n\\n\"\n", - " )\n", - " chain = LLMChain(llm=self.llm, prompt=prompt, verbose=verbose)\n", - " current_time_str = datetime.now().strftime(\"%B %d, %Y, %I:%M %p\")\n", - " already_completed = []\n", - " original_plan = []\n", - " for item in full_plan:\n", - " split_item = item.split(' - ')\n", - " time_format = '%I:%M%p'\n", - " try:\n", - " time_obj = datetime.strptime(split_item[0], time_format)\n", - " except:\n", - " original_plan.append(item) # TODO: better handle errors\n", - " if time_obj.time() > datetime.now().time():\n", - " original_plan.append(item)\n", - " else:\n", - " already_completed.append(item)\n", - " current_plan_str = \"\\n\".join([f\"{plan}\" for plan in original_plan])\n", - " result = chain.run(\n", - " agent_summary_description=self.get_summary(), \n", - " current_time = current_time_str,\n", - " name=self.name,\n", - " observation=observation,\n", - " reaction=reaction,\n", - " original_plan=current_plan_str)\n", - " new_plan = self._parse_list(result)\n", - " return already_completed + new_plan\n" + " def generate_reaction(self, observation: str) -> Tuple[bool, str]:\n", + " \"\"\"React to a given observation.\"\"\"\n", + " call_to_action_template = (\n", + " \"Should {agent_name} react to the observation, and if so,\"\n", + " +\" what would be an appropriate reaction? Respond in one line.\"\n", + " +' If the action is to engage in dialogue, write:\\nSAY: \"what to say\"'\n", + " +\"\\notherwise, write:\\nREACT: {agent_name}'s reaction (if anything).\"\n", + " + \"\\nEither do nothing, react, or say something but not both.\\n\\n\"\n", + " )\n", + " full_result = self._generate_reaction(observation, call_to_action_template)\n", + " result = full_result.strip().split('\\n')[0]\n", + " self.add_memory(f\"{self.name} observed {observation} and reacted by {result}\")\n", + " if \"REACT:\" in result:\n", + " reaction = result.split(\"REACT:\")[-1].strip()\n", + " return False, reaction\n", + " if \"SAY:\" in result:\n", + " return True, result.split(\"SAY:\")[-1].strip()\n", + " else:\n", + " return False, result\n", + "\n", + " def generate_dialogue_response(self, observation: str) -> Tuple[bool, str]:\n", + " \"\"\"React to a given observation.\"\"\"\n", + " call_to_action_template = (\n", + " 'What would {agent_name} say? To end the conversation, write: GOODBYE: \"what to say\". Otherwise to continue the conversation, write: SAY: \"what to say next\"\\n\\n'\n", + " )\n", + " full_result = self._generate_reaction(observation, call_to_action_template)\n", + " result = full_result.strip().split('\\n')[0]\n", + " if \"GOODBYE:\" in result:\n", + " farewell = result.split(\"GOODBYE:\")[-1].strip()\n", + " self.add_memory(f\"{self.name} observed {observation} and said {farewell}\")\n", + " return False, farewell\n", + " if \"SAY:\" in result:\n", + " response_text = result.split(\"SAY:\")[-1].strip()\n", + " self.add_memory(f\"{self.name} observed {observation} and said {response_text}\")\n", + " return True, response_text\n", + " else:\n", + " return False, result" ] }, { "cell_type": "markdown", - "id": "737c5223-889f-4799-a01b-1f4d50593d95", + "id": "361bd49e", "metadata": {}, "source": [ - "## Functions for interactions\n", + "## Memory Lifecycle\n", "\n", - "Characters are meant for interactions and actions. Let's define a few functions to parse responses to observations that can be connected to dialogue flows or virtual worlds." + "Summarizing the above key methods: `add_memory` and `summarize_related_memories`.\n", + "\n", + "When an agent makes an observation, it stores the memory:\n", + " \n", + "1. Language model scores the memory's importance (1 for mundane, 10 for poignant)\n", + "2. Observation and importance are stored within a document by TimeWeightedVectorStoreRetriever, with a `last_accessed_time`.\n", + "\n", + "When an agent responds to an observation:\n", + "\n", + "1. Generates query(s) for retriever, which fetches documents based on salience, recency, and importance.\n", + "2. Summarizes the retrieved information\n", + "3. Updates the `last_accessed_time` for the used documents.\n" + ] + }, + { + "cell_type": "markdown", + "id": "2fa3ca02", + "metadata": {}, + "source": [ + "## Create a Generative Character\n", + "\n", + "Now that we've walked through the definition, we will create two characters named \"Tommie\" and \"Eve\"." ] }, { "cell_type": "code", "execution_count": 5, - "id": "10834185-76b1-4d1d-a84c-edb07a31cb52", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def generate_reaction(agent, observation) -> Tuple[bool, str]:\n", - " call_to_action_template = (\n", - " \"Should {agent_name} react to the observation, and if so,\"\n", - " +\" what would be an appropriate reaction? Respond in one line.\"\n", - " +' If the action is to engage in dialogue, write:\\nSAY: \"what to say\"'\n", - " +\"\\notherwise, write:\\nREACT: {agent_name}'s reaction (if anything).\\nEither do nothing, react, or say something but not both.\\n\\n\"\n", - " )\n", - " full_result = agent._generate_reaction(observation, call_to_action_template)\n", - " result = full_result.strip().split('\\n')[0]\n", - " agent.add_memory(f\"{agent.name} observed {observation} and reacted by {result}\")\n", - " if \"REACT:\" in result:\n", - " reaction = result.split(\"REACT:\")[-1].strip()\n", - " return False, reaction\n", - " if \"SAY:\" in result:\n", - " return True, result.split(\"SAY:\")[-1].strip()\n", - " else:\n", - " return False, result\n", - "\n", - "def generate_dialogue_response(agent, observation: str):\n", - " call_to_action_template = (\n", - " 'What would {agent_name} say? To end the conversation, write: GOODBYE: \"what to say\". Otherwise to continue the conversation, write: SAY: \"what to say next\"\\n\\n'\n", - " )\n", - " full_result = agent._generate_reaction(observation, call_to_action_template)\n", - " result = full_result.strip().split('\\n')[0]\n", - " if \"GOODBYE:\" in result:\n", - " farewell = result.split(\"GOODBYE:\")[-1].strip()\n", - " agent.add_memory(f\"{agent.name} observed {observation} and said {farewell}\")\n", - " return False, farewell\n", - " if \"SAY:\" in result:\n", - " response_text = result.split(\"SAY:\")[-1].strip()\n", - " agent.add_memory(f\"{agent.name} observed {observation} and said {response_text}\")\n", - " return True, response_text\n", - " else:\n", - " return False, result\n", - " \n", - "def interview_agent(agent, message: str):\n", - " new_message = f\"Person A says {message}\"\n", - " return generate_dialogue_response(agent, new_message)[1]" - ] - }, - { - "cell_type": "markdown", - "id": "fcb84dd8-ea8f-4d9b-864a-4677a0347f49", - "metadata": {}, - "source": [ - "## Create a Character\n", - "\n", - "For this example, we will create two characters named \"Tommie\" and \"Eve\"." - ] - }, - { - "cell_type": "code", - "execution_count": 6, "id": "608c0272", "metadata": { "tags": [] @@ -526,6 +419,12 @@ "outputs": [], "source": [ "import faiss\n", + "\n", + "def interview_agent(agent: GenerativeAgent, message: str) -> str:\n", + " \"\"\"Help the notebook user interact with the agent.\"\"\"\n", + " new_message = f\"{USER_NAME} says {message}\"\n", + " return agent.generate_dialogue_response(new_message)[1]\n", + "\n", "def create_new_memory_retriever():\n", " \"\"\"Create a new vector store retriever unique to the agent.\"\"\"\n", " # Define your embedding model\n", @@ -539,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "7884f9dd-c597-4c27-8c77-1402c71bc2f8", "metadata": { "tags": [] @@ -561,7 +460,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "c524d529", "metadata": { "tags": [] @@ -573,7 +472,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "It is not possible to provide a summary without any statements or information about Tommie's characteristics. Please provide additional context.\n" + "Unfortunately, there are no statements provided to summarize Tommie's core characteristics.\n" ] } ], @@ -585,7 +484,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "4be60979-d56e-4abf-a636-b34ffa8b7fba", "metadata": { "tags": [] @@ -608,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "6992b48b-697f-4973-9560-142ef85357d7", "metadata": { "tags": [] @@ -620,7 +519,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie has memories of his childhood dog, observes his new home and noisy surroundings, notices his new neighbors have a cat, tries to rest while feeling tired from driving, and feels hungry.\n" + "Tommie is a person who is currently on a road trip and experiencing various sensory stimuli such as noise from the road at night, memories of his childhood dog, observing a new home and neighbors with a cat. He is also experiencing physical sensations such as fatigue from driving and hunger. Tommie attempts to rest to alleviate his tiredness and hunger.\n" ] } ], @@ -643,7 +542,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "54024d41-6e83-4914-91e5-73140e2dd9c8", "metadata": { "tags": [] @@ -652,10 +551,10 @@ { "data": { "text/plain": [ - "'\"I really enjoy design. It\\'s always been a passion of mine.\"'" + "'\"I really enjoy design. I find it calming and a way to express my creativity. But right now, I\\'m mostly focused on finding a job to support myself. How about you, Person A? What do you like to do?\"'" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -666,7 +565,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "71e2e8cc-921e-4816-82f1-66962b2c1055", "metadata": { "tags": [] @@ -675,10 +574,10 @@ { "data": { "text/plain": [ - "'\"Well, I\\'m actually looking for a job right now. I\\'m hoping to find something in the design field.\"'" + "'\"Well, since it\\'s already late at night, I\\'m mostly looking forward to getting some rest and starting fresh in the morning. How about you, Person A? What are you looking forward to doing tomorrow?\"'" ] }, - "execution_count": 12, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -689,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "a2521ffc-7050-4ac3-9a18-4cccfc798c31", "metadata": { "tags": [] @@ -698,10 +597,10 @@ { "data": { "text/plain": [ - "'\"Honestly, my biggest worry right now is finding a job in my field. It\\'s been a bit of a struggle, but I\\'m staying hopeful. How about you?\"'" + "'\"Honestly, I\\'ve been feeling pretty anxious lately about finding a job and making ends meet. But I\\'m trying to stay positive and keep pushing forward. How about you, Person A? What worries you?\"'" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -710,61 +609,6 @@ "interview_agent(tommie, \"What are you most worried about today?\")" ] }, - { - "cell_type": "markdown", - "id": "936c3d46-9324-48df-a5c3-9e37fb02eb6d", - "metadata": {}, - "source": [ - "## Create a plan for today" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "0b48b7eb-ac0e-452a-93f6-9655f8da9729", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "['6:00am - Wake up, get dressed, and head out for a 30-minute walk to explore the new town and get some fresh air.',\n", - " '6:30am - Return home and take a few minutes to stretch and cool down.',\n", - " '6:45am - Shower and get dressed for the day.',\n", - " '7:00am - Have breakfast while browsing job openings and saving any relevant ones.',\n", - " '7:30am - Start researching companies and their values to find potential matches for job openings.',\n", - " '8:00am - Reach out to any connections in the area to see if they know of any job opportunities or can provide any advice.',\n", - " '8:30am - Check for any upcoming networking events or job fairs in the area and add them to the calendar if applicable.',\n", - " '9:00am - Attend any networking events or job fairs in the area, if there are any, and make connections with potential employers or colleagues.',\n", - " '10:00am - Begin working on creating a portfolio of design work to showcase to potential employers.',\n", - " '10:15am - Gather any past design work and organize it by project or category.',\n", - " '10:45am - Start selecting the best pieces and editing them to fit the portfolio.',\n", - " '11:30am - Research design portfolio best practices and incorporate them into the portfolio design.',\n", - " '12:00pm - Take a break for lunch and practice self-care, such as taking a short walk or doing some light stretching.',\n", - " '12:30pm - Return to work on the portfolio, focusing on creating a cohesive and visually appealing presentation.',\n", - " '1:30pm - Take a break to rest and recharge.',\n", - " '2:00pm - Continue working on the portfolio, adding any finishing touches and ensuring it is up to date.',\n", - " '3:00pm - Take a break to manage anxiety and practice self-care, such as meditation or deep breathing exercises.',\n", - " '3:30pm - Review the progress made so far and adjust the plan for the rest of the day if necessary.',\n", - " '4:00pm - Set specific goals and tasks for the next day, such as following up with any networking connections or submitting job applications.',\n", - " '4:30pm - Finish up any remaining tasks for the day, such as sending out emails or making phone calls.',\n", - " '5:00pm - Take a break to unwind before dinner, such as reading a book or engaging in a hobby.',\n", - " '6:00pm - Have dinner and spend some time relaxing or engaging in a hobby, such as painting or listening to music.',\n", - " '7:30pm - Wind down for the evening with some light reading or meditation.',\n", - " '8:00pm - Get ready for bed, such as taking a hot shower or doing some light stretches.',\n", - " \"9:00pm - Aim to get a good night's sleep for the next day by turning off electronics and getting into bed.\"]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tommie.create_daily_plan()" - ] - }, { "cell_type": "markdown", "id": "e509c468-f7cd-4d72-9f3a-f4aba28b1eea", @@ -775,7 +619,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "154dee3d-bfe0-4828-b963-ed7e885799b3", "metadata": { "tags": [] @@ -825,7 +669,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "238be49c-edb3-4e26-a2b6-98777ba8de86", "metadata": { "tags": [] @@ -835,69 +679,56 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie groans and covers his head with a pillow to try to block out the noise.\n", - "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie makes himself some coffee.\n", - "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie sighs in frustration and continues searching through the boxes.\n", - "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie takes a sip of his coffee and feels a sense of relief.\n", - "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie grimaces and makes a mental note to buy a better brand of coffee next time.\n", - "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie feels disappointed but tries to stay positive and continues with his planned activities for the day.\n", - "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie nods to himself, satisfied with his progress.\n", - "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie feels a sense of excitement and anticipation as he sets out to explore the city and find job openings.\n", - "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m Tommie's eyes light up with hope and he makes a mental note to attend the job fair.\n", - "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie sighs and takes out his phone to pass the time while waiting in line.\n", - "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie feels discouraged but reminds himself to keep trying and not give up.\n", - "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie's shoulders slump and he lets out a defeated sigh as he heads back home.\n", - "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m Tommie enters the diner and looks at the menu with a grumbling stomach.\n", + "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie covers his head with a pillow to block out the noise.\n", + "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie starts brewing his coffee and enjoys the smell.\n", + "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie sighs in frustration and continues to search for the filters.\n", + "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie takes a sip of his coffee and feels relieved.\n", + "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie grimaces at the bitter taste of the coffee and makes a mental note to buy a better brand next time.\n", + "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie feels disappointed and anxious.\n", + "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie feels determined to continue job searching and improving his resume and cover letter.\n", + "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie feels excited to explore the city and hopeful about finding job openings.\n", + "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m \"That job fair looks promising. I'll definitely check it out.\"\n", + "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie feels impatient and frustrated by the long wait in line.\n", + "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie feels disappointed but determined to keep looking for job opportunities.\n", + "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie feels discouraged but still determined to keep searching for job opportunities.\n", + "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m \"Hi, can I get a menu please?\"\n", + "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie sighs in frustration and looks around for something to occupy his time while he waits.\n", + "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m \"Excuse me, I couldn't help but overhear about the job opening. Could you tell me more about it?\"\n", + "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m \"Thank you for the information. Do you happen to have any contact information for the company or know where I can apply?\"\n", "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", - "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie sighs and checks his phone to pass the time while waiting for his food.\n", - "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m \"Excuse me, I couldn't help but overhear about the job opening. Do you happen to have any more information about it?\"\n", - "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m \"Can you tell me more about the job opening? I'm actively searching for opportunities in the design field.\"\n", - "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m \"Thank you for the information. I will definitely apply for the job and keep my fingers crossed.\"\n", - "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie feels a sense of accomplishment and hope as he takes action towards finding a job.\n", - "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie takes a deep breath and enjoys the fresh air and nature around him, feeling momentarily at peace.\n", - "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie smiles and enjoys the moment of interaction with the dog.\n", + "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m \"Thank you for the information. Do you happen to have any contact information for the company or know where I can apply?\"\n", + "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie feels hopeful but also anxious about the possibility of not hearing back from any of the businesses.\n", + "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie feels a sense of calm and relaxation as he takes a break from his job search to enjoy nature.\n", + "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie feels a brief moment of happiness and connection with the dog before continuing on with his day.\n", "****************************************\n", "\u001b[34mAfter 20 observations, Tommie's summary is:\n", "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a determined individual who is actively searching for a job in the design field. Despite experiencing both excitement and disappointment in their job search, they remain hopeful and focused on achieving their goal. Tommie is also deeply attached to their dog, Bruno, and memories of their childhood together hold a special place in their heart. They actively network with potential employers and take action towards finding job opportunities. Despite setbacks, Tommie remains resilient and takes breaks to recharge and find moments of peace.\u001b[0m\n", + "Tommie is a determined and persistent job seeker who experiences a range of emotions, including disappointment, anxiety, determination, and excitement. He is proactive in his search and seeks out opportunities to explore the city and meet potential employers. Despite facing setbacks and challenges, he remains hopeful and continues to update his resume and cover letter.\u001b[0m\n", "****************************************\n", - "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m Tommie watches the group playing frisbee but decides not to join in as they are strangers.\n", - "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie rubs his nose and winces in pain before taking a break from the frisbee game.\n", - "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie lays down on the couch and closes their eyes, taking a deep breath to relax.\n", - "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie sighs and grabs a broom to clean up the mess.\n", - "\u001b[32mTommie takes a nap but has trouble sleeping because of the noisy construction site outside his window.\u001b[0m Tommie tosses and turns in frustration, unable to sleep due to the noise outside.\n", - "\u001b[32mTommie wakes up feeling even more tired than before.\u001b[0m Tommie groans and rubs their eyes, feeling frustrated about not getting enough rest.\n", - "\u001b[32mTommie decides to watch some TV to relax.\u001b[0m Tommie turns on the TV and settles into the couch, feeling grateful for the distraction and chance to unwind.\n", - "\u001b[32mThe show he's watching is a repeat, and he gets bored after a few minutes.\u001b[0m Tommie switches the channel to find something more engaging.\n", - "\u001b[32mTommie sees a commercial for a new energy drink and decides to try it.\u001b[0m Tommie takes note of the energy drink but decides not to try it, as they are wary of the potential side effects.\n", - "\u001b[32mThe energy drink tastes terrible, and Tommie regrets buying it.\u001b[0m Tommie throws away the energy drink and makes a mental note to avoid trying new products impulsively.\n", - "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie takes a deep breath and reminds themselves of their determination and resilience in their job search.\n", - "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m \"Hey, just wanted to talk to you about my job search struggles and get some support.\"\n", - "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m \"Thank you for the support, it means a lot to me.\"\n", - "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m \"Thank you for your kind words. It really helps to have your support.\"\n", - "\u001b[32mTommie decides to go for a jog to clear his mind.\u001b[0m Tommie puts on his running shoes and heads out for a jog to clear his mind.\n", - "\u001b[32mTommie jogs through the city and sees some interesting sights.\u001b[0m Tommie enjoys the sights and feels energized by the jog.\n", - "\u001b[32mTommie stops to take a picture of a street mural.\u001b[0m Tommie smiles and admires the street mural before continuing their jog.\n", - "\u001b[32mTommie runs into an old friend from college who now lives in the city.\u001b[0m \"Hey, it's great to see you! How have you been?\"\n", - "\u001b[32mThey catch up for a few minutes, but Tommie's friend has to leave to attend a meeting.\u001b[0m \"It was great running into you! Let's catch up again soon.\"\n", - "\u001b[32mTommie thanks his friend and feels hopeful again.\u001b[0m \"Thanks for the reminder that there are still good things happening in my life.\"\n", - "****************************************\n", - "\u001b[34mAfter 40 observations, Tommie's summary is:\n", - "Name: Tommie (age: 25)\n", - "Innate traits: anxious, likes design\n", - "Tommie is a determined and hopeful individual who holds a special place in their heart for their dog, Bruno. They are actively searching for a job in the design field and experiencing both excitement and disappointment in their job search. Despite facing challenges, Tommie remains determined to find a job and actively networks with potential employers and connections. They react positively to encouragement and take action towards finding a job. However, Tommie also experiences moments of disappointment and defeat.\u001b[0m\n", - "****************************************\n", - "\u001b[32mTommie heads back to his apartment to rest and prepare for his upcoming interviews.\u001b[0m Tommie takes a deep breath and mentally prepares for his upcoming interviews.\n", - "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", - "\u001b[32mTommie spends the evening rehearsing his interview pitch.\u001b[0m Tommie nods their head in determination and continues to rehearse their interview pitch.\n" + "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m \"Hi, can I play with you guys?\"\n", + "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie winces in pain and holds his nose, but continues to play through the discomfort.\n", + "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie sighs and takes a deep breath, feeling tired from the day's events.\n", + "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie cleans up the garbage and secures the trash bag to prevent future incidents.\n", + "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie takes a deep breath and reminds himself to stay positive and persistent in his job search.\n", + "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m \"Hey, thanks for listening. It feels good to talk about it and get some support.\"\n", + "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m \"Thanks for the encouragement, I really appreciate it.\"\n", + "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m Tommie nods and smiles, feeling grateful for his friend's support.\n", + "\u001b[32mTommie decides to go for a jog to clear his mind.\u001b[0m Tommie puts on his running shoes and heads out the door.\n", + "\u001b[32mTommie jogs through the city and sees some interesting sights.\u001b[0m Tommie feels a sense of wonder and appreciation for the beauty of the city.\n", + "\u001b[32mTommie stops to take a picture of a street mural.\u001b[0m Tommie feels inspired and appreciative of the creativity and beauty of the street mural.\n", + "\u001b[32mTommie runs into an old friend from college who now lives in the city.\u001b[0m \"Hey! It's great to see you! What have you been up to?\"\n", + "\u001b[32mThey catch up for a few minutes, but Tommie's friend has to leave to attend a meeting.\u001b[0m \"It was great seeing you, let's catch up again soon!\"\n", + "\u001b[32mTommie thanks his friend and feels hopeful again.\u001b[0m Tommie nods and smiles, feeling grateful for his friend's support.\n", + "\u001b[32mTommie heads back to his apartment to rest and prepare for his upcoming interviews.\u001b[0m Tommie takes a deep breath and feels a sense of relief knowing that he has upcoming interviews.\n", + "\u001b[32mTommie spends the evening rehearsing his interview pitch.\u001b[0m Tommie feels focused and determined to do well in his upcoming interviews.\n" ] } ], "source": [ "# Let's send Tommie on their way. We'll check in on their summary every few observations to watch it evolve\n", "for i, observation in enumerate(observations):\n", - " _, reaction = generate_reaction(tommie, observation)\n", + " _, reaction = tommie.generate_reaction(observation)\n", " print(colored(observation, \"green\"), reaction)\n", " if ((i+1) % 20) == 0:\n", " print('*'*40)\n", @@ -915,7 +746,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "id": "6336ab5d-3074-4831-951f-c9e2cba5dfb5", "metadata": { "tags": [] @@ -924,10 +755,10 @@ { "data": { "text/plain": [ - "'\"Hey, it\\'s been a bit of a mixed day, but overall it\\'s been okay. I went for a jog and saw some cool sights, which was nice. How about you?\"'" + "'\"Well, it\\'s been a bit of a rollercoaster, to be honest. I\\'ve been job searching all day and it\\'s been a mix of excitement, disappointment, and anxiety. But I\\'m trying to stay positive and keep pushing forward.\"'" ] }, - "execution_count": 17, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -938,7 +769,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "id": "809ac906-69b7-4326-99ec-af638d32bb20", "metadata": { "tags": [] @@ -947,10 +778,10 @@ { "data": { "text/plain": [ - "'\"I actually don\\'t drink coffee, but I love the smell of it. How about you?\"'" + "'\"I actually really like coffee, it helps me stay focused during my job search. How about you?\"'" ] }, - "execution_count": 18, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -961,7 +792,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "f733a431-19ea-421a-9101-ae2593a8c626", "metadata": { "tags": [] @@ -970,10 +801,10 @@ { "data": { "text/plain": [ - "'\"I actually don\\'t drink coffee, but I love the smell of it. How about you?\"'" + "'Tommie would say: \"I actually really like coffee, it helps me stay focused during my job search. How about you?\" '" ] }, - "execution_count": 19, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -994,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "id": "ec8bbe18-a021-419c-bf1f-23d34732cd99", "metadata": { "tags": [] @@ -1016,7 +847,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "id": "1e2745f5-e0da-4abd-98b4-830802ce6698", "metadata": { "tags": [] @@ -1039,7 +870,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "id": "de4726e3-4bb1-47da-8fd9-f317a036fe0f", "metadata": { "tags": [] @@ -1051,7 +882,7 @@ "text": [ "Name: Eve (age: 34)\n", "Innate traits: curious, helpful\n", - "Eve is a helpful and active person who is attentive to the people around her and enjoys sports.\n" + "Eve is attentive to her colleagues, enjoys physical activity, helpful to coworkers, responsible in waking up to her alarm, and eats breakfast.\n" ] } ], @@ -1072,7 +903,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "id": "6cda916d-800c-47bc-a7f9-6a2f19187472", "metadata": { "tags": [] @@ -1081,10 +912,10 @@ { "data": { "text/plain": [ - "'\"I\\'m feeling pretty good so far, thanks for asking! How about you, Person A?\"'" + "'\"I\\'m feeling curious about what we have planned for today. How about you?\"'" ] }, - "execution_count": 23, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1095,7 +926,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "id": "448ae644-0a66-4eb2-a03a-319f36948b37", "metadata": { "tags": [] @@ -1104,10 +935,10 @@ { "data": { "text/plain": [ - "'\"I don\\'t know much about Tommie, but I overheard someone saying he\\'s hard to work with. Have you had any experiences working with him?\"'" + "'\"I overheard someone mention that Tommie is hard to work with, but I don\\'t know much else about them. Why do you ask?\"'" ] }, - "execution_count": 24, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1118,7 +949,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "id": "493fc5b8-8730-4ef8-9820-0f1769ce1691", "metadata": { "tags": [] @@ -1127,10 +958,10 @@ { "data": { "text/plain": [ - "'\"That\\'s interesting to hear. What kind of job is Tommie looking for?\"'" + "'\"That\\'s interesting, I didn\\'t know Tommie was looking for a job. What kind of job is he looking for? Maybe I can keep an eye out for any openings that might be a good fit for him.\"'" ] }, - "execution_count": 25, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1141,7 +972,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "id": "4b46452a-6c54-4db2-9d87-18597f70fec8", "metadata": { "tags": [] @@ -1150,10 +981,10 @@ { "data": { "text/plain": [ - "'\"Sure, I\\'d be happy to ask him questions and learn more about his job search. What kind of experience or skills is he looking to bring to a job?\"'" + "'\"Sure, I\\'d be happy to talk to him and see if I can help in any way. Do you have any specific questions you\\'d like me to ask him?\"'" ] }, - "execution_count": 26, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1174,21 +1005,22 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "id": "042ea271-4bf1-4247-9082-239a6fea43b8", "metadata": { "tags": [] }, "outputs": [], "source": [ - "def run_conversation(agents, initial_observation: str, max_turns:int = 25, reflection_frequency: Optional[int] = 5):\n", - " _, observation = generate_reaction(agents[1], initial_observation)\n", + "def run_conversation(agents: List[GenerativeAgent], initial_observation: str, max_turns:int = 25) -> None:\n", + " \"\"\"Runs a conversation between agents.\"\"\"\n", + " _, observation = agents[1].generate_reaction(initial_observation)\n", " print(f\"{agents[1].name}: {observation}\")\n", " turns = 0\n", " while True:\n", " break_dialogue = False\n", " for agent in agents:\n", - " stay_in_dialogue, reaction = generate_dialogue_response(agent, observation)\n", + " stay_in_dialogue, reaction = agent.generate_dialogue_response(observation)\n", " print(f\"{agent.name}: {reaction}\")\n", " observation = f\"{agent.name} said {reaction}\"\n", " if not stay_in_dialogue:\n", @@ -1200,7 +1032,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "id": "d5462b14-218e-4d85-b035-df57ea8e0f80", "metadata": { "tags": [] @@ -1210,19 +1042,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "Eve: \"Sure, I'd be happy to share my story and offer any advice that might be helpful.\"\n", - "Tommie: \"Thank you for giving me the chance to share. It means a lot to me to have someone to talk to about my job search.\"\n", - "Eve: \"Of course, Tommie. I'm glad that I could be here to listen and offer any help that I can. Can you tell me more about the type of job you're looking for?\"\n", - "Tommie: \"Thank you, Eve. I'm really interested in finding a job in the design field. Specifically, I'm looking for opportunities in graphic design or web design. I have experience with both and I'm excited about the creative possibilities in these fields.\"\n", - "Eve: \"That's great, Tommie! It sounds like you have a lot of valuable skills to offer in the design field. Have you been actively searching for job opportunities in those areas?\"\n", - "Tommie: \"Yes, I have been actively searching and applying for jobs in those areas. It's been a bit of a challenge, but I'm staying hopeful and determined. Thank you for your support, Eve.\"\n", - "Eve: \"That's great to hear, Tommie. I'm glad you're staying positive and determined in your job search. I'll keep my eyes open for any opportunities that might be a good fit for you. Is there anything else I can do to help in the meantime?\"\n", - "Tommie: \"Thank you so much, Eve. Your support means a lot to me. If you come across any job opportunities or connections, please let me know. I'll continue to keep you updated on my job search progress.\"\n", - "Eve: \"I'll definitely keep you in mind, Tommie. And please do keep me updated on your progress. I'm rooting for you! Is there anything specific you're looking for in a job or company culture?\"\n", - "Tommie: \"Thank you, Eve. In terms of company culture, I'm looking for a place that values creativity and collaboration. I enjoy working in a team environment and bouncing ideas off of others. I'm also interested in a company that values work-life balance and offers opportunities for growth and learning. Thank you again for your support and for keeping me in mind for any opportunities.\"\n", - "Eve: \"Those are all great qualities to look for in a company, Tommie. I'll definitely keep those in mind as I come across job opportunities. And please do keep me updated on your progress. I'm here to support you in your job search. Good luck!\"\n", - "Tommie: \"Thank you so much, Eve. I really appreciate your support and willingness to help. I'll definitely keep you updated on my progress and any new opportunities I come across. Thanks again, and have a great day!\"\n", - "Eve: \"You're welcome, Tommie. I'm happy to help in any way I can. Good luck with your job search and keep me updated. Have a great day!\"\n" + "Eve: \"Sure, I'd love to share my story with you and offer any advice I can. Where would you like me to start?\"\n", + "Tommie: \"I've had some ups and downs, but overall I'm feeling hopeful about my job search. I've been updating my resume and cover letter, and I have a few upcoming interviews that I'm excited about. How about you, how has your day been going?\"\n", + "Eve: \"That's great to hear, Tommie. I'm glad you're feeling hopeful and have some upcoming interviews. Is there anything specific you're looking for in a job? Maybe I can keep an eye out for any opportunities that might be a good fit for you.\"\n", + "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", + "Tommie: \"Thank you so much, Eve! I really appreciate your offer to keep an eye out for job opportunities. Right now, I'm looking for a job in the design field, preferably in a creative agency or startup. But I'm open to exploring different options as well.\"\n", + "Eve: \"That's great to know, Tommie. I'll definitely keep an eye out for any opportunities in the design field, whether it's in a creative agency or startup. And if I come across anything that might be a good fit, I'll let you know right away. Good luck with your upcoming interviews and let me know if there's anything else I can do to help!\"\n", + "Tommie: \"Thank you so much, Eve! I really appreciate your willingness to help me find job opportunities. Have a great day!\"\n", + "Eve: \"You're welcome, Tommie. It was great talking with you and I wish you the best of luck in your job search. Have a great day!\"\n" ] } ], @@ -1245,7 +1072,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 27, "id": "c4d252f3-fcc1-474c-846e-a7605a6b4ce7", "metadata": { "tags": [] @@ -1257,16 +1084,32 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a determined and hopeful job seeker in the design field who values the support of friends and loved ones. They experience a mix of excitement and disappointment in their job search, but remain persistent and take breaks to find peace in nature. Tommie also holds their childhood memories close, especially those involving their beloved dog, Bruno.\n", - "Name: Eve (age: 34)\n", - "Innate traits: curious, helpful\n", - "Eve is a supportive and helpful person who is willing to listen and offer assistance to those in need. She is empathetic and asks thoughtful questions to better understand the needs of others. She is also interested in learning about and supporting career growth and development. Additionally, she is friendly and approachable in social situations.\n" + "Tommie is a determined and persistent individual who seeks support from friends during his job search. He finds inspiration in the creativity and beauty around him, and experiences a range of emotions including disappointment, anxiety, determination, and excitement. He copes with setbacks by remaining hopeful and proactive in his search, exploring the city and seeking out potential employers. He values the support and understanding of his friends throughout the process.\n" ] } ], "source": [ "# We can see how the agents have \n", - "print(tommie.get_summary(force_refresh=True))\n", + "print(tommie.get_summary(force_refresh=True))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "c04db9a4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Name: Eve (age: 34)\n", + "Innate traits: curious, helpful\n", + "Eve is a helpful and attentive person who is willing to offer assistance and keep an eye out for job opportunities. She is curious and interested in others' experiences and is a team player, willing to assist her colleagues with their tasks. She is also a tennis player and enjoys a bowl of porridge for breakfast. However, she is not immune to workplace gossip and occasionally overhears negative comments about others.\n" + ] + } + ], + "source": [ "\n", "# We can see a current \"Summary\" of a character based on their own perception of self\n", "print(eve.get_summary(force_refresh=True))" @@ -1274,7 +1117,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "id": "71762558-8fb6-44d7-8483-f5b47fb2a862", "metadata": { "tags": [] @@ -1283,10 +1126,10 @@ { "data": { "text/plain": [ - "'\"It was really helpful, actually. Eve offered to keep an eye out for any job opportunities and she asked about the type of job and company culture I\\'m looking for. It\\'s nice to have someone in my corner rooting for me. Thanks for asking, Person A.\"'" + "'\"It was really helpful actually. Eve offered to keep an eye out for any job opportunities in the design field, which is exactly what I\\'m looking for. It\\'s great to have supportive friends like her.\"'" ] }, - "execution_count": 30, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1297,7 +1140,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 30, "id": "085af3d8-ac21-41ea-8f8b-055c56976a67", "metadata": { "tags": [] @@ -1306,10 +1149,10 @@ { "data": { "text/plain": [ - "'\"It was really nice to talk to Tommie and learn more about his job search. He\\'s looking for opportunities in graphic design or web design, and I promised to keep him in mind for any job opportunities that come my way. He\\'s a really talented and motivated individual, and I\\'m excited to see where his career takes him.\"'" + "'\"It was really nice! Tommie seems like a great person and I\\'m happy to help them with their job search. Is there anything else you wanted to know about our conversation?\"'" ] }, - "execution_count": 32, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1320,26 +1163,19 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 31, "id": "5b439f3c-7849-4432-a697-2bcc85b89dae", "metadata": { "tags": [] }, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34mCharacter Eve is reflecting\u001b[0m\n" - ] - }, { "data": { "text/plain": [ - "'\"I feel like I covered most of the things I wanted to ask and offer, but if there\\'s anything else you want to share or ask me, please don\\'t hesitate to reach out. I\\'m here to support you in any way I can. Good luck with your job search, Tommie!\"'" + "'\"I think our conversation went well, but if there was one thing I wish I had said to Tommie, it would be to ask if they have any specific companies or agencies in mind that they would love to work for. That way, I can keep an even closer eye out for any job opportunities that might be a perfect fit for them. But overall, I think we covered a lot of ground and I\\'m excited to help Tommie in any way I can.\"'" ] }, - "execution_count": 33, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" }