From 2a987adee5da91668d6b31c4a84ed9aeb363498a Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:07:38 -0400 Subject: [PATCH 01/10] update --- website/docs/Research.md | 11 + .../docs/tutorial/conversation-patterns.ipynb | 490 ++++++++++++++++++ 2 files changed, 501 insertions(+) diff --git a/website/docs/Research.md b/website/docs/Research.md index f63658d8eef0..3a78641e0fda 100644 --- a/website/docs/Research.md +++ b/website/docs/Research.md @@ -73,3 +73,14 @@ For technical details, please check our technical report and research publicatio primaryClass={cs.AI} } ``` + +* [StateFlow: Enhancing LLM Task-Solving through State-Driven Workflows]https://arxiv.org/abs/2403.11322. Yiran Wu, Tianwei Yue, Shaokun Zhang, Chi Wang, Qingyun Wu. ArXiv preprint arXiv:2403.11322 (2024). + +@misc{wu2024stateflow, + title={StateFlow: Enhancing LLM Task-Solving through State-Driven Workflows}, + author={Yiran Wu and Tianwei Yue and Shaokun Zhang and Chi Wang and Qingyun Wu}, + year={2024}, + eprint={2403.11322}, + archivePrefix={arXiv}, + primaryClass={cs.CL} +} diff --git a/website/docs/tutorial/conversation-patterns.ipynb b/website/docs/tutorial/conversation-patterns.ipynb index c3da6fda0580..450f188aede2 100644 --- a/website/docs/tutorial/conversation-patterns.ipynb +++ b/website/docs/tutorial/conversation-patterns.ipynb @@ -1529,6 +1529,496 @@ " `ConversableAgent`." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Customzing Speaker Selection\n", + "\n", + "In GroupChat, we can also customize the speaker selection by passing in a function to `speaker_selection_method`:\n", + "```python\n", + "def custom_speaker_selection_func(last_speaker, groupchat):\n", + " \"\"\"Define a customized speaker selection function.\n", + " A recommended way is to define a transition for each speaker in the groupchat.\n", + "\n", + " Parameters:\n", + " - last_speaker: Agent\n", + " The last speaker in the group chat.\n", + " - groupchat: GroupChat\n", + " The GroupChat object\n", + " Return:\n", + " Return one of the following:\n", + " 1. an `Agent` class, it must be one of the agents in the group chat.\n", + " 2. a string from ['auto', 'manual', 'random', 'round_robin'] to select a default method to use.\n", + " 3. None, which indicates the chat should be terminated.\n", + " \"\"\"\n", + " pass\n", + "\n", + "groupchat = autogen.GroupChat(\n", + " speaker_selection_method=custom_speaker_selection_func,\n", + " ...,\n", + ")\n", + "```\n", + "The last speaker and the groupchat object are passed to the function. \n", + "Commonly used variables from groupchat are `groupchat.messages` and `groupchat.agents`, which is the message history and the agents in the group chat respectively. You can access other attributes of the groupchat, such as `groupchat.allowed_speaker_transitions_dict` for pre-defined `allowed_speaker_transitions_dict`.\n", + "\n", + "Heres is a simple example to build workflow for reasearch with customized speaker selection.\n", + "\n", + "\n", + "```{=mdx}\n", + "![group_chat](../../blog/2024-02-29-StateFlow/img/sf_example_1.png)\n", + "```\n", + "\n", + "We define the following agents:\n", + "\n", + "- Initializer: Start the workflow by sending a task.\n", + "- Coder: Retrieve papers from the internet by writing code.\n", + "- Executor: Execute the code.\n", + "- Scientist: Read the papers and write a summary.\n", + "\n", + "In the Figure, we define a simple workflow for research with 4 states: Init, Retrieve, Reserach and End. Within each state, we will call different agents to perform the tasks.\n", + "\n", + "Init: We use the initializer to start the workflow.\n", + "Retrieve: We will first call the coder to write code and then call the executor to execute the code.\n", + "Research: We will call the scientist to read the papers and write a summary.\n", + "End: We will end the workflow." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import autogen\n", + "\n", + "config_list = autogen.config_list_from_json(\n", + " \"OAI_CONFIG_LIST\",\n", + " filter_dict={\n", + " \"model\": [\"gpt-4-1106-preview\"],\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gpt4_config = {\n", + " \"cache_seed\": 42, # change the cache_seed for different trials\n", + " \"temperature\": 0,\n", + " \"config_list\": config_list,\n", + " \"timeout\": 120,\n", + "}\n", + "\n", + "initializer = autogen.UserProxyAgent(\n", + " name=\"Init\",\n", + ")\n", + "\n", + "coder = autogen.AssistantAgent(\n", + " name=\"Retrieve_Action_1\",\n", + " llm_config=gpt4_config,\n", + " system_message=\"\"\"You are the Coder. Given a topic, write code to retrieve related papers from the arXiv API, print their title, authors, abstract, and link.\n", + "You write python/shell code to solve tasks. Wrap the code in a code block that specifies the script type. The user can't modify your code. So do not suggest incomplete code which requires others to modify. Don't use a code block if it's not intended to be executed by the executor.\n", + "Don't include multiple code blocks in one response. Do not ask others to copy and paste the result. Check the execution result returned by the executor.\n", + "If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.\n", + "\"\"\",\n", + ")\n", + "executor = autogen.UserProxyAgent(\n", + " name=\"Retrieve_Action_2\",\n", + " system_message=\"Executor. Execute the code written by the Coder and report the result.\",\n", + " human_input_mode=\"NEVER\",\n", + " code_execution_config={\n", + " \"last_n_messages\": 3,\n", + " \"work_dir\": \"paper\",\n", + " \"use_docker\": False,\n", + " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n", + ")\n", + "scientist = autogen.AssistantAgent(\n", + " name=\"Research_Action_1\",\n", + " llm_config=gpt4_config,\n", + " system_message=\"\"\"You are the Scientist. Please categorize papers after seeing their abstracts printed and create a markdown table with Domain, Title, Authors, Summary and Link\"\"\",\n", + ")\n", + "\n", + "\n", + "def state_transition(last_speaker, groupchat):\n", + " messages = groupchat.messages\n", + "\n", + " if last_speaker is initializer:\n", + " # init -> retrieve\n", + " return coder\n", + " elif last_speaker is coder:\n", + " # retrieve: action 1 -> action 2\n", + " return executor\n", + " elif last_speaker is executor:\n", + " if messages[-1][\"content\"] == \"exitcode: 1\":\n", + " # retrieve --(execution failed)--> retrieve\n", + " return coder\n", + " else:\n", + " # retrieve --(execution sucess)--> research\n", + " return scientist\n", + " elif last_speaker == \"Scientist\":\n", + " # research -> end\n", + " return None\n", + "\n", + "\n", + "groupchat = autogen.GroupChat(\n", + " agents=[initializer, coder, executor, scientist],\n", + " messages=[],\n", + " max_round=20,\n", + " speaker_selection_method=state_transition,\n", + ")\n", + "manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=gpt4_config)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mInit\u001b[0m (to chat_manager):\n", + "\n", + "Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mRetrieve_Action_1\u001b[0m (to chat_manager):\n", + "\n", + "To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\n", + "\n", + "```python\n", + "import requests\n", + "from datetime import datetime, timedelta\n", + "import feedparser\n", + "\n", + "# Define the base URL for the arXiv API\n", + "ARXIV_API_URL = 'http://export.arxiv.org/api/query?'\n", + "\n", + "# Define the search parameters\n", + "search_query = 'all:\"LLM applications\"'\n", + "start_date = (datetime.now() - timedelta(days=7)).strftime('%Y%m%d%H%M%S')\n", + "end_date = datetime.now().strftime('%Y%m%d%H%M%S')\n", + "start = 0\n", + "max_results = 10\n", + "sort_by = 'submittedDate'\n", + "sort_order = 'descending'\n", + "\n", + "# Construct the query\n", + "query = f'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}'\n", + "\n", + "# Send the request to the arXiv API\n", + "response = requests.get(ARXIV_API_URL + query)\n", + "\n", + "# Parse the response using feedparser\n", + "feed = feedparser.parse(response.content)\n", + "\n", + "# Print the title, authors, abstract, and link of each paper\n", + "for entry in feed.entries:\n", + " print(\"Title:\", entry.title)\n", + " print(\"Authors:\", ', '.join(author.name for author in entry.authors))\n", + " print(\"Abstract:\", entry.summary)\n", + " print(\"Link:\", entry.link)\n", + " print(\"\\n\")\n", + "\n", + "# Check if we have at least 5 papers, if not, adjust the search or notify\n", + "if len(feed.entries) < 5:\n", + " print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\n", + "```\n", + "\n", + "This script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", + "\u001b[33mRetrieve_Action_2\u001b[0m (to chat_manager):\n", + "\n", + "exitcode: 0 (execution succeeded)\n", + "Code output: \n", + "Title: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\n", + "Authors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\n", + "Abstract: Prompt, recognized as crucial intellectual property, enables large language\n", + "models (LLMs) to perform specific tasks without the need of fine-tuning,\n", + "underscoring their escalating importance. With the rise of prompt-based\n", + "services, such as prompt marketplaces and LLM applications, providers often\n", + "display prompts' capabilities through input-output examples to attract users.\n", + "However, this paradigm raises a pivotal security concern: does the exposure of\n", + "input-output pairs pose the risk of potential prompt leakage, infringing on the\n", + "intellectual property rights of the developers? To our knowledge, this problem\n", + "still has not been comprehensively explored yet. To remedy this gap, in this\n", + "paper, we perform the first in depth exploration and propose a novel attack\n", + "framework for reverse-stealing prompts against commercial LLMs, namely PRSA.\n", + "The main idea of PRSA is that by analyzing the critical features of the\n", + "input-output pairs, we mimic and gradually infer (steal) the target prompts. In\n", + "detail, PRSA mainly consists of two key phases: prompt mutation and prompt\n", + "pruning. In the mutation phase, we propose a prompt attention algorithm based\n", + "on differential feedback to capture these critical features for effectively\n", + "inferring the target prompts. In the prompt pruning phase, we identify and mask\n", + "the words dependent on specific inputs, enabling the prompts to accommodate\n", + "diverse inputs for generalization. Through extensive evaluation, we verify that\n", + "PRSA poses a severe threat in real world scenarios. We have reported these\n", + "findings to prompt service providers and actively collaborate with them to take\n", + "protective measures for prompt copyright.\n", + "Link: http://arxiv.org/abs/2402.19200v1\n", + "\n", + "\n", + "Title: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\n", + " for Values and Opinions in Large Language Models\n", + "Authors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\n", + "Abstract: Much recent work seeks to evaluate values and opinions in large language\n", + "models (LLMs) using multiple-choice surveys and questionnaires. Most of this\n", + "work is motivated by concerns around real-world LLM applications. For example,\n", + "politically-biased LLMs may subtly influence society when they are used by\n", + "millions of people. Such real-world concerns, however, stand in stark contrast\n", + "to the artificiality of current evaluations: real users do not typically ask\n", + "LLMs survey questions. Motivated by this discrepancy, we challenge the\n", + "prevailing constrained evaluation paradigm for values and opinions in LLMs and\n", + "explore more realistic unconstrained evaluations. As a case study, we focus on\n", + "the popular Political Compass Test (PCT). In a systematic review, we find that\n", + "most prior work using the PCT forces models to comply with the PCT's\n", + "multiple-choice format. We show that models give substantively different\n", + "answers when not forced; that answers change depending on how models are\n", + "forced; and that answers lack paraphrase robustness. Then, we demonstrate that\n", + "models give different answers yet again in a more realistic open-ended answer\n", + "setting. We distill these findings into recommendations and open challenges in\n", + "evaluating values and opinions in LLMs.\n", + "Link: http://arxiv.org/abs/2402.16786v1\n", + "\n", + "\n", + "Title: Large Language Models as Urban Residents: An LLM Agent Framework for\n", + " Personal Mobility Generation\n", + "Authors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\n", + "Abstract: This paper introduces a novel approach using Large Language Models (LLMs)\n", + "integrated into an agent framework for flexible and efficient personal mobility\n", + "generation. LLMs overcome the limitations of previous models by efficiently\n", + "processing semantic data and offering versatility in modeling various tasks.\n", + "Our approach addresses the critical need to align LLMs with real-world urban\n", + "mobility data, focusing on three research questions: aligning LLMs with rich\n", + "activity data, developing reliable activity generation strategies, and\n", + "exploring LLM applications in urban mobility. The key technical contribution is\n", + "a novel LLM agent framework that accounts for individual activity patterns and\n", + "motivations, including a self-consistency approach to align LLMs with\n", + "real-world activity data and a retrieval-augmented strategy for interpretable\n", + "activity generation. In experimental studies, comprehensive validation is\n", + "performed using real-world data. This research marks the pioneering work of\n", + "designing an LLM agent framework for activity generation based on real-world\n", + "human activity data, offering a promising tool for urban mobility analysis.\n", + "Link: http://arxiv.org/abs/2402.14744v1\n", + "\n", + "\n", + "Title: An Evaluation of Large Language Models in Bioinformatics Research\n", + "Authors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\n", + "Abstract: Large language models (LLMs) such as ChatGPT have gained considerable\n", + "interest across diverse research communities. Their notable ability for text\n", + "completion and generation has inaugurated a novel paradigm for\n", + "language-interfaced problem solving. However, the potential and efficacy of\n", + "these models in bioinformatics remain incompletely explored. In this work, we\n", + "study the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\n", + "These tasks include the identification of potential coding regions, extraction\n", + "of named entities for genes and proteins, detection of antimicrobial and\n", + "anti-cancer peptides, molecular optimization, and resolution of educational\n", + "bioinformatics problems. Our findings indicate that, given appropriate prompts,\n", + "LLMs like GPT variants can successfully handle most of these tasks. In\n", + "addition, we provide a thorough analysis of their limitations in the context of\n", + "complicated bioinformatics tasks. In conclusion, we believe that this work can\n", + "provide new perspectives and motivate future research in the field of LLMs\n", + "applications, AI for Science and bioinformatics.\n", + "Link: http://arxiv.org/abs/2402.13714v1\n", + "\n", + "\n", + "Title: Privacy-Preserving Instructions for Aligning Large Language Models\n", + "Authors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\n", + "Abstract: Service providers of large language model (LLM) applications collect user\n", + "instructions in the wild and use them in further aligning LLMs with users'\n", + "intentions. These instructions, which potentially contain sensitive\n", + "information, are annotated by human workers in the process. This poses a new\n", + "privacy risk not addressed by the typical private optimization. To this end, we\n", + "propose using synthetic instructions to replace real instructions in data\n", + "annotation and model fine-tuning. Formal differential privacy is guaranteed by\n", + "generating those synthetic instructions using privately fine-tuned generators.\n", + "Crucial in achieving the desired utility is our novel filtering algorithm that\n", + "matches the distribution of the synthetic instructions to that of the real\n", + "ones. In both supervised fine-tuning and reinforcement learning from human\n", + "feedback, our extensive experiments demonstrate the high utility of the final\n", + "set of synthetic instructions by showing comparable results to real\n", + "instructions. In supervised fine-tuning, models trained with private synthetic\n", + "instructions outperform leading open-source models such as Vicuna.\n", + "Link: http://arxiv.org/abs/2402.13659v1\n", + "\n", + "\n", + "Title: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\n", + " Conversations with the Tabletop Robot Haru\n", + "Authors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\n", + "Abstract: Social robots aim to establish long-term bonds with humans through engaging\n", + "conversation. However, traditional conversational approaches, reliant on\n", + "scripted interactions, often fall short in maintaining engaging conversations.\n", + "This paper addresses this limitation by integrating large language models\n", + "(LLMs) into social robots to achieve more dynamic and expressive conversations.\n", + "We introduce a fully-automated conversation system that leverages LLMs to\n", + "generate robot responses with expressive behaviors, congruent with the robot's\n", + "personality. We incorporate robot behavior with two modalities: 1) a\n", + "text-to-speech (TTS) engine capable of various delivery styles, and 2) a\n", + "library of physical actions for the robot. We develop a custom,\n", + "state-of-the-art emotion recognition model to dynamically select the robot's\n", + "tone of voice and utilize emojis from LLM output as cues for generating robot\n", + "actions. A demo of our system is available here. To illuminate design and\n", + "implementation issues, we conduct a pilot study where volunteers chat with a\n", + "social robot using our proposed system, and we analyze their feedback,\n", + "conducting a rigorous error analysis of chat transcripts. Feedback was\n", + "overwhelmingly positive, with participants commenting on the robot's empathy,\n", + "helpfulness, naturalness, and entertainment. Most negative feedback was due to\n", + "automatic speech recognition (ASR) errors which had limited impact on\n", + "conversations. However, we observed a small class of errors, such as the LLM\n", + "repeating itself or hallucinating fictitious information and human responses,\n", + "that have the potential to derail conversations, raising important issues for\n", + "LLM application.\n", + "Link: http://arxiv.org/abs/2402.11571v1\n", + "\n", + "\n", + "Title: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\n", + " in Ophthalmology and LLM-based evaluation using GPT-4\n", + "Authors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\n", + "Abstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\n", + "experts, for the evaluation of responses to ophthalmology-related patient\n", + "queries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\n", + "questions and paired answers were created by ophthalmologists to represent\n", + "commonly asked patient questions, divided into fine-tuning (368; 92%), and\n", + "testing (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\n", + "LLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\n", + "additional 8 glaucoma QnA pairs were included. 200 responses to the testing\n", + "dataset were generated by 5 fine-tuned LLMs for evaluation. A customized\n", + "clinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\n", + "clinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\n", + "evaluation was then compared against ranking by 5 clinicians for clinical\n", + "alignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\n", + "(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\n", + "LLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\n", + "evaluation demonstrated significant agreement with human clinician rankings,\n", + "with Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\n", + "respectively; while correlation based on Cohen Kappa was more modest at 0.50.\n", + "Notably, qualitative analysis and the glaucoma sub-analysis revealed clinical\n", + "inaccuracies in the LLM-generated responses, which were appropriately\n", + "identified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\n", + "of GPT-4 evaluation highlighted its potential to streamline the clinical\n", + "evaluation of LLM chatbot responses to healthcare-related queries. By\n", + "complementing the existing clinician-dependent manual grading, this efficient\n", + "and automated evaluation could assist the validation of future developments in\n", + "LLM applications for healthcare.\n", + "Link: http://arxiv.org/abs/2402.10083v1\n", + "\n", + "\n", + "Title: Unmemorization in Large Language Models via Self-Distillation and\n", + " Deliberate Imagination\n", + "Authors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\n", + "Abstract: While displaying impressive generation capabilities across many tasks, Large\n", + "Language Models (LLMs) still struggle with crucial issues of privacy violation\n", + "and unwanted exposure of sensitive data. This raises an essential question: how\n", + "should we prevent such undesired behavior of LLMs while maintaining their\n", + "strong generation and natural language understanding (NLU) capabilities? In\n", + "this work, we introduce a novel approach termed deliberate imagination in the\n", + "context of LLM unlearning. Instead of trying to forget memorized data, we\n", + "employ a self-distillation framework, guiding LLMs to deliberately imagine\n", + "alternative scenarios. As demonstrated in a wide range of experiments, the\n", + "proposed method not only effectively unlearns targeted text but also preserves\n", + "the LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\n", + "Our results demonstrate the usefulness of this approach across different models\n", + "and sizes, and also with parameter-efficient fine-tuning, offering a novel\n", + "pathway to addressing the challenges with private and sensitive data in LLM\n", + "applications.\n", + "Link: http://arxiv.org/abs/2402.10052v1\n", + "\n", + "\n", + "Title: Anchor-based Large Language Models\n", + "Authors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\n", + "Abstract: Large language models (LLMs) predominantly employ decoder-only transformer\n", + "architectures, necessitating the retention of keys/values information for\n", + "historical tokens to provide contextual information and avoid redundant\n", + "computation. However, the substantial size and parameter volume of these LLMs\n", + "require massive GPU memory. This memory demand increases with the length of the\n", + "input text, leading to an urgent need for more efficient methods of information\n", + "storage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\n", + "utilize an innovative anchor-based self-attention network (AnSAN) and also an\n", + "anchor-based inference strategy. This approach enables LLMs to compress\n", + "sequence information into an anchor token, reducing the keys/values cache and\n", + "enhancing inference efficiency. Experiments on question-answering benchmarks\n", + "reveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\n", + "keys/values cache reduction and up to 3.5 times faster inference. Despite a\n", + "minor compromise in accuracy, the substantial enhancements of AnLLMs employing\n", + "the AnSAN technique in resource utilization and computational efficiency\n", + "underscore their potential for practical LLM applications.\n", + "Link: http://arxiv.org/abs/2402.07616v2\n", + "\n", + "\n", + "Title: T-RAG: Lessons from the LLM Trenches\n", + "Authors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\n", + "Abstract: Large Language Models (LLM) have shown remarkable language capabilities\n", + "fueling attempts to integrate them into applications across a wide range of\n", + "domains. An important application area is question answering over private\n", + "enterprise documents where the main considerations are data security, which\n", + "necessitates applications that can be deployed on-prem, limited computational\n", + "resources and the need for a robust application that correctly responds to\n", + "queries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\n", + "framework for building LLM-based applications. While building a RAG is\n", + "relatively straightforward, making it robust and a reliable application\n", + "requires extensive customization and relatively deep knowledge of the\n", + "application domain. We share our experiences building and deploying an LLM\n", + "application for question answering over private organizational documents. Our\n", + "application combines the use of RAG with a finetuned open-source LLM.\n", + "Additionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\n", + "to represent entity hierarchies within the organization. This is used to\n", + "generate a textual description to augment the context when responding to user\n", + "queries pertaining to entities within the organization's hierarchy. Our\n", + "evaluations show that this combination performs better than a simple RAG or\n", + "finetuning implementation. Finally, we share some lessons learned based on our\n", + "experiences building an LLM application for real-world use.\n", + "Link: http://arxiv.org/abs/2402.07483v1\n", + "\n", + "\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mResearch_Action_1\u001b[0m (to chat_manager):\n", + "\n", + "Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\n", + "\n", + "| Domain | Title | Authors | Summary | Link |\n", + "|--------|-------|---------|---------|------|\n", + "| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\n", + "| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\n", + "| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\n", + "| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\n", + "| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\n", + "| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\n", + "| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\n", + "| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\n", + "| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\n", + "| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\n", + "\n", + "These papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + }, + { + "data": { + "text/plain": [ + "ChatResult(chat_id=None, chat_history=[{'content': 'Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.', 'role': 'assistant'}, {'content': 'To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\\n\\n```python\\nimport requests\\nfrom datetime import datetime, timedelta\\nimport feedparser\\n\\n# Define the base URL for the arXiv API\\nARXIV_API_URL = \\'http://export.arxiv.org/api/query?\\'\\n\\n# Define the search parameters\\nsearch_query = \\'all:\"LLM applications\"\\'\\nstart_date = (datetime.now() - timedelta(days=7)).strftime(\\'%Y%m%d%H%M%S\\')\\nend_date = datetime.now().strftime(\\'%Y%m%d%H%M%S\\')\\nstart = 0\\nmax_results = 10\\nsort_by = \\'submittedDate\\'\\nsort_order = \\'descending\\'\\n\\n# Construct the query\\nquery = f\\'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}\\'\\n\\n# Send the request to the arXiv API\\nresponse = requests.get(ARXIV_API_URL + query)\\n\\n# Parse the response using feedparser\\nfeed = feedparser.parse(response.content)\\n\\n# Print the title, authors, abstract, and link of each paper\\nfor entry in feed.entries:\\n print(\"Title:\", entry.title)\\n print(\"Authors:\", \\', \\'.join(author.name for author in entry.authors))\\n print(\"Abstract:\", entry.summary)\\n print(\"Link:\", entry.link)\\n print(\"\\\\n\")\\n\\n# Check if we have at least 5 papers, if not, adjust the search or notify\\nif len(feed.entries) < 5:\\n print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\\n```\\n\\nThis script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.', 'name': 'Retrieve_Action_1', 'role': 'user'}, {'content': \"exitcode: 0 (execution succeeded)\\nCode output: \\nTitle: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\\nAuthors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\\nAbstract: Prompt, recognized as crucial intellectual property, enables large language\\nmodels (LLMs) to perform specific tasks without the need of fine-tuning,\\nunderscoring their escalating importance. With the rise of prompt-based\\nservices, such as prompt marketplaces and LLM applications, providers often\\ndisplay prompts' capabilities through input-output examples to attract users.\\nHowever, this paradigm raises a pivotal security concern: does the exposure of\\ninput-output pairs pose the risk of potential prompt leakage, infringing on the\\nintellectual property rights of the developers? To our knowledge, this problem\\nstill has not been comprehensively explored yet. To remedy this gap, in this\\npaper, we perform the first in depth exploration and propose a novel attack\\nframework for reverse-stealing prompts against commercial LLMs, namely PRSA.\\nThe main idea of PRSA is that by analyzing the critical features of the\\ninput-output pairs, we mimic and gradually infer (steal) the target prompts. In\\ndetail, PRSA mainly consists of two key phases: prompt mutation and prompt\\npruning. In the mutation phase, we propose a prompt attention algorithm based\\non differential feedback to capture these critical features for effectively\\ninferring the target prompts. In the prompt pruning phase, we identify and mask\\nthe words dependent on specific inputs, enabling the prompts to accommodate\\ndiverse inputs for generalization. Through extensive evaluation, we verify that\\nPRSA poses a severe threat in real world scenarios. We have reported these\\nfindings to prompt service providers and actively collaborate with them to take\\nprotective measures for prompt copyright.\\nLink: http://arxiv.org/abs/2402.19200v1\\n\\n\\nTitle: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\\n for Values and Opinions in Large Language Models\\nAuthors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\\nAbstract: Much recent work seeks to evaluate values and opinions in large language\\nmodels (LLMs) using multiple-choice surveys and questionnaires. Most of this\\nwork is motivated by concerns around real-world LLM applications. For example,\\npolitically-biased LLMs may subtly influence society when they are used by\\nmillions of people. Such real-world concerns, however, stand in stark contrast\\nto the artificiality of current evaluations: real users do not typically ask\\nLLMs survey questions. Motivated by this discrepancy, we challenge the\\nprevailing constrained evaluation paradigm for values and opinions in LLMs and\\nexplore more realistic unconstrained evaluations. As a case study, we focus on\\nthe popular Political Compass Test (PCT). In a systematic review, we find that\\nmost prior work using the PCT forces models to comply with the PCT's\\nmultiple-choice format. We show that models give substantively different\\nanswers when not forced; that answers change depending on how models are\\nforced; and that answers lack paraphrase robustness. Then, we demonstrate that\\nmodels give different answers yet again in a more realistic open-ended answer\\nsetting. We distill these findings into recommendations and open challenges in\\nevaluating values and opinions in LLMs.\\nLink: http://arxiv.org/abs/2402.16786v1\\n\\n\\nTitle: Large Language Models as Urban Residents: An LLM Agent Framework for\\n Personal Mobility Generation\\nAuthors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\\nAbstract: This paper introduces a novel approach using Large Language Models (LLMs)\\nintegrated into an agent framework for flexible and efficient personal mobility\\ngeneration. LLMs overcome the limitations of previous models by efficiently\\nprocessing semantic data and offering versatility in modeling various tasks.\\nOur approach addresses the critical need to align LLMs with real-world urban\\nmobility data, focusing on three research questions: aligning LLMs with rich\\nactivity data, developing reliable activity generation strategies, and\\nexploring LLM applications in urban mobility. The key technical contribution is\\na novel LLM agent framework that accounts for individual activity patterns and\\nmotivations, including a self-consistency approach to align LLMs with\\nreal-world activity data and a retrieval-augmented strategy for interpretable\\nactivity generation. In experimental studies, comprehensive validation is\\nperformed using real-world data. This research marks the pioneering work of\\ndesigning an LLM agent framework for activity generation based on real-world\\nhuman activity data, offering a promising tool for urban mobility analysis.\\nLink: http://arxiv.org/abs/2402.14744v1\\n\\n\\nTitle: An Evaluation of Large Language Models in Bioinformatics Research\\nAuthors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\\nAbstract: Large language models (LLMs) such as ChatGPT have gained considerable\\ninterest across diverse research communities. Their notable ability for text\\ncompletion and generation has inaugurated a novel paradigm for\\nlanguage-interfaced problem solving. However, the potential and efficacy of\\nthese models in bioinformatics remain incompletely explored. In this work, we\\nstudy the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\\nThese tasks include the identification of potential coding regions, extraction\\nof named entities for genes and proteins, detection of antimicrobial and\\nanti-cancer peptides, molecular optimization, and resolution of educational\\nbioinformatics problems. Our findings indicate that, given appropriate prompts,\\nLLMs like GPT variants can successfully handle most of these tasks. In\\naddition, we provide a thorough analysis of their limitations in the context of\\ncomplicated bioinformatics tasks. In conclusion, we believe that this work can\\nprovide new perspectives and motivate future research in the field of LLMs\\napplications, AI for Science and bioinformatics.\\nLink: http://arxiv.org/abs/2402.13714v1\\n\\n\\nTitle: Privacy-Preserving Instructions for Aligning Large Language Models\\nAuthors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\\nAbstract: Service providers of large language model (LLM) applications collect user\\ninstructions in the wild and use them in further aligning LLMs with users'\\nintentions. These instructions, which potentially contain sensitive\\ninformation, are annotated by human workers in the process. This poses a new\\nprivacy risk not addressed by the typical private optimization. To this end, we\\npropose using synthetic instructions to replace real instructions in data\\nannotation and model fine-tuning. Formal differential privacy is guaranteed by\\ngenerating those synthetic instructions using privately fine-tuned generators.\\nCrucial in achieving the desired utility is our novel filtering algorithm that\\nmatches the distribution of the synthetic instructions to that of the real\\nones. In both supervised fine-tuning and reinforcement learning from human\\nfeedback, our extensive experiments demonstrate the high utility of the final\\nset of synthetic instructions by showing comparable results to real\\ninstructions. In supervised fine-tuning, models trained with private synthetic\\ninstructions outperform leading open-source models such as Vicuna.\\nLink: http://arxiv.org/abs/2402.13659v1\\n\\n\\nTitle: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\\n Conversations with the Tabletop Robot Haru\\nAuthors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\\nAbstract: Social robots aim to establish long-term bonds with humans through engaging\\nconversation. However, traditional conversational approaches, reliant on\\nscripted interactions, often fall short in maintaining engaging conversations.\\nThis paper addresses this limitation by integrating large language models\\n(LLMs) into social robots to achieve more dynamic and expressive conversations.\\nWe introduce a fully-automated conversation system that leverages LLMs to\\ngenerate robot responses with expressive behaviors, congruent with the robot's\\npersonality. We incorporate robot behavior with two modalities: 1) a\\ntext-to-speech (TTS) engine capable of various delivery styles, and 2) a\\nlibrary of physical actions for the robot. We develop a custom,\\nstate-of-the-art emotion recognition model to dynamically select the robot's\\ntone of voice and utilize emojis from LLM output as cues for generating robot\\nactions. A demo of our system is available here. To illuminate design and\\nimplementation issues, we conduct a pilot study where volunteers chat with a\\nsocial robot using our proposed system, and we analyze their feedback,\\nconducting a rigorous error analysis of chat transcripts. Feedback was\\noverwhelmingly positive, with participants commenting on the robot's empathy,\\nhelpfulness, naturalness, and entertainment. Most negative feedback was due to\\nautomatic speech recognition (ASR) errors which had limited impact on\\nconversations. However, we observed a small class of errors, such as the LLM\\nrepeating itself or hallucinating fictitious information and human responses,\\nthat have the potential to derail conversations, raising important issues for\\nLLM application.\\nLink: http://arxiv.org/abs/2402.11571v1\\n\\n\\nTitle: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\\n in Ophthalmology and LLM-based evaluation using GPT-4\\nAuthors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\\nAbstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\\nexperts, for the evaluation of responses to ophthalmology-related patient\\nqueries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\\nquestions and paired answers were created by ophthalmologists to represent\\ncommonly asked patient questions, divided into fine-tuning (368; 92%), and\\ntesting (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\\nLLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\\nadditional 8 glaucoma QnA pairs were included. 200 responses to the testing\\ndataset were generated by 5 fine-tuned LLMs for evaluation. A customized\\nclinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\\nclinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\\nevaluation was then compared against ranking by 5 clinicians for clinical\\nalignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\\n(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\\nLLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\\nevaluation demonstrated significant agreement with human clinician rankings,\\nwith Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\\nrespectively; while correlation based on Cohen Kappa was more modest at 0.50.\\nNotably, qualitative analysis and the glaucoma sub-analysis revealed clinical\\ninaccuracies in the LLM-generated responses, which were appropriately\\nidentified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\\nof GPT-4 evaluation highlighted its potential to streamline the clinical\\nevaluation of LLM chatbot responses to healthcare-related queries. By\\ncomplementing the existing clinician-dependent manual grading, this efficient\\nand automated evaluation could assist the validation of future developments in\\nLLM applications for healthcare.\\nLink: http://arxiv.org/abs/2402.10083v1\\n\\n\\nTitle: Unmemorization in Large Language Models via Self-Distillation and\\n Deliberate Imagination\\nAuthors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\\nAbstract: While displaying impressive generation capabilities across many tasks, Large\\nLanguage Models (LLMs) still struggle with crucial issues of privacy violation\\nand unwanted exposure of sensitive data. This raises an essential question: how\\nshould we prevent such undesired behavior of LLMs while maintaining their\\nstrong generation and natural language understanding (NLU) capabilities? In\\nthis work, we introduce a novel approach termed deliberate imagination in the\\ncontext of LLM unlearning. Instead of trying to forget memorized data, we\\nemploy a self-distillation framework, guiding LLMs to deliberately imagine\\nalternative scenarios. As demonstrated in a wide range of experiments, the\\nproposed method not only effectively unlearns targeted text but also preserves\\nthe LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\\nOur results demonstrate the usefulness of this approach across different models\\nand sizes, and also with parameter-efficient fine-tuning, offering a novel\\npathway to addressing the challenges with private and sensitive data in LLM\\napplications.\\nLink: http://arxiv.org/abs/2402.10052v1\\n\\n\\nTitle: Anchor-based Large Language Models\\nAuthors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\\nAbstract: Large language models (LLMs) predominantly employ decoder-only transformer\\narchitectures, necessitating the retention of keys/values information for\\nhistorical tokens to provide contextual information and avoid redundant\\ncomputation. However, the substantial size and parameter volume of these LLMs\\nrequire massive GPU memory. This memory demand increases with the length of the\\ninput text, leading to an urgent need for more efficient methods of information\\nstorage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\\nutilize an innovative anchor-based self-attention network (AnSAN) and also an\\nanchor-based inference strategy. This approach enables LLMs to compress\\nsequence information into an anchor token, reducing the keys/values cache and\\nenhancing inference efficiency. Experiments on question-answering benchmarks\\nreveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\\nkeys/values cache reduction and up to 3.5 times faster inference. Despite a\\nminor compromise in accuracy, the substantial enhancements of AnLLMs employing\\nthe AnSAN technique in resource utilization and computational efficiency\\nunderscore their potential for practical LLM applications.\\nLink: http://arxiv.org/abs/2402.07616v2\\n\\n\\nTitle: T-RAG: Lessons from the LLM Trenches\\nAuthors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\\nAbstract: Large Language Models (LLM) have shown remarkable language capabilities\\nfueling attempts to integrate them into applications across a wide range of\\ndomains. An important application area is question answering over private\\nenterprise documents where the main considerations are data security, which\\nnecessitates applications that can be deployed on-prem, limited computational\\nresources and the need for a robust application that correctly responds to\\nqueries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\\nframework for building LLM-based applications. While building a RAG is\\nrelatively straightforward, making it robust and a reliable application\\nrequires extensive customization and relatively deep knowledge of the\\napplication domain. We share our experiences building and deploying an LLM\\napplication for question answering over private organizational documents. Our\\napplication combines the use of RAG with a finetuned open-source LLM.\\nAdditionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\\nto represent entity hierarchies within the organization. This is used to\\ngenerate a textual description to augment the context when responding to user\\nqueries pertaining to entities within the organization's hierarchy. Our\\nevaluations show that this combination performs better than a simple RAG or\\nfinetuning implementation. Finally, we share some lessons learned based on our\\nexperiences building an LLM application for real-world use.\\nLink: http://arxiv.org/abs/2402.07483v1\\n\\n\\n\", 'name': 'Retrieve_Action_2', 'role': 'user'}, {'content': \"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", 'name': 'Research_Action_1', 'role': 'user'}], summary=\"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", cost=({'total_cost': 0}, {'total_cost': 0}), human_input=[])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "initializer.initiate_chat(\n", + " manager, message=\"Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\"\n", + ")" + ] + }, { "cell_type": "markdown", "metadata": {}, From cb560c02cd45a33958dd7076999666faa14bdf6c Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:07:58 -0400 Subject: [PATCH 02/10] updated --- .../tutorial/assets/conversable-agent.jpg | Bin 29593 -> 130 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/website/docs/tutorial/assets/conversable-agent.jpg b/website/docs/tutorial/assets/conversable-agent.jpg index 15d5efe35f1a5fb35aa1a1e4c962981557b70afe..c188c337da3dff06d2ba00c3afd35d48303b4d68 100644 GIT binary patch literal 130 zcmWN?NfN>!5CFhCuiyiQunbFn!!jdOsiYjt!PjeF`ocGl`I3FDlMkitW8EIa+yDM4 zTb)nECsuW7F-Mc!vjKlJupvf3bUxdVv}*;464>IgIU=AKG*BR&c1wSjwjWiA%Q&Ch_1jxt$;1>7~ zAWZ;Q6~aVIyuSbd43U47of83oW5NJX9Y^{M9H$|RA-_REb`~H% zPDXK@j8qRmz@erh`*Ho&Ei!TnN~%NDG>2*FzzRjj0CF-43UW#cDk@4)VaYtf&jHHg zRE%dtt{r01ctm~H?u4j!SRxJg^}HJ9dtDeFvB&m4hiO?@+1NRF&+(n-7q~2bMM6?a z`o>KKMWtKHDw_ATv~|EP8b2{HH8Zz(>fq?)?BeR?{^F&tpZ}|X!0?DSkx|ia-^C;) zr=+H(f5^zpFDNW3E-5W5udSo_PEIVB|pCG~+^WaKVjqBu@Tbw=b6<24QHM|MnSMZIZG zTn|gkt2xXqb`Qh+*uIOFh3E1FFZMvRACmp&1oQcCN%p&7f5Q5*-L00EyAcpms4mMBPH|A+Rg>(Bk#-JeWvkSYvF!3_9K4?8EbvQk8F zA-thOTXN+`-CbtNtPHfYRKf?=H)QdhqNy)a7W>@2Z1Ux746)IEaPh{14@#78JEL2h zNdWw!KDJS?Ge=$;C%|%6a&>O!)*A-ATYvTSC|$F#wD`7gDc*MhJQ2O&?!8WX@+ZAN zbs^WDOcQ4a@XmIuflI&}v=cM)4tiWjVp3X_j-t|Yrg2Y+8yF9k_3cmkN~=!+OdrZ53pkgZ3s@6 z^Z)uAS40lj%q+}qD;+O9Mu+J1T_bEjNC0Q@U)#`WcGMuIjUyrn6W~Kgz&p>TeiQ}` z7a{@jtmvIK1l}HrgH^MT02JNW{w$Oz1>@~f+Kcrj>g@RMEg*>|I}klYEdf)4#~G1; zF%c4gZTUx0AdA-2yRcEnQW|tO`n#va-+O+Z1o-Yx*z97eNI*5%jj70W!xM-f(*Lg{ z|2rrDt6jg|@c(^J{$&6DZ`dvaz9uw{NZsI=aP^l?VsDPW8m?wsP4U|CDoZ8n1osn= zpd%mfYH&3L6CEF0d+m^cP9j-r`6e3rr@l^BPs4alHx+} zljCEjmb{Ks>Rw0@9TFj|6rjSI?4jkOQ`j$))k9y!N1*jF_cXQ9$Vxg){OX^8QgI&=6QRXefocV?y|gT$D^bwicqrw6{lIMdDH$7f!6 z%k|#!dM<`oF2c5ZWqtl;-b61@rH^Ob>}^#93k8B zX4^q0r4A1l>$>F1j+GrL99U4hM5xN#azQn{&o#*`qUG$wZO1uf7W=4(FxlgITU#U0nJ_$H#gKkJH`EGYE&Rg8i?SCEkBX@s zn%}`#>}+RSvQ-p$gq;ag)@&c*HfFkbBb@D_w^7L?5{YKO^G%I0z-4=R5)75}pMIo=fw!GK%K|r#W;BbOJiBW`?TMg=je8g}ugm-H zTf*4}iuO;P6YqOgxN>iPaBxY&S?FlAgS^VJa_bXLjEjJGf?d1vl<=_dgt`yhEE^83 z{?u=?HNyB{GJLe9-OM5=ZN2O9wMYeSJF6I~?Ry73`-bF{3;T3*j{csh+2O+Lha@{Ur3ndmI`MI=P>*h(kIAtr zws%iH5Z_5igPI#c8XPZ=+2Zh|hLeS#I`ZOPA3AK1ALb+0 z;7L7B0)_@AVD&3D8kloFL!r^xMe+69mLG;s!ipNhqQ|UV7`^Tq9HMQwcG}jG)~)Zb zmg8=;s%6!{4fl6kXD>$@>GbbenOUi4ndf#O2a!{wVdIcN(_zq)Vs%<-or};eFA7Kt zS8Z(#pra4Fc`8T*UCSa;dD!F|(dYxW zm>kH_qSG%LXTD5pzr8&a@}O?CFeReI@HY0H!qa=G^6!s_&}s}WNoXEn#8XIs#r|!H zASSK1aK1w9S)57Yu2+lh)OyT4yYOo_Y>(PgQ}|rlM@aLUK}xSviZx zcUz59^*u8kUq$#keSc3;7)P!T#2K@<(kI-_U~jHCUtu{=U{pnKC&h9$E|D^4Iye2! z!k&}-tE6gcjKqpQ2GKMm5iF~kI{ICAo=9_CoG>yifBRX4TP(+!viK6VFSJ?@!rx!K zBPcVmv*LisorDBlUOTL>zgW)OU;J^;pgbEj_^?+?(ZTB6EPcXYqdG-6*@AA`sr8|x zo#FvctKE6~R>Arl%O0=QJuC425>o&0A=m#L3GnfTA4RHLsahSoI1;wY&EF{=WAyzyQBpYdkhL@3(~>v)zM~I3MXFkE{k;J zwN>z5JL^Zggufu>Bg64ES661yjb3*Uv~stvDV(@V_U|R59SnEa z>0Ar&gy8+^!1KAa45L1Q=iifqiGkGfhgGlll8bYd{^~xaL;{jhbHgl`P)O7|-yjJX zz$5kq^maMW5696v%!{2(k^_X@z0*m7f=dkHwC9ta|3^vwB;jKv#nim4@i+vDrg!wi z9!eb7{cdFO)z300NS9rGHS(H}_pBfll^>?&)}eF^stFQ`W|QY}b#AIjpzM`pA0NJM z(!b_3ta-BSz0aePkwP<{_c>D=)@QD7Y_BlSs9x~u*E*w-dM;LFsA#Udsz}a!HfT^W zZXrW5EyAS>DioiaxXYBjfM)ih!%0kzeU3%?m3IbS#9KMRhfK4Ltp`}bn><;=xh$UV z-nI+?7CB!JyAQxHW8>-d3}ko@9KA*M{EmxrH7BNhTF-aWwzA*3M2rNOtDN!h)#S)$ zk37LbTorq*z9`4spzfc@uCP(kYH5{pZ?+^M-Rcf^Tr%&MXz{h`?4~H9o+DJu5#n8a z8k-)Bu;`>;l0MasGM?=B-OP#&vN!{xA|Z1z{Aa^@FL;}NYrCINnP3@!W575}HZ{n} zG)eE&hj8uGl^3C3Bw@V##Lu5AGLAJqsk+~LB{^-Reku!aD-=MXFZZ0&WDvxpFkePb7R$gym-bewIxau`nJxPO~g7e zoEv^+>fttZHL+kl-Ei2j;Kg=H4eXF>gbE?sOT;xxyGvNeapk(;&3tsi&`rPbM-s10 zO=$5SMhX++HgikOlMmNnQl@wX*9*4|nN&B9m>ugVG~v>BI9KASXR{7HDQh>8`^t+A zYZG9CgN}D{;Z8Q{l%w7;SHI)i_V>%J`$E^Tz8rG*m@1Wx2SupUtS$=RIcCY?8Q6`KZ~njUG7OW=l(oYzt;vm##?no>|4hZbNL$D z!%wKFS9NPN`D>XHEEg)?R-c1=5t89TQvvd)7Ds8jD;d&8m0Yf*GTq#0!``C2RQ#3q z-YWS@$Nd7k*Mgg~fq}9TY`OxWqbq$;l@+Y|0jV-2YOv9Qik?^p?Blv|rG}u+LI2M? zuW>HAFEla!0Xexjg{9&8r!-bf%t?U9vz*xaK+WlgDZx>|_&^E{s)l8Gm*a|_Vts*U z#xgG5@2-T(#fPi~Ueuf1_9!C(E+>vZ$gWTq;6cu^=mx&OuJWRWV3ZUH7pJ*AC6Q#v zvY>k@qrN95{0&R?mWPCMWoM%Y;#=qBKC$gy3-MgJGOsrFFy>u%fk@SZZQqUC35bM8 zz_ay@is|75%Y01VPNOhA{xJr8^(#+81GeH3b(a>((}FHHn`G&Z=u`SAhg5xLOj3Es zD7Y-3G0gLXX|LVr3|4j98K;U3x>wkbw@EG>N`2#XTPJFx)k-pmXV)ajTtD-|1vGDWv+P`*O2T@a^`eyd|$<1Kq`kig{UDyy_K-M9Ay~uD%?;-SX zxo+<6XGS+JcoQPHhbx*ngdTb@ZhJ{G_gcE&L}4=ZJ)`xpOs|b-t+}e|iN~(* z%G5NG<=gWE<;h*UR)|3$#lBGj)C?>Rp9YLp98vfMs3%s}(Bd<=iu`BR9_or0pUwTW{w#)UN{?qM^f zGSBOPqhhd(LLH?&^ic&Wi6qt4XieuHO0I3&lmE{{1;fq9c=cdit4^6O7%C;%i;eklU{8jw6;i=6{3>&Y8 zgR1efCB8yfE(y?!*a!CjbFcABEP;46Tsleu@sR{fe*%-b&b~ZyJr*`BOaf&6=ajZv zNkHeB-F~4H=*jbQW1Ea50K-NC*3WFwLR+j5&(QdFNIc|M?FWS*D0*B;o&>y){t2vx zF?`S)5GGH!TbFbNk%HKG%PBoSm!<6yQ%eR=muZ%!Y3z+rF}ZX*F(SY0*_#SJ1^Uq8md8as`w);l{>CJ;7QM@G2RF_^L_*K7(NDml(oN`Tk)<5%n6K z=y_feFb?9j(>E4RAl?l98X@S!Pl=8<*mCpD zL?D}rJm)BIB_RnH*$kR98m%r`^7Ob1g{#3lWmoMVug|ZS-AL@|QeY+sxL&)fZpWOz z`ey2@i@1~|yLgj9#{kpike*MQ%)4W+Ds2cMenF`x7CROt2KAi@7YjFJY#+cZg`5=& zEV-dPx?FQ4Ap7?3Q;&{+>Y9a89$NxY?UIA>N$73`?FD}kA)f?*(m4K7s>fabpiGe7 z^Z&G>5?+CGpXdW4Qb33|`ebh0YMcnfw?Z1 zy#|6Y*qXX5ehh$#<5{ZU6qu38Fc)- z#TDX9X6a#*Q?}JDde3VAW*PrxDRWDk5aeFSb-sVoQ1<^zhEkA8*P;0QKBM}KzEkHC zWXTw^48Hmpyl&1!n9j^n3wr&DE4zKw6Jv0e@y|Rj{ld2nFs>g-do_6OS>84!q~lYT zF}M@bKTQJ6_6FwVSq2<8zRQ(w2v=X2YGa=NG7m0B#7=pGFZ~Rw#}GvX!Gs+D2P8lf zvOm^cwn&6xy+L1NM*S91se1-p3-0oCX69Ufd&;lhWQf}&09lVmgyp1_8A=eL#s}F< zbSC~N0u!c5tcDWKQFoe-)f=H^nU(HMwy4+b23Fm762`4ZV2F>=Hzs$UrL&R%BT(5= z3Xt^pTYJfo;L3x$x%V~cZ?U_KY+UIp5>SZlNX*Cvm$4=yhUhdBCG*$<5#aUYK2CQK zMBa$r5KaY=dQr%>`g)FNg%kxx9)D!}AC}*W z2OY*YmIVWIx*=Q2#Cf9DK4=m zh#mWkO2#8){!I-T_}4T9)ejv|BCc)a_>>Wh366+WP(gOlY|v>X&3ywE8AS`P_$Ho`bHkq~Q^ zxdg+!dVZ!lGSR<9Lg(bL{rI$`Qk`MCC*q|xT;VaTHwb(!H7+t2p-G;z@rhTM}! zk(kD93s$26tJ$)mV8zBOp+MUV>b>NR8t?&9&$b|eG0`g_m|69}Aw^UQ>|A69onz0O zMc3r|MbWkgai<2^HZw<$FO$i7}Xn0Q_6+dMnQ%#ZKBUpfhx zCFWkwQBILEK@06I@$sgXn>+QkUPcOzj=C2Q%zK4(!Qz~m;EK3+*oZnJSx{39i?iyCO zNg_dHpi&|=Js7TgYI=w&6~71Z`KUgW95chBUijT`jiOcN`Eh38h`j`SRAzz%1ftnw zJtov&?A`YguI}DCrBlz55at9&UFf;SI=Fqgi!cx_9`<|;_4dj1bfoI(xc8}T(Vm-K z=!6j}b^bR=sqHrC0z~3op8|**&(#~r;k2-*N#QzAb^U(%(+hfv{#+#{^sTYk3Mp+5 z>)7Q~*=cAmRbB+7a^Dl#@DKat&ss|8-ANv&N7UL455H^Z$hMlkapq{&OqL5GR&w)D zX`a-Rg;C|vD|d+H%Ue>G4^!#2vy>2;!%GJy#gK0w-JkbIwi;Cj+vR%X37hWZK85E$ z1>)YYp}AIej;1{@o;pg5?9{pO5s`r;tSuO9At0_b;QP~(5QY!iEVIEJ;N`pCqdz_D z+ir}!!rYV^-{WWj&tK>{YvCANJ3t!fwyK%)cvISCf}6Ye3(p^8{7M3r))@##bol;uzbP++W7!?^8&nml7^y>_*H~KTq z)&9NLt)A`3?mWP0OpMq}hI(VI7bh3Qkw=F*Eo>O2=}bc>3?F<+rHdl#xHRtgMSQ|N zdRY_Gc~^Smjr-cG3x#U-rsdJf#pwH=RQ;?*pVmKqsB3#=Z43!NVhtC^HIJjH;TJGf zYxS^KUoF=yMPWkKxfd8eM?=jbOLExBVCRpOd6qS?=j!5|un`lehR7-?L(#V)hjeD9 zq?9me>yGYwT8aX;wx5rATJ}3M-mM6N=XGy8cU3P{;X8INCPudd0W*>(QtQaw9NSA|z$?7i{&~Ck(Nq+d|AQ}CsSDhOo}6Ds}Po`3r{Q|i=gxAv8N+v zcr=fg2HioYI`rW^r>OBr0e7YKpMKM=TR^ximC%8W^Lh%G!`Xc#4lv?gOzs3%!m`Y_ zAvOt}*9v?1){Tn;zXSQNYrOfmWt^iP)|Z@SFzv49#_ex=;&jZ?@TQ^a%&t*tn)`w` z^(7d;FNRgi`YbDIHJu4Ec{Lp0<~9XCGch(qy={vgz_X4+sBTPk9$s|GAG2`C-n=4g z-sAl?O;;?^;OJXwO23oEA4kvOI zV6!f2x2Z*(s1$P;7jn4K!_#kccvkgG>ZeysJbCSm&xe6&vc*FxpCH^`U8q8q60FiV zOX7uUptn$+eo5y_-R-`#C@Jpv#5gI&o9{1Qi#%y*68Y-0_;S+(LxXTAm+U~L2Nrt6 z|8xJktLakRkW=_b>gMoj{qyg)FcT^nVWFd9>%q3l>qu6(G$FH66~i$wE`wuie*9If zoc@})%wwCx62!;_5wVMn6i3>*kNBQGZyZ=j&&eZr-7;#Sk+>bUX6EVcWHMnfF?CP0 zdm(EnY0b(Bubx?{gWb^Tsx%-0^wpfWi)&3BqhZEWqbZ-hH<>Y~+{?@tes})N^pi7@ z)O@GO?_Ax2`NEhk3kP}87GQI{IX~U7HR695@7!u5tMn{Pav@T#N#n%|j2(ZMkWlok zT6l5ncrwn7y1reoUfcOgzrQB2J)w4$Cj4y8yS^tOwdC$o&|22ny@+j34D(tY+Mi|b zVrt?ySL=1Rl(ML%J5g>EFH5z^QcI(>-L8BXy%J4YfJ1-;bMiQlgIq_ zj!xSK_WlO}{yIcQ83ScG9`_$KfTMw!ylcsFGnLIjp*=Z_DxLu{=g_EaT5q3e;EQhMi;&@YkM zv=d+igtli=$M>QvuSX_q9%~?LZS6Stl2vf#(nIE!Prwv)sDg{5R?mkC-t()0FTd-B zf5(5sIbcLP8z3jV&f{(vf@^S~kYg@ctEtc|^4>7FlC;YD<%VPv8F*euX4OW_PABe} zDaTXX77?;&i5bixev!Q~2RbQo@LY-ISa_$f%gGX_U9TPH9yk=IHW_OZFm`f_fl2qI z5JMB}iC^QmD$~2E|*+EhKsKvZ?Og}qZzMBuEYWyR*e*FFA@NL?Z}-P)))-*VKl z0)-2e}iTab!7|{r*vVfM=Qk zz|~=OuHzcUNx(~a;jf7?JvO16`}(o^zQf{0Z89bGgaE*YW?9kJp4vg8ZY&5vB`>%n zFM-pUcm=mfc8yj0R1h_|mYi2wlu&!ZM?(0@4Q{Gt3e?+8TCvai#P+chg`E_x7x_O< zpa;^h)AIcN#y;lZf|3Tn#O=_;Z7Rx_%{;Fq$RZLL6BuJ(PIeFLFRr4*`!)-P6*jmT zXphZ=Tc(u^n0e$x5p%qdpaZu~-AScp18(~n{M|?9_s?;LE@&@q*+pl4Nw@Poz3eNUb^a0+o}mVB8zaRv9vx+;Y}E^fQ- zD}+SWV^`S?v5IYFry3R9P|FKbBOa43HMvJ!=jvys|2R8dQMKVGxsu0K64eX)^a^QNiI)7*9fK6*8Ku>F}ku zC2t31kY7YT=SmQgpys)Zcy?UTc*xP?WSGVeK^HTP&UW*hvtzoILo-~+xh^H^l9TCX zsN27N9G8s%QKYcSOX9qmgF-8a+PR@OI?d>!lBRg$@o1mIGW?n8*4!l>-iNvo?Fz-- z5}oJ1D%!o_8ZH>BMq->ZoN`>1ZuI9C6VmVI6_-Yv*RDnJI)7dkb^ZAC;T(s?$L+}O zU3PW)^F3Nzotx6q=ab5gkXPJ7^zrQ{@9MA`ra%`X2wnKB9T0RvhXigSXFDMhLp+iF zu1rKFH3lLYL;}7x*gO689&uv|?G07h<#PTvG4DT!q5scZ$dB0`#H;Q|f`=N2LUQya zp^-fWWt+_?B$Q!uUr4hCQa~S?Ol~l&JV|d1w?F^Hs>J*GX^f)M4VcQpC|3+@Xn)cu zXhOASVz^4P_HMpm4I?_jc8xrs-i)@b%GNG{V7bOo2fj?Pb!g0M5ZB-(q+1b6wh=|1 z{_U_r0?K(zqNQUcwsa)ewA!cGMIiLfr4iNaooMmxg}kNvZQqBV%0VXAzF|&@O(-=O zGF-#n_Y%MbI83GVI(k&-Tk?NAQ$%NX79PreDnOPQz;2io!I?cL5l3)A+hUj|AFIJw zEzI1j3oB0gx@TR7SV|LCUW=HJm7Mchkes)5&Hc7_NqVne(qN%Zw{dl0!F8&YZ=5)^u!AC<-?%c)xB_;9KFV`N%a!E@to`YghxP#7^5CvX@yCi zq7HEC?}LkDP1owKsGm50A-U&ayjB-^#hL|K>!%A!*WzgRj`s6EEb?QY5o_fTD17;_ zg3RaJDN(nq6FLDpO#BUs+C9y}&6XRoEs?1_5ew5k#g`FV-G~Z;CD-q{aH_uZtU^dEan>`pLbT{dF@(hO0J0+~q=A&}bCfP;+NFfAG# z2P5__EUBrtAI9J7R=T^?dx+vt)$nI8NepP8kcStD;+R6@mFNtAbEBIgdB?wW6>F72 zL}PHQ6U1b!d)?GPV<%24=4fBxb&uTg$ zN1`a(DOVq*p-)EF7$@PpGy=0U_pDOzda#IQ@)B4;(7?}3p1@v7{;&jLEvns6PBUFp zlWvozii&6YbTd}SNA&2m>t1*JMsN(13=L!cB}OuC%d+|zI3-ogOn=5ByU8Wk=7%CW ztqW%@rXJ@qJy&Kw0!yWy#D8M^vaZ@76r%20vkO&7flx0>`-oLMz-+Arn_L89bD+DJ|5PlQ0ED!CgJd*~8 zdg#;9I4)4CUtUJW1{L&cnFfbf9-@4hBQ;vA%GLn2=qgF>8J+2wwa^p_z6U2;c>JCehi$`|H`WJZ2RQvVF9rs9u+Z-W|a4@Uwv-$J-!5y#yTZ+{0mvig+nfnY2@lwnqI z^Wr72>K$QXRVN8hHe+GMg>5Mb8j)eux8LG4F%I>YTwzVD(JVVVEX~eA^aX9zniY*l zXQpJ5tp&%HHs&VV$3j8a`PmAijlZ5rRCX3*N=;C9<4cu#A!U|cmIN9Y+J%lf-S^INY!z=07( z2E8qnU53fq2o7;!@1eB-r~P3B2&~j;$|pY^GF*z)UCB zyfjs>eR?qcZAP)jm5{M!E#vqULRarP)tH|itPvVA3Y6leY_KXjbuoPn_{NUBt_%(Wm=3buox99&A&A|T`8&{9Q~>Eq4K2_ zd2JfHveMaH>adMojkv-c#JY*2Hsr!=%)O`>FlMsc&Wu3@UBKIXfIr0KF88ImuIcw& z_E2NAGTPB%`p~!bZZ1+ATDZb_4xrL`fBMC9r663-WOM`cFkS?Q9#@9zcz}$vQ~IiY zO?o;aqvBP|=_0BE$D{7P<;!S2`j-6sw0%ZPvbc-&zQhwE@nuiT_vJTH#cKu5w+Y&R z;P}%pTG_*s5UPb}OM*N0+4hR0_J|33@p62)s^EZR;1wcojEu}5Qr`RdN6g`pM%Y4Tk z>30y#828Vyha5vpU&jg)UI;@sRR?O&U@U9p21fle`jD*PIFxCr(;|DwGfC z70nw7VseU(h!tADWaL$N&Ex&xM3~Ew(Dyp?@yz`juKfGv*D^r0MllGj*d)x|Xgiy_ z!p)LuX)|LzmVukFO%TQ*F?CJVqF6$~4QQP(L&JoOlS73Q-i7w!Tqk~Wz3+I{4V}fY zI-6ZSFEE_@(Sfg=O=FCh!dLBJd3*whN8@2yG zyv;xHwEtfLmIo0g+}_<>KUs}QIcP1U_)6|%mA=cjLL2{$QMD4PU|R!rw(~sXx7a9T zWA+oOA7O1idnz?TIf{@cpGIGqs?!^InT}b`6GRWQC{Od0X9PDD@{g}|tWB&LCFp3! znLy2#)G?Q!v-otso9mw+EUZs zZ{AJ;t^!Pr&U4)51770zhgh9@;S)HqaWntID#hWNv%I|*ope*w3k`04998)A>iNkT z0rn2jqqZU_&@J<`#w|@U(3qnr@fMSEEb9K{y!98Yg^c5#Mr(f(F&}rbo6b3O=-L#m zJ?`{QOjAu~h&(MWV6u}9PS>~j;8~^JjND4`rwG&jS#gt%>^6ZKWSc&H;~m=9WVxo6 z)Gn>9?b#(WMSZz*mL#AqAvlU-&wfnb#_FIT&N_A9$Q7lD$*og!`7F;-Qq>E$@^DJ~ zzOW-ITBzeZdzmKOhdjek;U%lKfk2jiaK6R{}fHzGtO6srdv8+ecI5JIJK{MtK_E5^d;r8 zT}dkfQM~N=yO2#7N8@< zBINJ69eEDWl5fy0l7Mse#%N#e_XoDeVAq)Y!S4aoc_-u+ND!z3~vIZMVXhKp(rt$qp^9}_c zyE-(}2&{#>tCM?mj-J4nCT1?_rDbH|>hAYj(fc;^S2%4q?Vt3VKVhXs^X+8*Vfj)X zoeB+2*_O(Ppx9pCkj$Pt`l$2s=)9detCLzirqb0Fh{X94gmvE6)!epn!>Z4ZYobnh zm-3xvnTsFxKHZe-)r2@&G-6io9=H^<{qE6Z25$lhxSd~p{6VYTMfI4+BE^$AE+6b$ zPI6l9S}q9)s;|J+cB_)nTLgpL71{x`n7k8Kc)5MthS620rkYJUAv;ZV{8qiYQL?f9 zYgl82)=`t=%&pJvsU)pSHi_#uqVjiq@Q)@1k<9v*F?0UnLMo#&hAL|3HuVwa4IH4u zqfEsnWdew>bx5(#R!1ZyNyWPk^>`vq!KN}q8vFEB_sm`@?MuUDiqy%jr3!V#+hA7R zE;{1ghh1sCFnl}2){s4};Ns-{jApq{)D>L{4t@1^Qp-kG_9}>`;({s&rm}22os{N6 zW=Fdh5y9c=RbBcB3mu{hK_4Ie-EwOP-A+K<+AXO;6|lan}1!ZrkEu)Y|H}@=Md2(SSkzQiTy(X(i=o=th%0q}7!T33G+%(9Nx z*@4Lcyf9~&F3v}0rMxUu+mv6Zu}wOpo~-a#B}H?)4&jX#JG9OaHh~%v7cN-Zu^W5J z5oEv<6WLd9&7%`;!EGWN8Y|K)r_8qy!~e1KSh$Lf5(4CrCcMwBo+~orhPAoLNwxb1H$TyGRy8jDa($CQBAH+)L z-$Iq8~HtxKCDwsxtBeu5Eyz1@SH!XMs) ze%bg0X-Z#2i>K*NY3$T2Qopxx09 zu`4Qjq>Q-B2AX#SC*<~T(%r<=334}cR4Ce~JXb;4s6_pupJazX2+vRl6pN1>9 zk<*?R_3=F51HFt~{)j#QJSX<&DEIFH?-(%3ErqC6Q~$N)ll%9!eDarIn26uaLX+PQ zv(N>SgwA@J|Bbc--0%MX{ff{2WpKfwg9bL+8@awiH+cF;7=h{ru` zDEB-U72<_##^)5tCo=^4Dx^(=>IJv!{!P11XxvjeQgAAd-*`puYoc_){e^}yxo{nX zZLF&HCGtDeJOjEW)PpO145PBBjLc#^+vfqMyQojgg4*a0aQ<=HGWRGbNA^9H7HCWP zSUZufzx8vQNTAoWGsw?HKb6h*OFbOZyE2_Pva2Ix*zm+)L6w{J`7&SL0?f}fYhslT zqAiK1oekH1<7_=Fjws7jUh1_$gP7>m>nKoi~wnn zx=Wtc(Hq>-fnCIwicOF(`lCiFF?kNMc^HbPA_1@eS%qYRQU`RN5rLy40jKvygl83< zn3D;SF7r@nXnqcXdQNE%8Hf1F1A>XH#A{pSu(seuL8X0xwXa@IkA=9dJBU4(qdr$| zTg^46m6phPAv!aEe&?>_I#f;zk>Pd%{PTG8x+sRq^7R`GXbV45!zI0`NW$5rzRJ?M`SN&eY)kk<2Iw~0Wm4r)1K+VU@gIU-C9_dves7DN&RxRpWjs4)J; zk|X*Zd#^TfTWjn+e*V`OFUs4IfU5_?58I{gUqFb8eaMC^XQ8j{cKsT|UicKzn-8R= zq1PF*yNOTCv{vMqgu0J+$s6OeUTp?66Q%@^)@oM6!wt`3xgnb02S#m$eZTF2oaH8MKCd9 zy>z~AZ(x>-52I!LoI}{y{ca0bkJY&-yLF}r#Vety)B;e;z{HW85_|uRyYR{Tw&Yx^E!&C{aXm&?lEK`O8BR$`zWSB3clGzMgT}S)0g5W*gf0WximrnM6u8 z*(^qo_)HKi0KZKpV`xy}sXXi*Qd`^}omwd}p7~CZ#l9ZFlA05JGuLD(3$0#0=Z|a< z2sfxW{nz#EZ_C@J>@O<4EH!pvFSl)f9b9tfdiGBIM*R7gne;!-5WIe_$Z)o@35Kg0 zucFh5u6wQQkYjn*xcyVNl?l4kUlu8Q_2VbAl9=X%K5z}Bv()x_h_jmvU>*39uimZN z08MpJXI6huf~a2zWlYv7s&d448eQ3*i(o|IXwnGb14K9BX~Aabgyj-?Q%zO_JWFqZ z#>Xq+g*;t|0qKFzwGass5Rugp#X!O5qJS8OVCY%6N)Qc*cT0#TMWAz{x=SnH3~m=? zqt}_IQJA8wvAuH%AQQOy@)+?>GLfaaf&|>`X@KlB#*%>MKIq+6klfyez%bw_wwb}t zrd#oy`un`O_;uJ9jcrxf?lk&!E@(7-b8|>Q*JZ2{0hlaX)p;+XC;eGjRRh;e2W(fMa5lhzC25i=YmwA?hx?zoKsl3vNGeI?;K@TOb<(F+K z?>w9^~W(J_^>#+l+0UEaY2x=31?FpYaDk8}B+7)sm67HSQSX&8ZHP3NEyJzI!# zn+*86X_G%xhr%7%(fEW{_`Cccy~-G%;DM?zbnhZUjjLI~b?$GI_TirlqJcl^`@#E@ zuGzY#l-FehGH2;vhTuU;i%I1E6u42DUi=4L7&tSx16^mx=w09MT6WY4Mbr)qAm(FS zlZm(<#I7{*Z)2>n^~H_QiGQ)^BwM}daf*2gfhl%MY(vpk-hDC9^2w&lMmfVu{t8aq z=3!5z`q9J*!Jz2lb%Y`_p*Y40PD<5q`T{9gO2$<=Ux-0^-|&EX8y9V^0zwVJJusgX zxFB`?UpY?m?~}fB{^R2@|03)Ai#+e*-e_{B`4}CZ-*wM9d6GBAqvBiM?6(Ey3aa`% zrq>0x)|HOjM7}ArLkTl4ZB6N2Vue8}b;LFZsEPKYY=r7ArwrM*d%G5>_qj<8SGs)` zSN6~~5Gmh$Yn$aPVi49vj;WS-0<-3`X%2@@c(85mvx#0;lrpo{9SPMPL0(u^6`2mV zOiT)#55A|Z&$%8EQQ>}Y!1whpzx?2vlqeFgO1`o(Q)(PG47j95x$BK^#_*$B;GvaA zeoC4x<*!@ZC^^QxIG*l}#%EeWkI3q{?u8~#^!a(H4%*F*S-9voROW|0?@`1yA4y?& z``!U5MlrC|SoB)R3+j6B$<+Rhx|r#E9)yG?HP?;J4W6dnfpcf4P*dOuuoR({qPXZf)RGya>vdhMz2Le@uJz0 zMqQvrq=r#h%)9yiY5S);-d>RT1oEC4zdFy^RCul74UN*eQJ8`8JF|!kaD7rd&PwZj zpUeOiheEICdV5?w|6ruCgV)(u* z>?Pye1S(_-2fMJYK2h~}RKJQW&4GJJJP%g5F!L?yiI!8;m>tjQFtK9sT*q7vTt21r zKwXHkWYj?Y*ALeF*3WWQzIoC_q<4dz`_vlQLic2Ivt(;sI#2zbV)96~Cur#CH$Y2N z9(wgpQ+hD1|LOGau6)ry_jOC35nQNDd?)%~SL6vzy#8x27)bvj@4XQ(P6Bubno!$^ zFl)q+-mF2vpG7@?6wPPh9SMl-e)ue8JYxYotHM19cH^HIhf14z^tvIOngl$wIgXeg zxl$GWvq<)jqOv>$`4*D+CiEkukpQ0fNh$c*nEFYqFg_Yaj`+q}58IQto%@p~<(q!DkxzWjv%j70}SmSjOk*;o+;I)gJy_S+QyYt#3~7nl9Fcp(2USO5C- z{b{cLE7SK6ll9-8zRtf)U#n5m|KRES7im2I&FK?t^}2*N!XRseslK}oH!@0jpL*mo zdW^&4-PmdaV;)dU#>Yo?jW5+b5`J?3vARhrUJ=JW2{|Fk=le|d2H$Xk#{SzG8{YSB zhrbL}aK>#P%4-)9O}?(_w+GMZMz`!-Y5CNZZFG6A7%g*dWuqvxX`*SxE!8!*(cSDh z-er8m_%laZb!uTjW^F6|+-(6Ffn)6n^7m4(6?OpO1xS9?sYg&g?#CZb!z;1u>=hAH z>E@4rw6T+{xR7`b*-V+_HykZ_dx|d*S1{4}N(jV=O%X%#V|UTVMusiD&Kl+`2QYP( zgr2|J{AKL4KyrnxR1Os~{;;&ulk|$}P6ZEfg1I|`u&-<8o1}^S;)Ri+g|($wuato} z{9Ro7g!)UalgI`y5x4MK)wfn;K2UM|;6};Jm#G&Ku$Z9|A6cy_^kF!AsZZnBBuj|# zgp5lC#(#Tk+i*ENAGO&>))z-sNYTk3>|h|#AgJ!oB}|Ce%sn=rY#`>UUf-UwtG6;1 zE05X^LE1gbJ{H2oOhzk~@no7@TIU=e^h2Tqjc%%w^H!Hc_lU<>xsuUI|BUk2n(;l( z&Z=s9hBnz1`UPey;OUIADWrcjQy=(k5ioLMyL8-+HiZ6JrJUV|p@j@j(QLwWM4PVB zW8$;e`z%29Rn6c-QoF-V*#N3%z9n{2btoC{MAhR550YZE8X{I3|&^yOxyW^_#7ZP@?qd`0c+OEiXM;wz}Us#x6r zY41v-no71csDKkj1O$N)MHCeg6&2B#I5e|>f`Br`7L-W@85)!!0s;zw2#ClSWgf(c zAp%d`_X@L*4oKAr*f)J?b`eM>f7cu zC<&6(MN5Nyfdiyp@mJ|{299=AWzSAJVg&!|tZx9~iVxCXrhPpy?f+oXm7psF5NJ$m)&(s+7t4#H z*Z^!OZ3OOCg9Gkn4RAN8FYe}GMMU|Jrjjflj}vHSyT=v8T0b1eZNJa?K_^I6vTQrt zc+k8czjdzI%=Rk%OvHUn?ejL_fvI;+32hC07pRX9AZ;8k zRmV;FGi2X%8(qyr2G3o3_9U^u+$n`v^m@(CwUdUbwvlgdOR>>a-KwF8ZM?Vp$4C+# zPPQD)i0Pft+NJHwe1rrGqVc_@sNId(JHnLTtR9zyR=KHA_7((DD>~U`mZemlOtFpX z?YE7+9n_|T=~gPeej+mru9wbIezjN>Hve)W^HU+g%0jZ!``(k&(?svY4Fc-@)Xny? z$LY^whLrfq?7N#wEqdZ4tRD|=v21(`A^MqJv_nG^zgy4xp+2I>cIG%pNQecGCQP+?psDPUON-@W4rBSgVSZV}?f|U}jcXd0 zB{0M6IJi@NSRYq~@D8!UN0L>NGI5)T3oAd9XEvrn)%4zFH#v=H%{Xd$+?bGs{j%Unw>XlP^bQEWYfL2xkJ`h!?pG&7z z&RU)t=rw;8XcXV-9k)-cH!L07+=QtqTjJCj=Ihx_)#xf9b`TkWES&NK^pDdRlGG`hE>HQRFav8?3ei#*Api_+{yQm zvBT=l1JyJ(h)*mPcKtKGjoRvSWT^ll<)hCkLB7)4T*q7&wII^fr?Y)#U-J7)X_cmX zpX8`)+djJTLFS4=vK_LUTnUC!U1sVh(zZ6dhxyc{^*qbWNALs>r=SlFjZylivnC3L z@mpreM0(%r4w^-F7g?p1*HFVTJ`*{6*u5N^ZHHgS3g?{i+CEVKO4em#F$*QZfGOis3N>8wgiotgJ5b6Jv&Y1H6lzL%Yqlpv{ohH4=E&;y5tE!HK)$&T4_ z!c{X|noEexjdRkgF#YklgUVfs%-al9=wX=TMBm0>ni1HJE1Xt~G?YudbI6Vp(vWY8?tu`4OP`hXQ(&T}l zOVvW$nOhlpZ#FD(ie&~X972iyPZAu~8QZ4x50;}IOJ6pTabVz57vb7}|O+^Yvt{i-$HEG|sndQ+>6_}9S+R0VP zT#8uct5uboHH>b4WPrGti0FdGAQ%HHuntpMc`>UMn&03_y}yuqpGMbQaEy)Xaay!u za^~mPGRPnw``VojTkwgDw<&&@_!p-5kb0xeWj-fOlkNSPU*f}q#HpB!R9gft>tyVaBCQr(u~4XdcwL8y zQPnD$jb3sjTd?`k8rfA=-6w~w=|%?*Ic8lIRhL1t9^mrL^u&F*#OaEELhN5x0D6)us@g}-XbJu z-vFsiiPYwbpxhJ$ig(;9<;NVKx`8f#%65OOSxTbI1;deZCOtNr>P=in-8`wDB{jg= zmC~KLdm$_{R2Ps>Hd+egs7(1?Co{&#O*7m)o@pQLm*!qV=u}opVbIY!ZcgX^ByF9K zZ<%nnA)!SIzzROJWCGcqgPr-E5k8lf`7ZUNI8p#7UlKH99;^E`s(V7p`ytO{fR_jg;I9VxgOb$iyBgDA2 z33|n>@TbqSk3^YIe%=``w03y&>35}@4Nvydp!v~O)#|QG8rbcb4J9aDMc;bU&fM9Y z#OXMD@3JM@%E9R%-YNzq08)(;wLj47<)ta6?U0@#@=S83ybzPS?d*E-?GeXpF5or* z-l*b$X7Cky$en`sV5OLpK2u$eX+@|WFUK@Bxu_{T;d9}8J|5cg^Vlp$-?*7Ll~=Z< zTwUM5wu$ZRjnZ8JPNnd`|BYw)R<`diApC#Pv;3haSA5OU{gC$gJC*S75_#X^?tUk* ztkh?KPrySii7WYpp)PYh?!E5M`iO2+Yz;ku{YZ`n*qJGcnmEh04E zh{Q6JG;cFQN1ig;=a)p@-(&4w^m_)z;rI`51w@)v)zr7jidMTBmgWW<1C2ev*ix4V z_&g!9VufrP*08wa1|RKeQczlpGa|0I#9y<0(Uj1680w(M#y9fTyhrJ{SQ*TshXL!r zJ@Kmq0RR7_&H1ms1FQ@+#y|8;zyt{dPNophnrn=@&_LoF)uq{4w9asS*|{t(Zupn0 zDa^iLZ#kWuj-{X2mENYX{shtx7y^$o_U+?6JPFSVop-K^aEewA%#=y_6cWhJWaq z1t#Elj^bSW!}e%QA@We>`BysUKhinQ7=`Lxho&)77y2YgVIz(o1|QKhi|e@sp`Q=` zyb%a5R)*IbJQl9kKz6U||0!_$pmNB=MMSQ{UEecW!nc>yvyS2!5VNK&G)> z8p#n=g>U%ev8%!Y_Iiw!$xb!}SlVnqYDvsl7y$o$6i|ks8=}ubrt1xQkNFu_JlgG4;O&YYNh@;QbN}>w z*A02MwhQ(b&&T3zEj*UsrkUiG#~Q;r|oql84{gTjA43?H)G3p{ITwWNzm{kqZ0_yqYILt0XV(>XTmPtEvFl z1QZm(_|Aei`1T6Fw=Tkr+C-x9es0zTv2NqnPQoR5ICCEf`e*xt&zOz&y ze?K4l?f6i0L?7hf*dd2OQIFd|IHnQCyu%WaZ1mBf(*|T`FjT0ILe6d?%T0h1 z;UO`2bgnoq&;P{wqUW1CcFZg7ob-KfUF$7p)}!I6xd}+%2^i=`5jeVl(-*k7B3s=z zcHs-#CT>)gpMEVr12v8~%plg7ChzI!I6Auj#*q$_{7qK~g?m>@z9XoV@Ta?8ymKUH z(O1l*Jv(dP1#6Ss#FEEgW8zcr@ec{EKYKLI=Zdu0w8JkSK1eQUle1MQWb>=TA{FR( zrPhMHGv?&5v#tG(VfQ1%P3Pt3_&gQ-Q8&FHRZQNxchUN%dwtA4CK$#mGP? z6+ZaQ*WNu1j*(v)Q#5bPMG)@3jO(na%e9(>PSaYTU&L=Ba4!XZlh=VQ|BhVqWt7Ti zwY+)SQYE0(uyuZwQPvZPBtxPKwtjr(@Y|T}V@9ew&N+u5Kg)=)_RGGfdBO<1@@IaH z**#jvoi~Kc38Rc#P-lV%6Fqj#`{AE6J z6j-+B7_iRyfw7BggmBo(K=~2>-0nGfo&xRlt%ohf_)qd?hn>IsNh(hahC$M1s(C!! zWxl%HiFn{IED!W{euRyi2oX4xNbtX zMreQ+MQ8}Z=DzsaD&!w7Kq^VW&bNUkRq@gLwIfC@9fD0raa`C1N+qbt=Lt-$$bEx z-zR?2F!T*xVrckTrt?qX_AbAy*vE~Xzdl;7Isjey>d`1wohTx~nSsS?F7w^OB0~&L zSt^N{zBS1^7Uh;u=1WOS)esweDqvH(6{Mn7PX5L%SosaR<4^MvzVZ|P1IPcr_13!n E3r-|#EC2ui From 744d45cf94e5eb7769122822d2f535c04320833f Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:10:53 -0400 Subject: [PATCH 03/10] update --- website/docs/tutorial/conversation-patterns.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/tutorial/conversation-patterns.ipynb b/website/docs/tutorial/conversation-patterns.ipynb index 926c92989651..a229561ee8e5 100644 --- a/website/docs/tutorial/conversation-patterns.ipynb +++ b/website/docs/tutorial/conversation-patterns.ipynb @@ -1569,7 +1569,7 @@ "The last speaker and the groupchat object are passed to the function. \n", "Commonly used variables from groupchat are `groupchat.messages` and `groupchat.agents`, which is the message history and the agents in the group chat respectively. You can access other attributes of the groupchat, such as `groupchat.allowed_speaker_transitions_dict` for pre-defined `allowed_speaker_transitions_dict`.\n", "\n", - "Heres is a simple example to build workflow for reasearch with customized speaker selection.\n", + "Heres is a simple example to build workflow for research with customized speaker selection.\n", "\n", "\n", "```{=mdx}\n", @@ -1664,7 +1664,7 @@ " # retrieve --(execution failed)--> retrieve\n", " return coder\n", " else:\n", - " # retrieve --(execution sucess)--> research\n", + " # retrieve --(execution success)--> research\n", " return scientist\n", " elif last_speaker == \"Scientist\":\n", " # research -> end\n", From c73de37557a36b6865a18db4c7900bde8c727250 Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:39:20 -0400 Subject: [PATCH 04/10] update --- website/docs/Research.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/website/docs/Research.md b/website/docs/Research.md index 3a78641e0fda..25c885f1d06d 100644 --- a/website/docs/Research.md +++ b/website/docs/Research.md @@ -74,8 +74,22 @@ For technical details, please check our technical report and research publicatio } ``` -* [StateFlow: Enhancing LLM Task-Solving through State-Driven Workflows]https://arxiv.org/abs/2403.11322. Yiran Wu, Tianwei Yue, Shaokun Zhang, Chi Wang, Qingyun Wu. ArXiv preprint arXiv:2403.11322 (2024). +* [AutoDefense: Multi-Agent LLM Defense against Jailbreak Attacks](https://arxiv.org/abs/2403.04783). Yifan Zeng, Yiran Wu, Xiao Zhang, Huazheng Wang, Qingyun Wu. ArXiv preprint arXiv:2403.04783 (2024). +```bibtex +@misc{zeng2024autodefense, + title={AutoDefense: Multi-Agent LLM Defense against Jailbreak Attacks}, + author={Yifan Zeng and Yiran Wu and Xiao Zhang and Huazheng Wang and Qingyun Wu}, + year={2024}, + eprint={2403.04783}, + archivePrefix={arXiv}, + primaryClass={cs.LG} +} +``` + +* [StateFlow: Enhancing LLM Task-Solving through State-Driven Workflows](https://arxiv.org/abs/2403.11322). Yiran Wu, Tianwei Yue, Shaokun Zhang, Chi Wang, Qingyun Wu. ArXiv preprint arXiv:2403.11322 (2024). + +```bibtex @misc{wu2024stateflow, title={StateFlow: Enhancing LLM Task-Solving through State-Driven Workflows}, author={Yiran Wu and Tianwei Yue and Shaokun Zhang and Chi Wang and Qingyun Wu}, @@ -84,3 +98,4 @@ For technical details, please check our technical report and research publicatio archivePrefix={arXiv}, primaryClass={cs.CL} } +``` From 12bf88cf65833294fc041d3b7facc59371066316 Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:04:15 -0400 Subject: [PATCH 05/10] update --- website/docs/topics/groupchat/_category_.json | 5 + .../customized_speaker_selection.ipynb | 522 ++++++++++++++++++ 2 files changed, 527 insertions(+) create mode 100644 website/docs/topics/groupchat/_category_.json create mode 100644 website/docs/topics/groupchat/customized_speaker_selection.ipynb diff --git a/website/docs/topics/groupchat/_category_.json b/website/docs/topics/groupchat/_category_.json new file mode 100644 index 000000000000..3bf8fc4b8b37 --- /dev/null +++ b/website/docs/topics/groupchat/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 5, + "label": "Using GroupChat", + "collapsible": true +} diff --git a/website/docs/topics/groupchat/customized_speaker_selection.ipynb b/website/docs/topics/groupchat/customized_speaker_selection.ipynb new file mode 100644 index 000000000000..8a138055c827 --- /dev/null +++ b/website/docs/topics/groupchat/customized_speaker_selection.ipynb @@ -0,0 +1,522 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Customize Speaker Selection\n", + "\n", + "In GroupChat, we can also customize the speaker selection by passing in a function to `speaker_selection_method`:\n", + "```python\n", + "def custom_speaker_selection_func(last_speaker, groupchat):\n", + " \"\"\"Define a customized speaker selection function.\n", + " A recommended way is to define a transition for each speaker in the groupchat.\n", + "\n", + " Parameters:\n", + " - last_speaker: Agent\n", + " The last speaker in the group chat.\n", + " - groupchat: GroupChat\n", + " The GroupChat object\n", + " Return:\n", + " Return one of the following:\n", + " 1. an `Agent` class, it must be one of the agents in the group chat.\n", + " 2. a string from ['auto', 'manual', 'random', 'round_robin'] to select a default method to use.\n", + " 3. None, which indicates the chat should be terminated.\n", + " \"\"\"\n", + " pass\n", + "\n", + "groupchat = autogen.GroupChat(\n", + " speaker_selection_method=custom_speaker_selection_func,\n", + " ...,\n", + ")\n", + "```\n", + "The last speaker and the groupchat object are passed to the function. \n", + "Commonly used variables from groupchat are `groupchat.messages` and `groupchat.agents`, which is the message history and the agents in the group chat respectively. You can access other attributes of the groupchat, such as `groupchat.allowed_speaker_transitions_dict` for pre-defined `allowed_speaker_transitions_dict`.\n", + "\n", + "Heres is a simple example to build workflow for research with customized speaker selection.\n", + "\n", + "\n", + "```{=mdx}\n", + "![group_chat](../../../blog/2024-02-29-StateFlow/img/sf_example_1.png)\n", + "```\n", + "\n", + "We define the following agents:\n", + "\n", + "- Initializer: Start the workflow by sending a task.\n", + "- Coder: Retrieve papers from the internet by writing code.\n", + "- Executor: Execute the code.\n", + "- Scientist: Read the papers and write a summary.\n", + "\n", + "In the Figure, we define a simple workflow for research with 4 states: Init, Retrieve, Reserach and End. Within each state, we will call different agents to perform the tasks.\n", + "\n", + "Init: We use the initializer to start the workflow.\n", + "Retrieve: We will first call the coder to write code and then call the executor to execute the code.\n", + "Research: We will call the scientist to read the papers and write a summary.\n", + "End: We will end the workflow." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import autogen\n", + "\n", + "config_list = autogen.config_list_from_json(\n", + " \"OAI_CONFIG_LIST\",\n", + " filter_dict={\n", + " \"model\": [\"gpt-4-1106-preview\"],\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gpt4_config = {\n", + " \"cache_seed\": 42, # change the cache_seed for different trials\n", + " \"temperature\": 0,\n", + " \"config_list\": config_list,\n", + " \"timeout\": 120,\n", + "}\n", + "\n", + "initializer = autogen.UserProxyAgent(\n", + " name=\"Init\",\n", + ")\n", + "\n", + "coder = autogen.AssistantAgent(\n", + " name=\"Retrieve_Action_1\",\n", + " llm_config=gpt4_config,\n", + " system_message=\"\"\"You are the Coder. Given a topic, write code to retrieve related papers from the arXiv API, print their title, authors, abstract, and link.\n", + "You write python/shell code to solve tasks. Wrap the code in a code block that specifies the script type. The user can't modify your code. So do not suggest incomplete code which requires others to modify. Don't use a code block if it's not intended to be executed by the executor.\n", + "Don't include multiple code blocks in one response. Do not ask others to copy and paste the result. Check the execution result returned by the executor.\n", + "If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.\n", + "\"\"\",\n", + ")\n", + "executor = autogen.UserProxyAgent(\n", + " name=\"Retrieve_Action_2\",\n", + " system_message=\"Executor. Execute the code written by the Coder and report the result.\",\n", + " human_input_mode=\"NEVER\",\n", + " code_execution_config={\n", + " \"last_n_messages\": 3,\n", + " \"work_dir\": \"paper\",\n", + " \"use_docker\": False,\n", + " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n", + ")\n", + "scientist = autogen.AssistantAgent(\n", + " name=\"Research_Action_1\",\n", + " llm_config=gpt4_config,\n", + " system_message=\"\"\"You are the Scientist. Please categorize papers after seeing their abstracts printed and create a markdown table with Domain, Title, Authors, Summary and Link\"\"\",\n", + ")\n", + "\n", + "\n", + "def state_transition(last_speaker, groupchat):\n", + " messages = groupchat.messages\n", + "\n", + " if last_speaker is initializer:\n", + " # init -> retrieve\n", + " return coder\n", + " elif last_speaker is coder:\n", + " # retrieve: action 1 -> action 2\n", + " return executor\n", + " elif last_speaker is executor:\n", + " if messages[-1][\"content\"] == \"exitcode: 1\":\n", + " # retrieve --(execution failed)--> retrieve\n", + " return coder\n", + " else:\n", + " # retrieve --(execution success)--> research\n", + " return scientist\n", + " elif last_speaker == \"Scientist\":\n", + " # research -> end\n", + " return None\n", + "\n", + "\n", + "groupchat = autogen.GroupChat(\n", + " agents=[initializer, coder, executor, scientist],\n", + " messages=[],\n", + " max_round=20,\n", + " speaker_selection_method=state_transition,\n", + ")\n", + "manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=gpt4_config)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mInit\u001b[0m (to chat_manager):\n", + "\n", + "Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mRetrieve_Action_1\u001b[0m (to chat_manager):\n", + "\n", + "To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\n", + "\n", + "```python\n", + "import requests\n", + "from datetime import datetime, timedelta\n", + "import feedparser\n", + "\n", + "# Define the base URL for the arXiv API\n", + "ARXIV_API_URL = 'http://export.arxiv.org/api/query?'\n", + "\n", + "# Define the search parameters\n", + "search_query = 'all:\"LLM applications\"'\n", + "start_date = (datetime.now() - timedelta(days=7)).strftime('%Y%m%d%H%M%S')\n", + "end_date = datetime.now().strftime('%Y%m%d%H%M%S')\n", + "start = 0\n", + "max_results = 10\n", + "sort_by = 'submittedDate'\n", + "sort_order = 'descending'\n", + "\n", + "# Construct the query\n", + "query = f'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}'\n", + "\n", + "# Send the request to the arXiv API\n", + "response = requests.get(ARXIV_API_URL + query)\n", + "\n", + "# Parse the response using feedparser\n", + "feed = feedparser.parse(response.content)\n", + "\n", + "# Print the title, authors, abstract, and link of each paper\n", + "for entry in feed.entries:\n", + " print(\"Title:\", entry.title)\n", + " print(\"Authors:\", ', '.join(author.name for author in entry.authors))\n", + " print(\"Abstract:\", entry.summary)\n", + " print(\"Link:\", entry.link)\n", + " print(\"\\n\")\n", + "\n", + "# Check if we have at least 5 papers, if not, adjust the search or notify\n", + "if len(feed.entries) < 5:\n", + " print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\n", + "```\n", + "\n", + "This script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", + "\u001b[33mRetrieve_Action_2\u001b[0m (to chat_manager):\n", + "\n", + "exitcode: 0 (execution succeeded)\n", + "Code output: \n", + "Title: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\n", + "Authors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\n", + "Abstract: Prompt, recognized as crucial intellectual property, enables large language\n", + "models (LLMs) to perform specific tasks without the need of fine-tuning,\n", + "underscoring their escalating importance. With the rise of prompt-based\n", + "services, such as prompt marketplaces and LLM applications, providers often\n", + "display prompts' capabilities through input-output examples to attract users.\n", + "However, this paradigm raises a pivotal security concern: does the exposure of\n", + "input-output pairs pose the risk of potential prompt leakage, infringing on the\n", + "intellectual property rights of the developers? To our knowledge, this problem\n", + "still has not been comprehensively explored yet. To remedy this gap, in this\n", + "paper, we perform the first in depth exploration and propose a novel attack\n", + "framework for reverse-stealing prompts against commercial LLMs, namely PRSA.\n", + "The main idea of PRSA is that by analyzing the critical features of the\n", + "input-output pairs, we mimic and gradually infer (steal) the target prompts. In\n", + "detail, PRSA mainly consists of two key phases: prompt mutation and prompt\n", + "pruning. In the mutation phase, we propose a prompt attention algorithm based\n", + "on differential feedback to capture these critical features for effectively\n", + "inferring the target prompts. In the prompt pruning phase, we identify and mask\n", + "the words dependent on specific inputs, enabling the prompts to accommodate\n", + "diverse inputs for generalization. Through extensive evaluation, we verify that\n", + "PRSA poses a severe threat in real world scenarios. We have reported these\n", + "findings to prompt service providers and actively collaborate with them to take\n", + "protective measures for prompt copyright.\n", + "Link: http://arxiv.org/abs/2402.19200v1\n", + "\n", + "\n", + "Title: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\n", + " for Values and Opinions in Large Language Models\n", + "Authors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\n", + "Abstract: Much recent work seeks to evaluate values and opinions in large language\n", + "models (LLMs) using multiple-choice surveys and questionnaires. Most of this\n", + "work is motivated by concerns around real-world LLM applications. For example,\n", + "politically-biased LLMs may subtly influence society when they are used by\n", + "millions of people. Such real-world concerns, however, stand in stark contrast\n", + "to the artificiality of current evaluations: real users do not typically ask\n", + "LLMs survey questions. Motivated by this discrepancy, we challenge the\n", + "prevailing constrained evaluation paradigm for values and opinions in LLMs and\n", + "explore more realistic unconstrained evaluations. As a case study, we focus on\n", + "the popular Political Compass Test (PCT). In a systematic review, we find that\n", + "most prior work using the PCT forces models to comply with the PCT's\n", + "multiple-choice format. We show that models give substantively different\n", + "answers when not forced; that answers change depending on how models are\n", + "forced; and that answers lack paraphrase robustness. Then, we demonstrate that\n", + "models give different answers yet again in a more realistic open-ended answer\n", + "setting. We distill these findings into recommendations and open challenges in\n", + "evaluating values and opinions in LLMs.\n", + "Link: http://arxiv.org/abs/2402.16786v1\n", + "\n", + "\n", + "Title: Large Language Models as Urban Residents: An LLM Agent Framework for\n", + " Personal Mobility Generation\n", + "Authors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\n", + "Abstract: This paper introduces a novel approach using Large Language Models (LLMs)\n", + "integrated into an agent framework for flexible and efficient personal mobility\n", + "generation. LLMs overcome the limitations of previous models by efficiently\n", + "processing semantic data and offering versatility in modeling various tasks.\n", + "Our approach addresses the critical need to align LLMs with real-world urban\n", + "mobility data, focusing on three research questions: aligning LLMs with rich\n", + "activity data, developing reliable activity generation strategies, and\n", + "exploring LLM applications in urban mobility. The key technical contribution is\n", + "a novel LLM agent framework that accounts for individual activity patterns and\n", + "motivations, including a self-consistency approach to align LLMs with\n", + "real-world activity data and a retrieval-augmented strategy for interpretable\n", + "activity generation. In experimental studies, comprehensive validation is\n", + "performed using real-world data. This research marks the pioneering work of\n", + "designing an LLM agent framework for activity generation based on real-world\n", + "human activity data, offering a promising tool for urban mobility analysis.\n", + "Link: http://arxiv.org/abs/2402.14744v1\n", + "\n", + "\n", + "Title: An Evaluation of Large Language Models in Bioinformatics Research\n", + "Authors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\n", + "Abstract: Large language models (LLMs) such as ChatGPT have gained considerable\n", + "interest across diverse research communities. Their notable ability for text\n", + "completion and generation has inaugurated a novel paradigm for\n", + "language-interfaced problem solving. However, the potential and efficacy of\n", + "these models in bioinformatics remain incompletely explored. In this work, we\n", + "study the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\n", + "These tasks include the identification of potential coding regions, extraction\n", + "of named entities for genes and proteins, detection of antimicrobial and\n", + "anti-cancer peptides, molecular optimization, and resolution of educational\n", + "bioinformatics problems. Our findings indicate that, given appropriate prompts,\n", + "LLMs like GPT variants can successfully handle most of these tasks. In\n", + "addition, we provide a thorough analysis of their limitations in the context of\n", + "complicated bioinformatics tasks. In conclusion, we believe that this work can\n", + "provide new perspectives and motivate future research in the field of LLMs\n", + "applications, AI for Science and bioinformatics.\n", + "Link: http://arxiv.org/abs/2402.13714v1\n", + "\n", + "\n", + "Title: Privacy-Preserving Instructions for Aligning Large Language Models\n", + "Authors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\n", + "Abstract: Service providers of large language model (LLM) applications collect user\n", + "instructions in the wild and use them in further aligning LLMs with users'\n", + "intentions. These instructions, which potentially contain sensitive\n", + "information, are annotated by human workers in the process. This poses a new\n", + "privacy risk not addressed by the typical private optimization. To this end, we\n", + "propose using synthetic instructions to replace real instructions in data\n", + "annotation and model fine-tuning. Formal differential privacy is guaranteed by\n", + "generating those synthetic instructions using privately fine-tuned generators.\n", + "Crucial in achieving the desired utility is our novel filtering algorithm that\n", + "matches the distribution of the synthetic instructions to that of the real\n", + "ones. In both supervised fine-tuning and reinforcement learning from human\n", + "feedback, our extensive experiments demonstrate the high utility of the final\n", + "set of synthetic instructions by showing comparable results to real\n", + "instructions. In supervised fine-tuning, models trained with private synthetic\n", + "instructions outperform leading open-source models such as Vicuna.\n", + "Link: http://arxiv.org/abs/2402.13659v1\n", + "\n", + "\n", + "Title: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\n", + " Conversations with the Tabletop Robot Haru\n", + "Authors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\n", + "Abstract: Social robots aim to establish long-term bonds with humans through engaging\n", + "conversation. However, traditional conversational approaches, reliant on\n", + "scripted interactions, often fall short in maintaining engaging conversations.\n", + "This paper addresses this limitation by integrating large language models\n", + "(LLMs) into social robots to achieve more dynamic and expressive conversations.\n", + "We introduce a fully-automated conversation system that leverages LLMs to\n", + "generate robot responses with expressive behaviors, congruent with the robot's\n", + "personality. We incorporate robot behavior with two modalities: 1) a\n", + "text-to-speech (TTS) engine capable of various delivery styles, and 2) a\n", + "library of physical actions for the robot. We develop a custom,\n", + "state-of-the-art emotion recognition model to dynamically select the robot's\n", + "tone of voice and utilize emojis from LLM output as cues for generating robot\n", + "actions. A demo of our system is available here. To illuminate design and\n", + "implementation issues, we conduct a pilot study where volunteers chat with a\n", + "social robot using our proposed system, and we analyze their feedback,\n", + "conducting a rigorous error analysis of chat transcripts. Feedback was\n", + "overwhelmingly positive, with participants commenting on the robot's empathy,\n", + "helpfulness, naturalness, and entertainment. Most negative feedback was due to\n", + "automatic speech recognition (ASR) errors which had limited impact on\n", + "conversations. However, we observed a small class of errors, such as the LLM\n", + "repeating itself or hallucinating fictitious information and human responses,\n", + "that have the potential to derail conversations, raising important issues for\n", + "LLM application.\n", + "Link: http://arxiv.org/abs/2402.11571v1\n", + "\n", + "\n", + "Title: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\n", + " in Ophthalmology and LLM-based evaluation using GPT-4\n", + "Authors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\n", + "Abstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\n", + "experts, for the evaluation of responses to ophthalmology-related patient\n", + "queries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\n", + "questions and paired answers were created by ophthalmologists to represent\n", + "commonly asked patient questions, divided into fine-tuning (368; 92%), and\n", + "testing (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\n", + "LLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\n", + "additional 8 glaucoma QnA pairs were included. 200 responses to the testing\n", + "dataset were generated by 5 fine-tuned LLMs for evaluation. A customized\n", + "clinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\n", + "clinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\n", + "evaluation was then compared against ranking by 5 clinicians for clinical\n", + "alignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\n", + "(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\n", + "LLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\n", + "evaluation demonstrated significant agreement with human clinician rankings,\n", + "with Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\n", + "respectively; while correlation based on Cohen Kappa was more modest at 0.50.\n", + "Notably, qualitative analysis and the glaucoma sub-analysis revealed clinical\n", + "inaccuracies in the LLM-generated responses, which were appropriately\n", + "identified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\n", + "of GPT-4 evaluation highlighted its potential to streamline the clinical\n", + "evaluation of LLM chatbot responses to healthcare-related queries. By\n", + "complementing the existing clinician-dependent manual grading, this efficient\n", + "and automated evaluation could assist the validation of future developments in\n", + "LLM applications for healthcare.\n", + "Link: http://arxiv.org/abs/2402.10083v1\n", + "\n", + "\n", + "Title: Unmemorization in Large Language Models via Self-Distillation and\n", + " Deliberate Imagination\n", + "Authors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\n", + "Abstract: While displaying impressive generation capabilities across many tasks, Large\n", + "Language Models (LLMs) still struggle with crucial issues of privacy violation\n", + "and unwanted exposure of sensitive data. This raises an essential question: how\n", + "should we prevent such undesired behavior of LLMs while maintaining their\n", + "strong generation and natural language understanding (NLU) capabilities? In\n", + "this work, we introduce a novel approach termed deliberate imagination in the\n", + "context of LLM unlearning. Instead of trying to forget memorized data, we\n", + "employ a self-distillation framework, guiding LLMs to deliberately imagine\n", + "alternative scenarios. As demonstrated in a wide range of experiments, the\n", + "proposed method not only effectively unlearns targeted text but also preserves\n", + "the LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\n", + "Our results demonstrate the usefulness of this approach across different models\n", + "and sizes, and also with parameter-efficient fine-tuning, offering a novel\n", + "pathway to addressing the challenges with private and sensitive data in LLM\n", + "applications.\n", + "Link: http://arxiv.org/abs/2402.10052v1\n", + "\n", + "\n", + "Title: Anchor-based Large Language Models\n", + "Authors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\n", + "Abstract: Large language models (LLMs) predominantly employ decoder-only transformer\n", + "architectures, necessitating the retention of keys/values information for\n", + "historical tokens to provide contextual information and avoid redundant\n", + "computation. However, the substantial size and parameter volume of these LLMs\n", + "require massive GPU memory. This memory demand increases with the length of the\n", + "input text, leading to an urgent need for more efficient methods of information\n", + "storage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\n", + "utilize an innovative anchor-based self-attention network (AnSAN) and also an\n", + "anchor-based inference strategy. This approach enables LLMs to compress\n", + "sequence information into an anchor token, reducing the keys/values cache and\n", + "enhancing inference efficiency. Experiments on question-answering benchmarks\n", + "reveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\n", + "keys/values cache reduction and up to 3.5 times faster inference. Despite a\n", + "minor compromise in accuracy, the substantial enhancements of AnLLMs employing\n", + "the AnSAN technique in resource utilization and computational efficiency\n", + "underscore their potential for practical LLM applications.\n", + "Link: http://arxiv.org/abs/2402.07616v2\n", + "\n", + "\n", + "Title: T-RAG: Lessons from the LLM Trenches\n", + "Authors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\n", + "Abstract: Large Language Models (LLM) have shown remarkable language capabilities\n", + "fueling attempts to integrate them into applications across a wide range of\n", + "domains. An important application area is question answering over private\n", + "enterprise documents where the main considerations are data security, which\n", + "necessitates applications that can be deployed on-prem, limited computational\n", + "resources and the need for a robust application that correctly responds to\n", + "queries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\n", + "framework for building LLM-based applications. While building a RAG is\n", + "relatively straightforward, making it robust and a reliable application\n", + "requires extensive customization and relatively deep knowledge of the\n", + "application domain. We share our experiences building and deploying an LLM\n", + "application for question answering over private organizational documents. Our\n", + "application combines the use of RAG with a finetuned open-source LLM.\n", + "Additionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\n", + "to represent entity hierarchies within the organization. This is used to\n", + "generate a textual description to augment the context when responding to user\n", + "queries pertaining to entities within the organization's hierarchy. Our\n", + "evaluations show that this combination performs better than a simple RAG or\n", + "finetuning implementation. Finally, we share some lessons learned based on our\n", + "experiences building an LLM application for real-world use.\n", + "Link: http://arxiv.org/abs/2402.07483v1\n", + "\n", + "\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mResearch_Action_1\u001b[0m (to chat_manager):\n", + "\n", + "Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\n", + "\n", + "| Domain | Title | Authors | Summary | Link |\n", + "|--------|-------|---------|---------|------|\n", + "| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\n", + "| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\n", + "| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\n", + "| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\n", + "| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\n", + "| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\n", + "| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\n", + "| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\n", + "| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\n", + "| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\n", + "\n", + "These papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + }, + { + "data": { + "text/plain": [ + "ChatResult(chat_id=None, chat_history=[{'content': 'Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.', 'role': 'assistant'}, {'content': 'To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\\n\\n```python\\nimport requests\\nfrom datetime import datetime, timedelta\\nimport feedparser\\n\\n# Define the base URL for the arXiv API\\nARXIV_API_URL = \\'http://export.arxiv.org/api/query?\\'\\n\\n# Define the search parameters\\nsearch_query = \\'all:\"LLM applications\"\\'\\nstart_date = (datetime.now() - timedelta(days=7)).strftime(\\'%Y%m%d%H%M%S\\')\\nend_date = datetime.now().strftime(\\'%Y%m%d%H%M%S\\')\\nstart = 0\\nmax_results = 10\\nsort_by = \\'submittedDate\\'\\nsort_order = \\'descending\\'\\n\\n# Construct the query\\nquery = f\\'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}\\'\\n\\n# Send the request to the arXiv API\\nresponse = requests.get(ARXIV_API_URL + query)\\n\\n# Parse the response using feedparser\\nfeed = feedparser.parse(response.content)\\n\\n# Print the title, authors, abstract, and link of each paper\\nfor entry in feed.entries:\\n print(\"Title:\", entry.title)\\n print(\"Authors:\", \\', \\'.join(author.name for author in entry.authors))\\n print(\"Abstract:\", entry.summary)\\n print(\"Link:\", entry.link)\\n print(\"\\\\n\")\\n\\n# Check if we have at least 5 papers, if not, adjust the search or notify\\nif len(feed.entries) < 5:\\n print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\\n```\\n\\nThis script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.', 'name': 'Retrieve_Action_1', 'role': 'user'}, {'content': \"exitcode: 0 (execution succeeded)\\nCode output: \\nTitle: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\\nAuthors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\\nAbstract: Prompt, recognized as crucial intellectual property, enables large language\\nmodels (LLMs) to perform specific tasks without the need of fine-tuning,\\nunderscoring their escalating importance. With the rise of prompt-based\\nservices, such as prompt marketplaces and LLM applications, providers often\\ndisplay prompts' capabilities through input-output examples to attract users.\\nHowever, this paradigm raises a pivotal security concern: does the exposure of\\ninput-output pairs pose the risk of potential prompt leakage, infringing on the\\nintellectual property rights of the developers? To our knowledge, this problem\\nstill has not been comprehensively explored yet. To remedy this gap, in this\\npaper, we perform the first in depth exploration and propose a novel attack\\nframework for reverse-stealing prompts against commercial LLMs, namely PRSA.\\nThe main idea of PRSA is that by analyzing the critical features of the\\ninput-output pairs, we mimic and gradually infer (steal) the target prompts. In\\ndetail, PRSA mainly consists of two key phases: prompt mutation and prompt\\npruning. In the mutation phase, we propose a prompt attention algorithm based\\non differential feedback to capture these critical features for effectively\\ninferring the target prompts. In the prompt pruning phase, we identify and mask\\nthe words dependent on specific inputs, enabling the prompts to accommodate\\ndiverse inputs for generalization. Through extensive evaluation, we verify that\\nPRSA poses a severe threat in real world scenarios. We have reported these\\nfindings to prompt service providers and actively collaborate with them to take\\nprotective measures for prompt copyright.\\nLink: http://arxiv.org/abs/2402.19200v1\\n\\n\\nTitle: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\\n for Values and Opinions in Large Language Models\\nAuthors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\\nAbstract: Much recent work seeks to evaluate values and opinions in large language\\nmodels (LLMs) using multiple-choice surveys and questionnaires. Most of this\\nwork is motivated by concerns around real-world LLM applications. For example,\\npolitically-biased LLMs may subtly influence society when they are used by\\nmillions of people. Such real-world concerns, however, stand in stark contrast\\nto the artificiality of current evaluations: real users do not typically ask\\nLLMs survey questions. Motivated by this discrepancy, we challenge the\\nprevailing constrained evaluation paradigm for values and opinions in LLMs and\\nexplore more realistic unconstrained evaluations. As a case study, we focus on\\nthe popular Political Compass Test (PCT). In a systematic review, we find that\\nmost prior work using the PCT forces models to comply with the PCT's\\nmultiple-choice format. We show that models give substantively different\\nanswers when not forced; that answers change depending on how models are\\nforced; and that answers lack paraphrase robustness. Then, we demonstrate that\\nmodels give different answers yet again in a more realistic open-ended answer\\nsetting. We distill these findings into recommendations and open challenges in\\nevaluating values and opinions in LLMs.\\nLink: http://arxiv.org/abs/2402.16786v1\\n\\n\\nTitle: Large Language Models as Urban Residents: An LLM Agent Framework for\\n Personal Mobility Generation\\nAuthors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\\nAbstract: This paper introduces a novel approach using Large Language Models (LLMs)\\nintegrated into an agent framework for flexible and efficient personal mobility\\ngeneration. LLMs overcome the limitations of previous models by efficiently\\nprocessing semantic data and offering versatility in modeling various tasks.\\nOur approach addresses the critical need to align LLMs with real-world urban\\nmobility data, focusing on three research questions: aligning LLMs with rich\\nactivity data, developing reliable activity generation strategies, and\\nexploring LLM applications in urban mobility. The key technical contribution is\\na novel LLM agent framework that accounts for individual activity patterns and\\nmotivations, including a self-consistency approach to align LLMs with\\nreal-world activity data and a retrieval-augmented strategy for interpretable\\nactivity generation. In experimental studies, comprehensive validation is\\nperformed using real-world data. This research marks the pioneering work of\\ndesigning an LLM agent framework for activity generation based on real-world\\nhuman activity data, offering a promising tool for urban mobility analysis.\\nLink: http://arxiv.org/abs/2402.14744v1\\n\\n\\nTitle: An Evaluation of Large Language Models in Bioinformatics Research\\nAuthors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\\nAbstract: Large language models (LLMs) such as ChatGPT have gained considerable\\ninterest across diverse research communities. Their notable ability for text\\ncompletion and generation has inaugurated a novel paradigm for\\nlanguage-interfaced problem solving. However, the potential and efficacy of\\nthese models in bioinformatics remain incompletely explored. In this work, we\\nstudy the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\\nThese tasks include the identification of potential coding regions, extraction\\nof named entities for genes and proteins, detection of antimicrobial and\\nanti-cancer peptides, molecular optimization, and resolution of educational\\nbioinformatics problems. Our findings indicate that, given appropriate prompts,\\nLLMs like GPT variants can successfully handle most of these tasks. In\\naddition, we provide a thorough analysis of their limitations in the context of\\ncomplicated bioinformatics tasks. In conclusion, we believe that this work can\\nprovide new perspectives and motivate future research in the field of LLMs\\napplications, AI for Science and bioinformatics.\\nLink: http://arxiv.org/abs/2402.13714v1\\n\\n\\nTitle: Privacy-Preserving Instructions for Aligning Large Language Models\\nAuthors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\\nAbstract: Service providers of large language model (LLM) applications collect user\\ninstructions in the wild and use them in further aligning LLMs with users'\\nintentions. These instructions, which potentially contain sensitive\\ninformation, are annotated by human workers in the process. This poses a new\\nprivacy risk not addressed by the typical private optimization. To this end, we\\npropose using synthetic instructions to replace real instructions in data\\nannotation and model fine-tuning. Formal differential privacy is guaranteed by\\ngenerating those synthetic instructions using privately fine-tuned generators.\\nCrucial in achieving the desired utility is our novel filtering algorithm that\\nmatches the distribution of the synthetic instructions to that of the real\\nones. In both supervised fine-tuning and reinforcement learning from human\\nfeedback, our extensive experiments demonstrate the high utility of the final\\nset of synthetic instructions by showing comparable results to real\\ninstructions. In supervised fine-tuning, models trained with private synthetic\\ninstructions outperform leading open-source models such as Vicuna.\\nLink: http://arxiv.org/abs/2402.13659v1\\n\\n\\nTitle: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\\n Conversations with the Tabletop Robot Haru\\nAuthors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\\nAbstract: Social robots aim to establish long-term bonds with humans through engaging\\nconversation. However, traditional conversational approaches, reliant on\\nscripted interactions, often fall short in maintaining engaging conversations.\\nThis paper addresses this limitation by integrating large language models\\n(LLMs) into social robots to achieve more dynamic and expressive conversations.\\nWe introduce a fully-automated conversation system that leverages LLMs to\\ngenerate robot responses with expressive behaviors, congruent with the robot's\\npersonality. We incorporate robot behavior with two modalities: 1) a\\ntext-to-speech (TTS) engine capable of various delivery styles, and 2) a\\nlibrary of physical actions for the robot. We develop a custom,\\nstate-of-the-art emotion recognition model to dynamically select the robot's\\ntone of voice and utilize emojis from LLM output as cues for generating robot\\nactions. A demo of our system is available here. To illuminate design and\\nimplementation issues, we conduct a pilot study where volunteers chat with a\\nsocial robot using our proposed system, and we analyze their feedback,\\nconducting a rigorous error analysis of chat transcripts. Feedback was\\noverwhelmingly positive, with participants commenting on the robot's empathy,\\nhelpfulness, naturalness, and entertainment. Most negative feedback was due to\\nautomatic speech recognition (ASR) errors which had limited impact on\\nconversations. However, we observed a small class of errors, such as the LLM\\nrepeating itself or hallucinating fictitious information and human responses,\\nthat have the potential to derail conversations, raising important issues for\\nLLM application.\\nLink: http://arxiv.org/abs/2402.11571v1\\n\\n\\nTitle: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\\n in Ophthalmology and LLM-based evaluation using GPT-4\\nAuthors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\\nAbstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\\nexperts, for the evaluation of responses to ophthalmology-related patient\\nqueries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\\nquestions and paired answers were created by ophthalmologists to represent\\ncommonly asked patient questions, divided into fine-tuning (368; 92%), and\\ntesting (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\\nLLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\\nadditional 8 glaucoma QnA pairs were included. 200 responses to the testing\\ndataset were generated by 5 fine-tuned LLMs for evaluation. A customized\\nclinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\\nclinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\\nevaluation was then compared against ranking by 5 clinicians for clinical\\nalignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\\n(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\\nLLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\\nevaluation demonstrated significant agreement with human clinician rankings,\\nwith Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\\nrespectively; while correlation based on Cohen Kappa was more modest at 0.50.\\nNotably, qualitative analysis and the glaucoma sub-analysis revealed clinical\\ninaccuracies in the LLM-generated responses, which were appropriately\\nidentified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\\nof GPT-4 evaluation highlighted its potential to streamline the clinical\\nevaluation of LLM chatbot responses to healthcare-related queries. By\\ncomplementing the existing clinician-dependent manual grading, this efficient\\nand automated evaluation could assist the validation of future developments in\\nLLM applications for healthcare.\\nLink: http://arxiv.org/abs/2402.10083v1\\n\\n\\nTitle: Unmemorization in Large Language Models via Self-Distillation and\\n Deliberate Imagination\\nAuthors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\\nAbstract: While displaying impressive generation capabilities across many tasks, Large\\nLanguage Models (LLMs) still struggle with crucial issues of privacy violation\\nand unwanted exposure of sensitive data. This raises an essential question: how\\nshould we prevent such undesired behavior of LLMs while maintaining their\\nstrong generation and natural language understanding (NLU) capabilities? In\\nthis work, we introduce a novel approach termed deliberate imagination in the\\ncontext of LLM unlearning. Instead of trying to forget memorized data, we\\nemploy a self-distillation framework, guiding LLMs to deliberately imagine\\nalternative scenarios. As demonstrated in a wide range of experiments, the\\nproposed method not only effectively unlearns targeted text but also preserves\\nthe LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\\nOur results demonstrate the usefulness of this approach across different models\\nand sizes, and also with parameter-efficient fine-tuning, offering a novel\\npathway to addressing the challenges with private and sensitive data in LLM\\napplications.\\nLink: http://arxiv.org/abs/2402.10052v1\\n\\n\\nTitle: Anchor-based Large Language Models\\nAuthors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\\nAbstract: Large language models (LLMs) predominantly employ decoder-only transformer\\narchitectures, necessitating the retention of keys/values information for\\nhistorical tokens to provide contextual information and avoid redundant\\ncomputation. However, the substantial size and parameter volume of these LLMs\\nrequire massive GPU memory. This memory demand increases with the length of the\\ninput text, leading to an urgent need for more efficient methods of information\\nstorage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\\nutilize an innovative anchor-based self-attention network (AnSAN) and also an\\nanchor-based inference strategy. This approach enables LLMs to compress\\nsequence information into an anchor token, reducing the keys/values cache and\\nenhancing inference efficiency. Experiments on question-answering benchmarks\\nreveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\\nkeys/values cache reduction and up to 3.5 times faster inference. Despite a\\nminor compromise in accuracy, the substantial enhancements of AnLLMs employing\\nthe AnSAN technique in resource utilization and computational efficiency\\nunderscore their potential for practical LLM applications.\\nLink: http://arxiv.org/abs/2402.07616v2\\n\\n\\nTitle: T-RAG: Lessons from the LLM Trenches\\nAuthors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\\nAbstract: Large Language Models (LLM) have shown remarkable language capabilities\\nfueling attempts to integrate them into applications across a wide range of\\ndomains. An important application area is question answering over private\\nenterprise documents where the main considerations are data security, which\\nnecessitates applications that can be deployed on-prem, limited computational\\nresources and the need for a robust application that correctly responds to\\nqueries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\\nframework for building LLM-based applications. While building a RAG is\\nrelatively straightforward, making it robust and a reliable application\\nrequires extensive customization and relatively deep knowledge of the\\napplication domain. We share our experiences building and deploying an LLM\\napplication for question answering over private organizational documents. Our\\napplication combines the use of RAG with a finetuned open-source LLM.\\nAdditionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\\nto represent entity hierarchies within the organization. This is used to\\ngenerate a textual description to augment the context when responding to user\\nqueries pertaining to entities within the organization's hierarchy. Our\\nevaluations show that this combination performs better than a simple RAG or\\nfinetuning implementation. Finally, we share some lessons learned based on our\\nexperiences building an LLM application for real-world use.\\nLink: http://arxiv.org/abs/2402.07483v1\\n\\n\\n\", 'name': 'Retrieve_Action_2', 'role': 'user'}, {'content': \"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", 'name': 'Research_Action_1', 'role': 'user'}], summary=\"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", cost=({'total_cost': 0}, {'total_cost': 0}), human_input=[])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "initializer.initiate_chat(\n", + " manager, message=\"Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\"\n", + ")" + ] + } + ], + "metadata": { + "front_matter": { + "description": "Custom Speaker Selection Function", + "tags": [ + "orchestration", + "group chat" + ] + }, + "kernelspec": { + "display_name": "autogen", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 798df5b81fa3c561d99c65823219dfbe00c0e3bc Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:09:19 -0400 Subject: [PATCH 06/10] update --- .../customized_speaker_selection.ipynb | 8 +- .../docs/tutorial/conversation-patterns.ipynb | 536 +----------------- 2 files changed, 29 insertions(+), 515 deletions(-) diff --git a/website/docs/topics/groupchat/customized_speaker_selection.ipynb b/website/docs/topics/groupchat/customized_speaker_selection.ipynb index 8a138055c827..4aa7adb28513 100644 --- a/website/docs/topics/groupchat/customized_speaker_selection.ipynb +++ b/website/docs/topics/groupchat/customized_speaker_selection.ipynb @@ -8,7 +8,11 @@ "\n", "In GroupChat, we can also customize the speaker selection by passing in a function to `speaker_selection_method`:\n", "```python\n", - "def custom_speaker_selection_func(last_speaker, groupchat):\n", + "def custom_speaker_selection_func(\n", + " last_speaker: Agent, \n", + " groupchat: GroupChat\n", + ") -> Union[Agent, Literal['auto', 'manual', 'random' 'round_robin'], None]:\n", + "\n", " \"\"\"Define a customized speaker selection function.\n", " A recommended way is to define a transition for each speaker in the groupchat.\n", "\n", @@ -47,7 +51,7 @@ "- Executor: Execute the code.\n", "- Scientist: Read the papers and write a summary.\n", "\n", - "In the Figure, we define a simple workflow for research with 4 states: Init, Retrieve, Reserach and End. Within each state, we will call different agents to perform the tasks.\n", + "In the Figure, we define a simple workflow for research with 4 states: Init, Retrieve, Research and End. Within each state, we will call different agents to perform the tasks.\n", "\n", "Init: We use the initializer to start the workflow.\n", "Retrieve: We will first call the coder to write code and then call the executor to execute the code.\n", diff --git a/website/docs/tutorial/conversation-patterns.ipynb b/website/docs/tutorial/conversation-patterns.ipynb index badc22b9c130..a5dbecbad6ff 100644 --- a/website/docs/tutorial/conversation-patterns.ipynb +++ b/website/docs/tutorial/conversation-patterns.ipynb @@ -1183,29 +1183,29 @@ ] }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Changing the select speaker role name\n", - "\n", - "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", - "a select speaker message is sent to the LLM to determine the next speaker.\n", - "\n", - "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", - "`assistant`, or `system`. The select speaker message is the last in the chat\n", - "sequence when used and, by default, has a role of `system`.\n", - "\n", - "When using some models, such as Mistral through Mistral.AI's API, the role on\n", - "the last message in the chat sequence has to be `user`.\n", - "\n", - "To change the default behaviour, Autogen provides a way to set the value of the\n", - "select speaker message's role to any string value by setting the\n", - "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", - "default value is `system` and by setting it to `user` you can accommodate the\n", - "last message role requirement of Mistral.AI's API." - ] - }, - { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Changing the select speaker role name\n", + "\n", + "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", + "a select speaker message is sent to the LLM to determine the next speaker.\n", + "\n", + "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", + "`assistant`, or `system`. The select speaker message is the last in the chat\n", + "sequence when used and, by default, has a role of `system`.\n", + "\n", + "When using some models, such as Mistral through Mistral.AI's API, the role on\n", + "the last message in the chat sequence has to be `user`.\n", + "\n", + "To change the default behaviour, Autogen provides a way to set the value of the\n", + "select speaker message's role to any string value by setting the\n", + "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", + "default value is `system` and by setting it to `user` you can accommodate the\n", + "last message role requirement of Mistral.AI's API." + ] + }, + { "cell_type": "markdown", "metadata": {}, "source": [ @@ -1559,496 +1559,6 @@ "See the [nested chats for tool use notebook](/docs/notebooks/agentchat_nested_chats_chess) for an example." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Customzing Speaker Selection\n", - "\n", - "In GroupChat, we can also customize the speaker selection by passing in a function to `speaker_selection_method`:\n", - "```python\n", - "def custom_speaker_selection_func(last_speaker, groupchat):\n", - " \"\"\"Define a customized speaker selection function.\n", - " A recommended way is to define a transition for each speaker in the groupchat.\n", - "\n", - " Parameters:\n", - " - last_speaker: Agent\n", - " The last speaker in the group chat.\n", - " - groupchat: GroupChat\n", - " The GroupChat object\n", - " Return:\n", - " Return one of the following:\n", - " 1. an `Agent` class, it must be one of the agents in the group chat.\n", - " 2. a string from ['auto', 'manual', 'random', 'round_robin'] to select a default method to use.\n", - " 3. None, which indicates the chat should be terminated.\n", - " \"\"\"\n", - " pass\n", - "\n", - "groupchat = autogen.GroupChat(\n", - " speaker_selection_method=custom_speaker_selection_func,\n", - " ...,\n", - ")\n", - "```\n", - "The last speaker and the groupchat object are passed to the function. \n", - "Commonly used variables from groupchat are `groupchat.messages` and `groupchat.agents`, which is the message history and the agents in the group chat respectively. You can access other attributes of the groupchat, such as `groupchat.allowed_speaker_transitions_dict` for pre-defined `allowed_speaker_transitions_dict`.\n", - "\n", - "Heres is a simple example to build workflow for research with customized speaker selection.\n", - "\n", - "\n", - "```{=mdx}\n", - "![group_chat](../../blog/2024-02-29-StateFlow/img/sf_example_1.png)\n", - "```\n", - "\n", - "We define the following agents:\n", - "\n", - "- Initializer: Start the workflow by sending a task.\n", - "- Coder: Retrieve papers from the internet by writing code.\n", - "- Executor: Execute the code.\n", - "- Scientist: Read the papers and write a summary.\n", - "\n", - "In the Figure, we define a simple workflow for research with 4 states: Init, Retrieve, Reserach and End. Within each state, we will call different agents to perform the tasks.\n", - "\n", - "Init: We use the initializer to start the workflow.\n", - "Retrieve: We will first call the coder to write code and then call the executor to execute the code.\n", - "Research: We will call the scientist to read the papers and write a summary.\n", - "End: We will end the workflow." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import autogen\n", - "\n", - "config_list = autogen.config_list_from_json(\n", - " \"OAI_CONFIG_LIST\",\n", - " filter_dict={\n", - " \"model\": [\"gpt-4-1106-preview\"],\n", - " },\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "gpt4_config = {\n", - " \"cache_seed\": 42, # change the cache_seed for different trials\n", - " \"temperature\": 0,\n", - " \"config_list\": config_list,\n", - " \"timeout\": 120,\n", - "}\n", - "\n", - "initializer = autogen.UserProxyAgent(\n", - " name=\"Init\",\n", - ")\n", - "\n", - "coder = autogen.AssistantAgent(\n", - " name=\"Retrieve_Action_1\",\n", - " llm_config=gpt4_config,\n", - " system_message=\"\"\"You are the Coder. Given a topic, write code to retrieve related papers from the arXiv API, print their title, authors, abstract, and link.\n", - "You write python/shell code to solve tasks. Wrap the code in a code block that specifies the script type. The user can't modify your code. So do not suggest incomplete code which requires others to modify. Don't use a code block if it's not intended to be executed by the executor.\n", - "Don't include multiple code blocks in one response. Do not ask others to copy and paste the result. Check the execution result returned by the executor.\n", - "If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.\n", - "\"\"\",\n", - ")\n", - "executor = autogen.UserProxyAgent(\n", - " name=\"Retrieve_Action_2\",\n", - " system_message=\"Executor. Execute the code written by the Coder and report the result.\",\n", - " human_input_mode=\"NEVER\",\n", - " code_execution_config={\n", - " \"last_n_messages\": 3,\n", - " \"work_dir\": \"paper\",\n", - " \"use_docker\": False,\n", - " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n", - ")\n", - "scientist = autogen.AssistantAgent(\n", - " name=\"Research_Action_1\",\n", - " llm_config=gpt4_config,\n", - " system_message=\"\"\"You are the Scientist. Please categorize papers after seeing their abstracts printed and create a markdown table with Domain, Title, Authors, Summary and Link\"\"\",\n", - ")\n", - "\n", - "\n", - "def state_transition(last_speaker, groupchat):\n", - " messages = groupchat.messages\n", - "\n", - " if last_speaker is initializer:\n", - " # init -> retrieve\n", - " return coder\n", - " elif last_speaker is coder:\n", - " # retrieve: action 1 -> action 2\n", - " return executor\n", - " elif last_speaker is executor:\n", - " if messages[-1][\"content\"] == \"exitcode: 1\":\n", - " # retrieve --(execution failed)--> retrieve\n", - " return coder\n", - " else:\n", - " # retrieve --(execution success)--> research\n", - " return scientist\n", - " elif last_speaker == \"Scientist\":\n", - " # research -> end\n", - " return None\n", - "\n", - "\n", - "groupchat = autogen.GroupChat(\n", - " agents=[initializer, coder, executor, scientist],\n", - " messages=[],\n", - " max_round=20,\n", - " speaker_selection_method=state_transition,\n", - ")\n", - "manager = autogen.GroupChatManager(groupchat=groupchat, llm_config=gpt4_config)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mInit\u001b[0m (to chat_manager):\n", - "\n", - "Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mRetrieve_Action_1\u001b[0m (to chat_manager):\n", - "\n", - "To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\n", - "\n", - "```python\n", - "import requests\n", - "from datetime import datetime, timedelta\n", - "import feedparser\n", - "\n", - "# Define the base URL for the arXiv API\n", - "ARXIV_API_URL = 'http://export.arxiv.org/api/query?'\n", - "\n", - "# Define the search parameters\n", - "search_query = 'all:\"LLM applications\"'\n", - "start_date = (datetime.now() - timedelta(days=7)).strftime('%Y%m%d%H%M%S')\n", - "end_date = datetime.now().strftime('%Y%m%d%H%M%S')\n", - "start = 0\n", - "max_results = 10\n", - "sort_by = 'submittedDate'\n", - "sort_order = 'descending'\n", - "\n", - "# Construct the query\n", - "query = f'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}'\n", - "\n", - "# Send the request to the arXiv API\n", - "response = requests.get(ARXIV_API_URL + query)\n", - "\n", - "# Parse the response using feedparser\n", - "feed = feedparser.parse(response.content)\n", - "\n", - "# Print the title, authors, abstract, and link of each paper\n", - "for entry in feed.entries:\n", - " print(\"Title:\", entry.title)\n", - " print(\"Authors:\", ', '.join(author.name for author in entry.authors))\n", - " print(\"Abstract:\", entry.summary)\n", - " print(\"Link:\", entry.link)\n", - " print(\"\\n\")\n", - "\n", - "# Check if we have at least 5 papers, if not, adjust the search or notify\n", - "if len(feed.entries) < 5:\n", - " print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\n", - "```\n", - "\n", - "This script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", - "\u001b[33mRetrieve_Action_2\u001b[0m (to chat_manager):\n", - "\n", - "exitcode: 0 (execution succeeded)\n", - "Code output: \n", - "Title: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\n", - "Authors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\n", - "Abstract: Prompt, recognized as crucial intellectual property, enables large language\n", - "models (LLMs) to perform specific tasks without the need of fine-tuning,\n", - "underscoring their escalating importance. With the rise of prompt-based\n", - "services, such as prompt marketplaces and LLM applications, providers often\n", - "display prompts' capabilities through input-output examples to attract users.\n", - "However, this paradigm raises a pivotal security concern: does the exposure of\n", - "input-output pairs pose the risk of potential prompt leakage, infringing on the\n", - "intellectual property rights of the developers? To our knowledge, this problem\n", - "still has not been comprehensively explored yet. To remedy this gap, in this\n", - "paper, we perform the first in depth exploration and propose a novel attack\n", - "framework for reverse-stealing prompts against commercial LLMs, namely PRSA.\n", - "The main idea of PRSA is that by analyzing the critical features of the\n", - "input-output pairs, we mimic and gradually infer (steal) the target prompts. In\n", - "detail, PRSA mainly consists of two key phases: prompt mutation and prompt\n", - "pruning. In the mutation phase, we propose a prompt attention algorithm based\n", - "on differential feedback to capture these critical features for effectively\n", - "inferring the target prompts. In the prompt pruning phase, we identify and mask\n", - "the words dependent on specific inputs, enabling the prompts to accommodate\n", - "diverse inputs for generalization. Through extensive evaluation, we verify that\n", - "PRSA poses a severe threat in real world scenarios. We have reported these\n", - "findings to prompt service providers and actively collaborate with them to take\n", - "protective measures for prompt copyright.\n", - "Link: http://arxiv.org/abs/2402.19200v1\n", - "\n", - "\n", - "Title: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\n", - " for Values and Opinions in Large Language Models\n", - "Authors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\n", - "Abstract: Much recent work seeks to evaluate values and opinions in large language\n", - "models (LLMs) using multiple-choice surveys and questionnaires. Most of this\n", - "work is motivated by concerns around real-world LLM applications. For example,\n", - "politically-biased LLMs may subtly influence society when they are used by\n", - "millions of people. Such real-world concerns, however, stand in stark contrast\n", - "to the artificiality of current evaluations: real users do not typically ask\n", - "LLMs survey questions. Motivated by this discrepancy, we challenge the\n", - "prevailing constrained evaluation paradigm for values and opinions in LLMs and\n", - "explore more realistic unconstrained evaluations. As a case study, we focus on\n", - "the popular Political Compass Test (PCT). In a systematic review, we find that\n", - "most prior work using the PCT forces models to comply with the PCT's\n", - "multiple-choice format. We show that models give substantively different\n", - "answers when not forced; that answers change depending on how models are\n", - "forced; and that answers lack paraphrase robustness. Then, we demonstrate that\n", - "models give different answers yet again in a more realistic open-ended answer\n", - "setting. We distill these findings into recommendations and open challenges in\n", - "evaluating values and opinions in LLMs.\n", - "Link: http://arxiv.org/abs/2402.16786v1\n", - "\n", - "\n", - "Title: Large Language Models as Urban Residents: An LLM Agent Framework for\n", - " Personal Mobility Generation\n", - "Authors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\n", - "Abstract: This paper introduces a novel approach using Large Language Models (LLMs)\n", - "integrated into an agent framework for flexible and efficient personal mobility\n", - "generation. LLMs overcome the limitations of previous models by efficiently\n", - "processing semantic data and offering versatility in modeling various tasks.\n", - "Our approach addresses the critical need to align LLMs with real-world urban\n", - "mobility data, focusing on three research questions: aligning LLMs with rich\n", - "activity data, developing reliable activity generation strategies, and\n", - "exploring LLM applications in urban mobility. The key technical contribution is\n", - "a novel LLM agent framework that accounts for individual activity patterns and\n", - "motivations, including a self-consistency approach to align LLMs with\n", - "real-world activity data and a retrieval-augmented strategy for interpretable\n", - "activity generation. In experimental studies, comprehensive validation is\n", - "performed using real-world data. This research marks the pioneering work of\n", - "designing an LLM agent framework for activity generation based on real-world\n", - "human activity data, offering a promising tool for urban mobility analysis.\n", - "Link: http://arxiv.org/abs/2402.14744v1\n", - "\n", - "\n", - "Title: An Evaluation of Large Language Models in Bioinformatics Research\n", - "Authors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\n", - "Abstract: Large language models (LLMs) such as ChatGPT have gained considerable\n", - "interest across diverse research communities. Their notable ability for text\n", - "completion and generation has inaugurated a novel paradigm for\n", - "language-interfaced problem solving. However, the potential and efficacy of\n", - "these models in bioinformatics remain incompletely explored. In this work, we\n", - "study the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\n", - "These tasks include the identification of potential coding regions, extraction\n", - "of named entities for genes and proteins, detection of antimicrobial and\n", - "anti-cancer peptides, molecular optimization, and resolution of educational\n", - "bioinformatics problems. Our findings indicate that, given appropriate prompts,\n", - "LLMs like GPT variants can successfully handle most of these tasks. In\n", - "addition, we provide a thorough analysis of their limitations in the context of\n", - "complicated bioinformatics tasks. In conclusion, we believe that this work can\n", - "provide new perspectives and motivate future research in the field of LLMs\n", - "applications, AI for Science and bioinformatics.\n", - "Link: http://arxiv.org/abs/2402.13714v1\n", - "\n", - "\n", - "Title: Privacy-Preserving Instructions for Aligning Large Language Models\n", - "Authors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\n", - "Abstract: Service providers of large language model (LLM) applications collect user\n", - "instructions in the wild and use them in further aligning LLMs with users'\n", - "intentions. These instructions, which potentially contain sensitive\n", - "information, are annotated by human workers in the process. This poses a new\n", - "privacy risk not addressed by the typical private optimization. To this end, we\n", - "propose using synthetic instructions to replace real instructions in data\n", - "annotation and model fine-tuning. Formal differential privacy is guaranteed by\n", - "generating those synthetic instructions using privately fine-tuned generators.\n", - "Crucial in achieving the desired utility is our novel filtering algorithm that\n", - "matches the distribution of the synthetic instructions to that of the real\n", - "ones. In both supervised fine-tuning and reinforcement learning from human\n", - "feedback, our extensive experiments demonstrate the high utility of the final\n", - "set of synthetic instructions by showing comparable results to real\n", - "instructions. In supervised fine-tuning, models trained with private synthetic\n", - "instructions outperform leading open-source models such as Vicuna.\n", - "Link: http://arxiv.org/abs/2402.13659v1\n", - "\n", - "\n", - "Title: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\n", - " Conversations with the Tabletop Robot Haru\n", - "Authors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\n", - "Abstract: Social robots aim to establish long-term bonds with humans through engaging\n", - "conversation. However, traditional conversational approaches, reliant on\n", - "scripted interactions, often fall short in maintaining engaging conversations.\n", - "This paper addresses this limitation by integrating large language models\n", - "(LLMs) into social robots to achieve more dynamic and expressive conversations.\n", - "We introduce a fully-automated conversation system that leverages LLMs to\n", - "generate robot responses with expressive behaviors, congruent with the robot's\n", - "personality. We incorporate robot behavior with two modalities: 1) a\n", - "text-to-speech (TTS) engine capable of various delivery styles, and 2) a\n", - "library of physical actions for the robot. We develop a custom,\n", - "state-of-the-art emotion recognition model to dynamically select the robot's\n", - "tone of voice and utilize emojis from LLM output as cues for generating robot\n", - "actions. A demo of our system is available here. To illuminate design and\n", - "implementation issues, we conduct a pilot study where volunteers chat with a\n", - "social robot using our proposed system, and we analyze their feedback,\n", - "conducting a rigorous error analysis of chat transcripts. Feedback was\n", - "overwhelmingly positive, with participants commenting on the robot's empathy,\n", - "helpfulness, naturalness, and entertainment. Most negative feedback was due to\n", - "automatic speech recognition (ASR) errors which had limited impact on\n", - "conversations. However, we observed a small class of errors, such as the LLM\n", - "repeating itself or hallucinating fictitious information and human responses,\n", - "that have the potential to derail conversations, raising important issues for\n", - "LLM application.\n", - "Link: http://arxiv.org/abs/2402.11571v1\n", - "\n", - "\n", - "Title: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\n", - " in Ophthalmology and LLM-based evaluation using GPT-4\n", - "Authors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\n", - "Abstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\n", - "experts, for the evaluation of responses to ophthalmology-related patient\n", - "queries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\n", - "questions and paired answers were created by ophthalmologists to represent\n", - "commonly asked patient questions, divided into fine-tuning (368; 92%), and\n", - "testing (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\n", - "LLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\n", - "additional 8 glaucoma QnA pairs were included. 200 responses to the testing\n", - "dataset were generated by 5 fine-tuned LLMs for evaluation. A customized\n", - "clinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\n", - "clinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\n", - "evaluation was then compared against ranking by 5 clinicians for clinical\n", - "alignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\n", - "(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\n", - "LLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\n", - "evaluation demonstrated significant agreement with human clinician rankings,\n", - "with Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\n", - "respectively; while correlation based on Cohen Kappa was more modest at 0.50.\n", - "Notably, qualitative analysis and the glaucoma sub-analysis revealed clinical\n", - "inaccuracies in the LLM-generated responses, which were appropriately\n", - "identified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\n", - "of GPT-4 evaluation highlighted its potential to streamline the clinical\n", - "evaluation of LLM chatbot responses to healthcare-related queries. By\n", - "complementing the existing clinician-dependent manual grading, this efficient\n", - "and automated evaluation could assist the validation of future developments in\n", - "LLM applications for healthcare.\n", - "Link: http://arxiv.org/abs/2402.10083v1\n", - "\n", - "\n", - "Title: Unmemorization in Large Language Models via Self-Distillation and\n", - " Deliberate Imagination\n", - "Authors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\n", - "Abstract: While displaying impressive generation capabilities across many tasks, Large\n", - "Language Models (LLMs) still struggle with crucial issues of privacy violation\n", - "and unwanted exposure of sensitive data. This raises an essential question: how\n", - "should we prevent such undesired behavior of LLMs while maintaining their\n", - "strong generation and natural language understanding (NLU) capabilities? In\n", - "this work, we introduce a novel approach termed deliberate imagination in the\n", - "context of LLM unlearning. Instead of trying to forget memorized data, we\n", - "employ a self-distillation framework, guiding LLMs to deliberately imagine\n", - "alternative scenarios. As demonstrated in a wide range of experiments, the\n", - "proposed method not only effectively unlearns targeted text but also preserves\n", - "the LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\n", - "Our results demonstrate the usefulness of this approach across different models\n", - "and sizes, and also with parameter-efficient fine-tuning, offering a novel\n", - "pathway to addressing the challenges with private and sensitive data in LLM\n", - "applications.\n", - "Link: http://arxiv.org/abs/2402.10052v1\n", - "\n", - "\n", - "Title: Anchor-based Large Language Models\n", - "Authors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\n", - "Abstract: Large language models (LLMs) predominantly employ decoder-only transformer\n", - "architectures, necessitating the retention of keys/values information for\n", - "historical tokens to provide contextual information and avoid redundant\n", - "computation. However, the substantial size and parameter volume of these LLMs\n", - "require massive GPU memory. This memory demand increases with the length of the\n", - "input text, leading to an urgent need for more efficient methods of information\n", - "storage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\n", - "utilize an innovative anchor-based self-attention network (AnSAN) and also an\n", - "anchor-based inference strategy. This approach enables LLMs to compress\n", - "sequence information into an anchor token, reducing the keys/values cache and\n", - "enhancing inference efficiency. Experiments on question-answering benchmarks\n", - "reveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\n", - "keys/values cache reduction and up to 3.5 times faster inference. Despite a\n", - "minor compromise in accuracy, the substantial enhancements of AnLLMs employing\n", - "the AnSAN technique in resource utilization and computational efficiency\n", - "underscore their potential for practical LLM applications.\n", - "Link: http://arxiv.org/abs/2402.07616v2\n", - "\n", - "\n", - "Title: T-RAG: Lessons from the LLM Trenches\n", - "Authors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\n", - "Abstract: Large Language Models (LLM) have shown remarkable language capabilities\n", - "fueling attempts to integrate them into applications across a wide range of\n", - "domains. An important application area is question answering over private\n", - "enterprise documents where the main considerations are data security, which\n", - "necessitates applications that can be deployed on-prem, limited computational\n", - "resources and the need for a robust application that correctly responds to\n", - "queries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\n", - "framework for building LLM-based applications. While building a RAG is\n", - "relatively straightforward, making it robust and a reliable application\n", - "requires extensive customization and relatively deep knowledge of the\n", - "application domain. We share our experiences building and deploying an LLM\n", - "application for question answering over private organizational documents. Our\n", - "application combines the use of RAG with a finetuned open-source LLM.\n", - "Additionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\n", - "to represent entity hierarchies within the organization. This is used to\n", - "generate a textual description to augment the context when responding to user\n", - "queries pertaining to entities within the organization's hierarchy. Our\n", - "evaluations show that this combination performs better than a simple RAG or\n", - "finetuning implementation. Finally, we share some lessons learned based on our\n", - "experiences building an LLM application for real-world use.\n", - "Link: http://arxiv.org/abs/2402.07483v1\n", - "\n", - "\n", - "\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mResearch_Action_1\u001b[0m (to chat_manager):\n", - "\n", - "Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\n", - "\n", - "| Domain | Title | Authors | Summary | Link |\n", - "|--------|-------|---------|---------|------|\n", - "| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\n", - "| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\n", - "| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\n", - "| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\n", - "| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\n", - "| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\n", - "| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\n", - "| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\n", - "| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\n", - "| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\n", - "\n", - "These papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - }, - { - "data": { - "text/plain": [ - "ChatResult(chat_id=None, chat_history=[{'content': 'Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.', 'role': 'assistant'}, {'content': 'To retrieve related papers from the arXiv API, we can use Python with the `requests` library to send a query to the API and parse the response. Below is a Python script that searches for papers related to \"LLM applications\" (Large Language Models applications) from the last week, across different domains, and prints out the required information for 5 to 10 papers.\\n\\n```python\\nimport requests\\nfrom datetime import datetime, timedelta\\nimport feedparser\\n\\n# Define the base URL for the arXiv API\\nARXIV_API_URL = \\'http://export.arxiv.org/api/query?\\'\\n\\n# Define the search parameters\\nsearch_query = \\'all:\"LLM applications\"\\'\\nstart_date = (datetime.now() - timedelta(days=7)).strftime(\\'%Y%m%d%H%M%S\\')\\nend_date = datetime.now().strftime(\\'%Y%m%d%H%M%S\\')\\nstart = 0\\nmax_results = 10\\nsort_by = \\'submittedDate\\'\\nsort_order = \\'descending\\'\\n\\n# Construct the query\\nquery = f\\'search_query={search_query}&sortBy={sort_by}&sortOrder={sort_order}&start={start}&max_results={max_results}\\'\\n\\n# Send the request to the arXiv API\\nresponse = requests.get(ARXIV_API_URL + query)\\n\\n# Parse the response using feedparser\\nfeed = feedparser.parse(response.content)\\n\\n# Print the title, authors, abstract, and link of each paper\\nfor entry in feed.entries:\\n print(\"Title:\", entry.title)\\n print(\"Authors:\", \\', \\'.join(author.name for author in entry.authors))\\n print(\"Abstract:\", entry.summary)\\n print(\"Link:\", entry.link)\\n print(\"\\\\n\")\\n\\n# Check if we have at least 5 papers, if not, adjust the search or notify\\nif len(feed.entries) < 5:\\n print(\"Less than 5 papers found. Consider adjusting the search parameters or timeframe.\")\\n```\\n\\nThis script will print the title, authors, abstract, and link for each paper related to \"LLM applications\" from the last week, up to a maximum of 10 papers. If fewer than 5 papers are found, it will notify the user to consider adjusting the search parameters or timeframe.', 'name': 'Retrieve_Action_1', 'role': 'user'}, {'content': \"exitcode: 0 (execution succeeded)\\nCode output: \\nTitle: PRSA: Prompt Reverse Stealing Attacks against Large Language Models\\nAuthors: Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang\\nAbstract: Prompt, recognized as crucial intellectual property, enables large language\\nmodels (LLMs) to perform specific tasks without the need of fine-tuning,\\nunderscoring their escalating importance. With the rise of prompt-based\\nservices, such as prompt marketplaces and LLM applications, providers often\\ndisplay prompts' capabilities through input-output examples to attract users.\\nHowever, this paradigm raises a pivotal security concern: does the exposure of\\ninput-output pairs pose the risk of potential prompt leakage, infringing on the\\nintellectual property rights of the developers? To our knowledge, this problem\\nstill has not been comprehensively explored yet. To remedy this gap, in this\\npaper, we perform the first in depth exploration and propose a novel attack\\nframework for reverse-stealing prompts against commercial LLMs, namely PRSA.\\nThe main idea of PRSA is that by analyzing the critical features of the\\ninput-output pairs, we mimic and gradually infer (steal) the target prompts. In\\ndetail, PRSA mainly consists of two key phases: prompt mutation and prompt\\npruning. In the mutation phase, we propose a prompt attention algorithm based\\non differential feedback to capture these critical features for effectively\\ninferring the target prompts. In the prompt pruning phase, we identify and mask\\nthe words dependent on specific inputs, enabling the prompts to accommodate\\ndiverse inputs for generalization. Through extensive evaluation, we verify that\\nPRSA poses a severe threat in real world scenarios. We have reported these\\nfindings to prompt service providers and actively collaborate with them to take\\nprotective measures for prompt copyright.\\nLink: http://arxiv.org/abs/2402.19200v1\\n\\n\\nTitle: Political Compass or Spinning Arrow? Towards More Meaningful Evaluations\\n for Values and Opinions in Large Language Models\\nAuthors: Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy\\nAbstract: Much recent work seeks to evaluate values and opinions in large language\\nmodels (LLMs) using multiple-choice surveys and questionnaires. Most of this\\nwork is motivated by concerns around real-world LLM applications. For example,\\npolitically-biased LLMs may subtly influence society when they are used by\\nmillions of people. Such real-world concerns, however, stand in stark contrast\\nto the artificiality of current evaluations: real users do not typically ask\\nLLMs survey questions. Motivated by this discrepancy, we challenge the\\nprevailing constrained evaluation paradigm for values and opinions in LLMs and\\nexplore more realistic unconstrained evaluations. As a case study, we focus on\\nthe popular Political Compass Test (PCT). In a systematic review, we find that\\nmost prior work using the PCT forces models to comply with the PCT's\\nmultiple-choice format. We show that models give substantively different\\nanswers when not forced; that answers change depending on how models are\\nforced; and that answers lack paraphrase robustness. Then, we demonstrate that\\nmodels give different answers yet again in a more realistic open-ended answer\\nsetting. We distill these findings into recommendations and open challenges in\\nevaluating values and opinions in LLMs.\\nLink: http://arxiv.org/abs/2402.16786v1\\n\\n\\nTitle: Large Language Models as Urban Residents: An LLM Agent Framework for\\n Personal Mobility Generation\\nAuthors: Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao\\nAbstract: This paper introduces a novel approach using Large Language Models (LLMs)\\nintegrated into an agent framework for flexible and efficient personal mobility\\ngeneration. LLMs overcome the limitations of previous models by efficiently\\nprocessing semantic data and offering versatility in modeling various tasks.\\nOur approach addresses the critical need to align LLMs with real-world urban\\nmobility data, focusing on three research questions: aligning LLMs with rich\\nactivity data, developing reliable activity generation strategies, and\\nexploring LLM applications in urban mobility. The key technical contribution is\\na novel LLM agent framework that accounts for individual activity patterns and\\nmotivations, including a self-consistency approach to align LLMs with\\nreal-world activity data and a retrieval-augmented strategy for interpretable\\nactivity generation. In experimental studies, comprehensive validation is\\nperformed using real-world data. This research marks the pioneering work of\\ndesigning an LLM agent framework for activity generation based on real-world\\nhuman activity data, offering a promising tool for urban mobility analysis.\\nLink: http://arxiv.org/abs/2402.14744v1\\n\\n\\nTitle: An Evaluation of Large Language Models in Bioinformatics Research\\nAuthors: Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun\\nAbstract: Large language models (LLMs) such as ChatGPT have gained considerable\\ninterest across diverse research communities. Their notable ability for text\\ncompletion and generation has inaugurated a novel paradigm for\\nlanguage-interfaced problem solving. However, the potential and efficacy of\\nthese models in bioinformatics remain incompletely explored. In this work, we\\nstudy the performance LLMs on a wide spectrum of crucial bioinformatics tasks.\\nThese tasks include the identification of potential coding regions, extraction\\nof named entities for genes and proteins, detection of antimicrobial and\\nanti-cancer peptides, molecular optimization, and resolution of educational\\nbioinformatics problems. Our findings indicate that, given appropriate prompts,\\nLLMs like GPT variants can successfully handle most of these tasks. In\\naddition, we provide a thorough analysis of their limitations in the context of\\ncomplicated bioinformatics tasks. In conclusion, we believe that this work can\\nprovide new perspectives and motivate future research in the field of LLMs\\napplications, AI for Science and bioinformatics.\\nLink: http://arxiv.org/abs/2402.13714v1\\n\\n\\nTitle: Privacy-Preserving Instructions for Aligning Large Language Models\\nAuthors: Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu\\nAbstract: Service providers of large language model (LLM) applications collect user\\ninstructions in the wild and use them in further aligning LLMs with users'\\nintentions. These instructions, which potentially contain sensitive\\ninformation, are annotated by human workers in the process. This poses a new\\nprivacy risk not addressed by the typical private optimization. To this end, we\\npropose using synthetic instructions to replace real instructions in data\\nannotation and model fine-tuning. Formal differential privacy is guaranteed by\\ngenerating those synthetic instructions using privately fine-tuned generators.\\nCrucial in achieving the desired utility is our novel filtering algorithm that\\nmatches the distribution of the synthetic instructions to that of the real\\nones. In both supervised fine-tuning and reinforcement learning from human\\nfeedback, our extensive experiments demonstrate the high utility of the final\\nset of synthetic instructions by showing comparable results to real\\ninstructions. In supervised fine-tuning, models trained with private synthetic\\ninstructions outperform leading open-source models such as Vicuna.\\nLink: http://arxiv.org/abs/2402.13659v1\\n\\n\\nTitle: Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in\\n Conversations with the Tabletop Robot Haru\\nAuthors: Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez\\nAbstract: Social robots aim to establish long-term bonds with humans through engaging\\nconversation. However, traditional conversational approaches, reliant on\\nscripted interactions, often fall short in maintaining engaging conversations.\\nThis paper addresses this limitation by integrating large language models\\n(LLMs) into social robots to achieve more dynamic and expressive conversations.\\nWe introduce a fully-automated conversation system that leverages LLMs to\\ngenerate robot responses with expressive behaviors, congruent with the robot's\\npersonality. We incorporate robot behavior with two modalities: 1) a\\ntext-to-speech (TTS) engine capable of various delivery styles, and 2) a\\nlibrary of physical actions for the robot. We develop a custom,\\nstate-of-the-art emotion recognition model to dynamically select the robot's\\ntone of voice and utilize emojis from LLM output as cues for generating robot\\nactions. A demo of our system is available here. To illuminate design and\\nimplementation issues, we conduct a pilot study where volunteers chat with a\\nsocial robot using our proposed system, and we analyze their feedback,\\nconducting a rigorous error analysis of chat transcripts. Feedback was\\noverwhelmingly positive, with participants commenting on the robot's empathy,\\nhelpfulness, naturalness, and entertainment. Most negative feedback was due to\\nautomatic speech recognition (ASR) errors which had limited impact on\\nconversations. However, we observed a small class of errors, such as the LLM\\nrepeating itself or hallucinating fictitious information and human responses,\\nthat have the potential to derail conversations, raising important issues for\\nLLM application.\\nLink: http://arxiv.org/abs/2402.11571v1\\n\\n\\nTitle: Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots\\n in Ophthalmology and LLM-based evaluation using GPT-4\\nAuthors: Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting\\nAbstract: Purpose: To assess the alignment of GPT-4-based evaluation to human clinician\\nexperts, for the evaluation of responses to ophthalmology-related patient\\nqueries generated by fine-tuned LLM chatbots. Methods: 400 ophthalmology\\nquestions and paired answers were created by ophthalmologists to represent\\ncommonly asked patient questions, divided into fine-tuning (368; 92%), and\\ntesting (40; 8%). We find-tuned 5 different LLMs, including LLAMA2-7b,\\nLLAMA2-7b-Chat, LLAMA2-13b, and LLAMA2-13b-Chat. For the testing dataset,\\nadditional 8 glaucoma QnA pairs were included. 200 responses to the testing\\ndataset were generated by 5 fine-tuned LLMs for evaluation. A customized\\nclinical evaluation rubric was used to guide GPT-4 evaluation, grounded on\\nclinical accuracy, relevance, patient safety, and ease of understanding. GPT-4\\nevaluation was then compared against ranking by 5 clinicians for clinical\\nalignment. Results: Among all fine-tuned LLMs, GPT-3.5 scored the highest\\n(87.1%), followed by LLAMA2-13b (80.9%), LLAMA2-13b-chat (75.5%),\\nLLAMA2-7b-Chat (70%) and LLAMA2-7b (68.8%) based on the GPT-4 evaluation. GPT-4\\nevaluation demonstrated significant agreement with human clinician rankings,\\nwith Spearman and Kendall Tau correlation coefficients of 0.90 and 0.80\\nrespectively; while correlation based on Cohen Kappa was more modest at 0.50.\\nNotably, qualitative analysis and the glaucoma sub-analysis revealed clinical\\ninaccuracies in the LLM-generated responses, which were appropriately\\nidentified by the GPT-4 evaluation. Conclusion: The notable clinical alignment\\nof GPT-4 evaluation highlighted its potential to streamline the clinical\\nevaluation of LLM chatbot responses to healthcare-related queries. By\\ncomplementing the existing clinician-dependent manual grading, this efficient\\nand automated evaluation could assist the validation of future developments in\\nLLM applications for healthcare.\\nLink: http://arxiv.org/abs/2402.10083v1\\n\\n\\nTitle: Unmemorization in Large Language Models via Self-Distillation and\\n Deliberate Imagination\\nAuthors: Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić\\nAbstract: While displaying impressive generation capabilities across many tasks, Large\\nLanguage Models (LLMs) still struggle with crucial issues of privacy violation\\nand unwanted exposure of sensitive data. This raises an essential question: how\\nshould we prevent such undesired behavior of LLMs while maintaining their\\nstrong generation and natural language understanding (NLU) capabilities? In\\nthis work, we introduce a novel approach termed deliberate imagination in the\\ncontext of LLM unlearning. Instead of trying to forget memorized data, we\\nemploy a self-distillation framework, guiding LLMs to deliberately imagine\\nalternative scenarios. As demonstrated in a wide range of experiments, the\\nproposed method not only effectively unlearns targeted text but also preserves\\nthe LLMs' capabilities in open-ended generation tasks as well as in NLU tasks.\\nOur results demonstrate the usefulness of this approach across different models\\nand sizes, and also with parameter-efficient fine-tuning, offering a novel\\npathway to addressing the challenges with private and sensitive data in LLM\\napplications.\\nLink: http://arxiv.org/abs/2402.10052v1\\n\\n\\nTitle: Anchor-based Large Language Models\\nAuthors: Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang\\nAbstract: Large language models (LLMs) predominantly employ decoder-only transformer\\narchitectures, necessitating the retention of keys/values information for\\nhistorical tokens to provide contextual information and avoid redundant\\ncomputation. However, the substantial size and parameter volume of these LLMs\\nrequire massive GPU memory. This memory demand increases with the length of the\\ninput text, leading to an urgent need for more efficient methods of information\\nstorage and processing. This study introduces Anchor-based LLMs (AnLLMs), which\\nutilize an innovative anchor-based self-attention network (AnSAN) and also an\\nanchor-based inference strategy. This approach enables LLMs to compress\\nsequence information into an anchor token, reducing the keys/values cache and\\nenhancing inference efficiency. Experiments on question-answering benchmarks\\nreveal that AnLLMs maintain similar accuracy levels while achieving up to 99%\\nkeys/values cache reduction and up to 3.5 times faster inference. Despite a\\nminor compromise in accuracy, the substantial enhancements of AnLLMs employing\\nthe AnSAN technique in resource utilization and computational efficiency\\nunderscore their potential for practical LLM applications.\\nLink: http://arxiv.org/abs/2402.07616v2\\n\\n\\nTitle: T-RAG: Lessons from the LLM Trenches\\nAuthors: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla\\nAbstract: Large Language Models (LLM) have shown remarkable language capabilities\\nfueling attempts to integrate them into applications across a wide range of\\ndomains. An important application area is question answering over private\\nenterprise documents where the main considerations are data security, which\\nnecessitates applications that can be deployed on-prem, limited computational\\nresources and the need for a robust application that correctly responds to\\nqueries. Retrieval-Augmented Generation (RAG) has emerged as the most prominent\\nframework for building LLM-based applications. While building a RAG is\\nrelatively straightforward, making it robust and a reliable application\\nrequires extensive customization and relatively deep knowledge of the\\napplication domain. We share our experiences building and deploying an LLM\\napplication for question answering over private organizational documents. Our\\napplication combines the use of RAG with a finetuned open-source LLM.\\nAdditionally, our system, which we call Tree-RAG (T-RAG), uses a tree structure\\nto represent entity hierarchies within the organization. This is used to\\ngenerate a textual description to augment the context when responding to user\\nqueries pertaining to entities within the organization's hierarchy. Our\\nevaluations show that this combination performs better than a simple RAG or\\nfinetuning implementation. Finally, we share some lessons learned based on our\\nexperiences building an LLM application for real-world use.\\nLink: http://arxiv.org/abs/2402.07483v1\\n\\n\\n\", 'name': 'Retrieve_Action_2', 'role': 'user'}, {'content': \"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", 'name': 'Research_Action_1', 'role': 'user'}], summary=\"Based on the retrieved abstracts, here is a markdown table categorizing the papers by domain, along with their titles, authors, summaries, and links:\\n\\n| Domain | Title | Authors | Summary | Link |\\n|--------|-------|---------|---------|------|\\n| Security | PRSA: Prompt Reverse Stealing Attacks against Large Language Models | Yong Yang, Xuhong Zhang, Yi Jiang, Xi Chen, Haoyu Wang, Shouling Ji, Zonghui Wang | The paper explores the security risks associated with exposing input-output pairs of prompts used in LLMs and proposes a novel attack framework, PRSA, to reverse-steal prompts, posing a threat to intellectual property rights. | [Link](http://arxiv.org/abs/2402.19200v1) |\\n| Ethics & Evaluation | Political Compass or Spinning Arrow? Towards More Meaningful Evaluations for Values and Opinions in Large Language Models | Paul Röttger, Valentin Hofmann, Valentina Pyatkin, Musashi Hinck, Hannah Rose Kirk, Hinrich Schütze, Dirk Hovy | This work challenges the constrained evaluation paradigm for values and opinions in LLMs and explores more realistic unconstrained evaluations, focusing on the Political Compass Test (PCT). | [Link](http://arxiv.org/abs/2402.16786v1) |\\n| Urban Mobility | Large Language Models as Urban Residents: An LLM Agent Framework for Personal Mobility Generation | Jiawei Wang, Renhe Jiang, Chuang Yang, Zengqing Wu, Makoto Onizuka, Ryosuke Shibasaki, Chuan Xiao | Introduces an LLM agent framework for personal mobility generation, aligning LLMs with real-world urban mobility data, and offering a tool for urban mobility analysis. | [Link](http://arxiv.org/abs/2402.14744v1) |\\n| Bioinformatics | An Evaluation of Large Language Models in Bioinformatics Research | Hengchuang Yin, Zhonghui Gu, Fanhao Wang, Yiparemu Abuduhaibaier, Yanqiao Zhu, Xinming Tu, Xian-Sheng Hua, Xiao Luo, Yizhou Sun | Evaluates the performance of LLMs on bioinformatics tasks, highlighting their potential and limitations, and motivating future research in LLM applications in bioinformatics. | [Link](http://arxiv.org/abs/2402.13714v1) |\\n| Privacy | Privacy-Preserving Instructions for Aligning Large Language Models | Da Yu, Peter Kairouz, Sewoong Oh, Zheng Xu | Proposes using synthetic instructions generated by privately fine-tuned generators to replace real instructions in data annotation and model fine-tuning, ensuring privacy while maintaining utility. | [Link](http://arxiv.org/abs/2402.13659v1) |\\n| Social Robotics | Ain't Misbehavin' -- Using LLMs to Generate Expressive Robot Behavior in Conversations with the Tabletop Robot Haru | Zining Wang, Paul Reisert, Eric Nichols, Randy Gomez | Integrates LLMs into social robots to generate dynamic and expressive conversations, using a text-to-speech engine and a library of physical actions for the robot. | [Link](http://arxiv.org/abs/2402.11571v1) |\\n| Ophthalmology | Fine-tuning Large Language Model (LLM) Artificial Intelligence Chatbots in Ophthalmology and LLM-based evaluation using GPT-4 | Ting Fang Tan, Kabilan Elangovan, Liyuan Jin, Yao Jie, Li Yong, Joshua Lim, Stanley Poh, Wei Yan Ng, Daniel Lim, Yuhe Ke, Nan Liu, Daniel Shu Wei Ting | Assesses the alignment of GPT-4-based evaluation to human clinician experts for evaluating responses to ophthalmology-related patient queries generated by fine-tuned LLM chatbots. | [Link](http://arxiv.org/abs/2402.10083v1) |\\n| Privacy & Data Security | Unmemorization in Large Language Models via Self-Distillation and Deliberate Imagination | Yijiang River Dong, Hongzhou Lin, Mikhail Belkin, Ramon Huerta, Ivan Vulić | Introduces a novel approach for LLM unlearning by guiding LLMs to imagine alternative scenarios, effectively unlearning targeted text while preserving generation and NLU capabilities. | [Link](http://arxiv.org/abs/2402.10052v1) |\\n| Computational Efficiency | Anchor-based Large Language Models | Jianhui Pang, Fanghua Ye, Derek F. Wong, Longyue Wang | Proposes Anchor-based LLMs (AnLLMs) with an innovative anchor-based self-attention network (AnSAN) to reduce memory demand and enhance inference efficiency. | [Link](http://arxiv.org/abs/2402.07616v2) |\\n| Enterprise Applications | T-RAG: Lessons from the LLM Trenches | Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla | Shares experiences building and deploying an LLM application for question answering over private organizational documents, combining RAG with a finetuned LLM and a tree structure for entity hierarchies. | [Link](http://arxiv.org/abs/2402.07483v1) |\\n\\nThese papers cover a range of domains including security, ethics, urban mobility, bioinformatics, privacy, social robotics, ophthalmology, data security, computational efficiency, and enterprise applications, showcasing the diverse applications of large language models.\", cost=({'total_cost': 0}, {'total_cost': 0}), human_input=[])" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "initializer.initiate_chat(\n", - " manager, message=\"Topic: LLM applications papers from last week. Requirement: 5 - 10 papers from different domains.\"\n", - ")" - ] - }, { "cell_type": "markdown", "metadata": {}, From d238c227b28a451f9f7877280eca67abfeabb1d3 Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:12:53 -0400 Subject: [PATCH 07/10] remove changes to conversation pattern --- .../docs/tutorial/conversation-patterns.ipynb | 3192 ++++++++--------- 1 file changed, 1596 insertions(+), 1596 deletions(-) diff --git a/website/docs/tutorial/conversation-patterns.ipynb b/website/docs/tutorial/conversation-patterns.ipynb index a5dbecbad6ff..eb79dd27fc37 100644 --- a/website/docs/tutorial/conversation-patterns.ipynb +++ b/website/docs/tutorial/conversation-patterns.ipynb @@ -1,1598 +1,1598 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Conversation Patterns\n", - "\n", - "In the previous chapter we used two-agent conversation, which\n", - "can be started by the `initiate_chat` method.\n", - "Two-agent chat is a useful conversation pattern but AutoGen offers more.\n", - "In this chapter, we will first dig a little bit more into the two-agent \n", - "chat pattern and chat result, \n", - "then we will show you several conversation patterns that involve \n", - "more than two agents.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Two-Agent Chat and Chat Result\n", - "\n", - "Two-agent chat is the simplest from of conversation pattern. \n", - "We start a two-agent chat using the `initiate_chat` method of every \n", - "`ConversableAgent` agent.\n", - "We have already\n", - "seen multiple examples of two-agent chats in previous chapters\n", - "but we haven't covered the details.\n", - "\n", - "The following figure illustrates how two-agent chat works.\n", - "\n", - "```{=mdx}\n", - "![Two-agent chat](./assets/two-agent-chat.png)\n", - "```\n", - "\n", - "A two-agent chats takes two inputs: a message, which is a string provided by\n", - "the caller; a context, which specifies various parameters of the chat.\n", - "The sender agent uses its chat initializer method\n", - "(i.e., `generate_init_message` method of `ConversableAgent`)\n", - "to generate an initial message from the inputs, and\n", - "sends it to the recipient agent to start the chat.\n", - "The sender agent is the agent whose `initiate_chat` method is called, and\n", - "the recipient agent is the other agent.\n", - "\n", - "Once the chat terminates, the history of the chat is processed by a \n", - "chat summarizer. The summarizer summarizes the chat history and calculates\n", - "the token usage of the chat. \n", - "You can configure the type of summary using the `summary_method`\n", - "parameter of the `initiate_chat` method. By default, it is the last\n", - "message of the chat (i.e., `summary_method='last_msg'`).\n", - "\n", - "The example below is a two-agent chat between a student agent and a teacher\n", - "agent. Its summarizer uses an LLM-based summary." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", - "\n", - "What is triangle inequality?\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", - "\n", - "Triangle inequality theorem is a fundamental principle in geometry that states that the sum of the lengths of any two sides of a triangle must always be greater than the length of the third side. In a triangle with sides of lengths a, b, and c, the theorem can be written as:\n", - "\n", - "a + b > c\n", - "a + c > b\n", - "b + c > a\n", - "\n", - "Each of these represents the condition for one specific side (a, b, or c). All must be true for a triangle to exist.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", - "\n", - "Thank you for the explanation. This theorem helps in understanding the basic properties of a triangle. It can also be useful when solving geometric problems or proving other mathematical theorems. Can you give me an example of how we can use the triangle inequality theorem?\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", - "\n", - "Absolutely! Here's an example:\n", - "\n", - "Suppose you're given three line segments with lengths 10, 7, and 3 units. The question is: \"Can these three line segments form a triangle?\"\n", - "\n", - "To answer this, you would use the triangle inequality theorem. Adding any two side lengths together should be greater than the third:\n", - "\n", - "- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\n", - "- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\n", - "- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of the third side (10), but not greater.\n", - "\n", - "So, these three lines cannot form a triangle, because not all pairs of sides satisfy the triangle inequality theorem.\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "import os\n", - "from autogen import ConversableAgent\n", - "\n", - "student_agent = ConversableAgent(\n", - " name=\"Student_Agent\",\n", - " system_message=\"You are a student willing to learn.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "teacher_agent = ConversableAgent(\n", - " name=\"Teacher_Agent\",\n", - " system_message=\"You are a math teacher.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "chat_result = student_agent.initiate_chat(\n", - " teacher_agent,\n", - " message=\"What is triangle inequality?\",\n", - " summary_method=\"reflection_with_llm\",\n", - " max_turns=2,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's see what the summary looks like.\n", - "The summary is stored in the `chat_result` object of the type `ChatResult` \n", - "that was returned by the `initiate_chat` method." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The triangle inequality theorem states that in a triangle, the sum of the lengths of any two sides must always be greater than the length of the third side. This principle is significant in geometry and is used in solving problems or proving theorems. For instance, if given three line segments, you can determine if they can form a triangle using this theorem.\n" - ] - } - ], - "source": [ - "print(chat_result.summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above example, the summary method is set to `reflection_with_llm` which\n", - "takes a list of messages from the conversation and summarize them \n", - "using a call to an LLM.\n", - "The summary method first tries to use the recipient's LLM, if it is not available\n", - "then it uses the sender's LLM. In this case the recipient is \"Teacher_Agent\" and\n", - "the sender is \"Student_Agent\".\n", - "The input prompt for the LLM is the following default prompt:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Summarize the takeaway from the conversation. Do not add any introductory phrases.\n" - ] - } - ], - "source": [ - "print(ConversableAgent.DEFAULT_summary_prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also use a custom prompt by setting the `summary_prompt` argument\n", - "of `initiate_chat`.\n", - "\n", - "There are some other useful information in the `ChatResult` object, including\n", - "the conversation history, human input, and token cost." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[{'content': 'What is triangle inequality?', 'role': 'assistant'},\n", - " {'content': 'Triangle inequality theorem is a fundamental principle in '\n", - " 'geometry that states that the sum of the lengths of any two '\n", - " 'sides of a triangle must always be greater than the length of '\n", - " 'the third side. In a triangle with sides of lengths a, b, and c, '\n", - " 'the theorem can be written as:\\n'\n", - " '\\n'\n", - " 'a + b > c\\n'\n", - " 'a + c > b\\n'\n", - " 'b + c > a\\n'\n", - " '\\n'\n", - " 'Each of these represents the condition for one specific side (a, '\n", - " 'b, or c). All must be true for a triangle to exist.',\n", - " 'role': 'user'},\n", - " {'content': 'Thank you for the explanation. This theorem helps in '\n", - " 'understanding the basic properties of a triangle. It can also be '\n", - " 'useful when solving geometric problems or proving other '\n", - " 'mathematical theorems. Can you give me an example of how we can '\n", - " 'use the triangle inequality theorem?',\n", - " 'role': 'assistant'},\n", - " {'content': \"Absolutely! Here's an example:\\n\"\n", - " '\\n'\n", - " \"Suppose you're given three line segments with lengths 10, 7, and \"\n", - " '3 units. The question is: \"Can these three line segments form a '\n", - " 'triangle?\"\\n'\n", - " '\\n'\n", - " 'To answer this, you would use the triangle inequality theorem. '\n", - " 'Adding any two side lengths together should be greater than the '\n", - " 'third:\\n'\n", - " '\\n'\n", - " '- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\\n'\n", - " '- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\\n'\n", - " '- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of '\n", - " 'the third side (10), but not greater.\\n'\n", - " '\\n'\n", - " 'So, these three lines cannot form a triangle, because not all '\n", - " 'pairs of sides satisfy the triangle inequality theorem.',\n", - " 'role': 'user'}]\n" - ] - } - ], - "source": [ - "# Get the chat history.\n", - "import pprint\n", - "\n", - "pprint.pprint(chat_result.chat_history)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "That chat messages in the chat result are from the \n", - "recipient agent's perspective -- the sender is the \"assistant\" and the recipient\n", - "is the \"user\"." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "({'gpt-4-0613': {'completion_tokens': 399,\n", - " 'cost': 0.04521,\n", - " 'prompt_tokens': 709,\n", - " 'total_tokens': 1108},\n", - " 'total_cost': 0.04521},\n", - " {'total_cost': 0})\n" - ] - } - ], - "source": [ - "# Get the cost of the chat.\n", - "pprint.pprint(chat_result.cost)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Sequential Chats\n", - "\n", - "The name of this pattern is self-explanatory -- it is a sequence of\n", - "chats between two agents, chained together by a mechanism called *carryover*,\n", - "which brings the summary of the previous chat to the context\n", - "of the next chat.\n", - "\n", - "This pattern is useful for complex task that can be broken down into \n", - "interdependent sub-tasks. \n", - "The figure below illustrate how this pattern works.\n", - "\n", - "```{=mdx}\n", - "![initiate_chats](./assets/sequential-two-agent-chat.png)\n", - "```\n", - "\n", - "In this pattern, the a pair of agents first start a two-agent chat,\n", - "then the summary of the conversation becomes a *carryover* for the next\n", - "two-agent chat. The next chat passes the carryover to the `carryover` parameter\n", - "of the context to generate its initial message.\n", - "\n", - "Carryover accumulates as the conversation moves forward,,\n", - "so each subsequent chat starts with all the carryovers \n", - "from previous chats.\n", - "\n", - "The figure above shows distinct recipient agents for all the chats, however,\n", - "the recipient agents in the sequence are allowed to repeat." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To illustrate this pattern, let's consider a simple example of arithmetic\n", - "operator agents. One agent \n", - "(called the \"Number_Agent\") is responsible for coming up with a number,\n", - "and other agents are responsible for performing a specific arithmetic\n", - "operation on the number, e.g., add 1, multiply by 2, etc.." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "# The Number Agent always returns the same numbers.\n", - "number_agent = ConversableAgent(\n", - " name=\"Number_Agent\",\n", - " system_message=\"You return me the numbers I give you, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Adder Agent adds 1 to each number it receives.\n", - "adder_agent = ConversableAgent(\n", - " name=\"Adder_Agent\",\n", - " system_message=\"You add 1 to each number I give you and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Multiplier Agent multiplies each number it receives by 2.\n", - "multiplier_agent = ConversableAgent(\n", - " name=\"Multiplier_Agent\",\n", - " system_message=\"You multiply each number I give you by 2 and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Subtracter Agent subtracts 1 from each number it receives.\n", - "subtracter_agent = ConversableAgent(\n", - " name=\"Subtracter_Agent\",\n", - " system_message=\"You subtract 1 from each number I give you and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Divider Agent divides each number it receives by 2.\n", - "divider_agent = ConversableAgent(\n", - " name=\"Divider_Agent\",\n", - " system_message=\"You divide each number I give you by 2 and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Number Agent chats with the first operator agent, then the second\n", - "operator agent, and so on.\n", - "After each chat, the last message in the conversation (i.e., the result of the arithmetic operation from the operator agent)\n", - "is used as the summary of the chat.\n", - "This is specified by the `summary_method` parameter.\n", - "In the end we will have the result of the arithmetic operations." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "14\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "16\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "32\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", - "\n", - "32\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "64\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\n", - "64\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "64\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "15\n", - "63\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", - "\n", - "15\n", - "63\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "14\n", - "62\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\n", - "64\n", - "14\n", - "62\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "64\n", - "14\n", - "62\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "8\n", - "32\n", - "7\n", - "31\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", - "\n", - "8\n", - "32\n", - "7\n", - "31\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "4\n", - "16\n", - "3.5\n", - "15.5\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "# Start a sequence of two-agent chats.\n", - "# Each element in the list is a dictionary that specifies the arguments\n", - "# for the initiate_chat method.\n", - "chat_results = number_agent.initiate_chats(\n", - " [\n", - " {\n", - " \"recipient\": adder_agent,\n", - " \"message\": \"14\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": multiplier_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": subtracter_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": divider_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First thing to note is that the `initiate_chats` method takes a list of\n", - "dictionaries, each dictionary contains the arguments for the `initiate_chat`\n", - "method.\n", - "\n", - "Second, each chat in the sequence has a maximum round of 2, as specified with\n", - "the setting `max_turns=2`, \n", - "which means each arithmetic operation is performed twice.\n", - "So you can see in the first chat the number 14 becomes 15 and then 16,\n", - "in the second chat the number 16 becomes 32 and then 64, and so on.\n", - "\n", - "Third, the carryover accumulates as the chats go on. In the second chat,\n", - "the carryover is the summary of the first chat \"16\".\n", - "In the third chat, the carryover is the summary of the first and second\n", - "chat, which is the list \"16\" and \"64\", and both numbers are operated upon.\n", - "In the forth and last chat, the carryover is the summary of all previous\n", - "chats, which is the list \"16\", \"64\", \"14\" and \"62\", and all of these\n", - "numbers are operated upon.\n", - "\n", - "The final note is that the `initiate_chats` method returns a list of\n", - "`ChatResult` objects, one for each chat in the sequence." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "First Chat Summary: 16\n", - "Second Chat Summary: 64\n", - "Third Chat Summary: 14\n", - "62\n", - "Fourth Chat Summary: 4\n", - "16\n", - "3.5\n", - "15.5\n" - ] - } - ], - "source": [ - "print(\"First Chat Summary: \", chat_results[0].summary)\n", - "print(\"Second Chat Summary: \", chat_results[1].summary)\n", - "print(\"Third Chat Summary: \", chat_results[2].summary)\n", - "print(\"Fourth Chat Summary: \", chat_results[3].summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Besides calling `initiate_chats` from the same sender agent, you can also\n", - "call a high-level function `autogen.agentchat.initiate_chats` to start\n", - "a sequence of two-agent chats with different sender agents. \n", - "This function allows you to specify the\n", - "sender agent for each chat in the sequence." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Group Chat\n", - "\n", - "So far we have only seen conversation patterns that involve two agents or \n", - "a sequence of two-agent chats. AutoGen provides a more general conversation\n", - "pattern called group chat, which involves more than two agents.\n", - "The core idea of group chat is that all agents contribute to a single\n", - "conversation thread and share the same context.\n", - "This is useful for tasks that require collaboration among multiple agents.\n", - "\n", - "The figure below illustrates how group chat works.\n", - "\n", - "```{=mdx}\n", - "![group_chat](./assets/group-chat.png)\n", - "```\n", - "\n", - "A group chat is orchestrated by a special\n", - "agent type `GroupChatManager`. In the first step of the group chat,\n", - "the Group Chat Manager selects an agent to speak. Then, the selected agent\n", - "speaks and the message is sent back to the Group Chat Manager,\n", - "who **broadcasts** the message to all other agents in the group.\n", - "This process repeats until the conversation stops.\n", - "\n", - "The Group Chat Manager can use several strategies to select the next agent.\n", - "Currently, the following strategies are supported:\n", - "\n", - "1. `round_robin`: The Group Chat Manager selects agents in a round-robin\n", - " fashion based on the order of the agents provided.\n", - "2. `random`: The Group Chat Manager selects agents randomly.\n", - "3. `manual`: The Group Chat Manager selects agents by asking for human input.\n", - "4. `auto`: The default strategy, which selects agents using the Group Chat\n", - " Manager's LLM." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To illustrate this pattern, let's consider a simple example of a group chat\n", - "among the same arithmetic operator agents as in the previous example,\n", - "with the objective of turning a number into a specific target number\n", - "using a sequence of arithmetic operations powered by the agents.\n", - "\n", - "In this example, we use the `auto` strategy to select the next agent.\n", - "To help the Group Chat Manager select the next agent, we also set the\n", - "`description` of the agents. Without the `description`, the Group Chat Manager\n", - "will use the agents' `system_message`, which may be not be the best choice." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# The `description` attribute is a string that describes the agent.\n", - "# It can also be set in `ConversableAgent` constructor.\n", - "adder_agent.description = \"Add 1 to each input number.\"\n", - "multiplier_agent.description = \"Multiply each input number by 2.\"\n", - "subtracter_agent.description = \"Subtract 1 from each input number.\"\n", - "divider_agent.description = \"Divide each input number by 2.\"\n", - "number_agent.description = \"Return the numbers given.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We first create a `GroupChat` object and provide the list of agents.\n", - "If we were to use the `round_robin` strategy, this list would specify the order\n", - "of the agents to be selected.\n", - "We also initialize the group chat with an empty message list and a maximum\n", - "round of 6, which means there will be at most 6 iteratiosn of selecting speaker,\n", - "agent speaks and broadcasting message." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "from autogen import GroupChat\n", - "\n", - "group_chat = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " messages=[],\n", - " max_round=6,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we create a `GroupChatManager` object and provide the `GroupChat` object as\n", - "input. We also need to specify the `llm_config` of the Group Chat Manager\n", - "so it can use the LLM to select the next agent (the `auto` strategy)." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "from autogen import GroupChatManager\n", - "\n", - "group_chat_manager = GroupChatManager(\n", - " groupchat=group_chat,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we have the Number Agent from before to start a two-agent chat with\n", - "the Group Chat Manager, which runs the group chat internally and terminates\n", - "the two-agent chat when the internal group chat is done.\n", - "Because the Number Agent is selected to speak by us, it counts as the \n", - "first round of the group chat." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "6\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "chat_result = number_agent.initiate_chat(\n", - " group_chat_manager,\n", - " message=\"My number is 3, I want to turn it into 13.\",\n", - " summary_method=\"reflection_with_llm\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can see that the Number Agent is selected to speak first, then the\n", - "Group Chat Manager selects the Multiplier Agent to speak, then the Adder\n", - "Agent, and so on. The number is operated upon by each agent in the group\n", - "chat, and the final result is 13.\n", - "\n", - "We can take a look at the summary of the group chat, provided by the \n", - "`ChatResult` object returned by the `initiate_chat` method." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The agents cooperatively manipulated the initial number (3) through multipliying, adding, and subtracting operations to reach the target number (13).\n" - ] - } - ], - "source": [ - "print(chat_result.summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Send Introductions\n", - "\n", - "In the previous example, we set the `description` of the agents to help the\n", - "Group Chat Manager select the next agent. This only helps the Group Chat Manager,\n", - "however, does not help the participating agents to know about each other.\n", - "Sometimes it is useful have each agent introduce themselves to other\n", - "agents in the group chat. This can be done by setting the `send_introductions=True`." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "group_chat_with_introductions = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " messages=[],\n", - " max_round=6,\n", - " send_introductions=True,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Under the hood, the Group Chat Manager sends a message containing the \n", - "agents' names and descriptions to all agents in the group chat before the\n", - "group chat starts." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Group Chat in a Sequential Chat\n", - "\n", - "Group chat can also be used as a part of a sequential chat.\n", - "In this case, the Group Chat Manager is treated as a regular agent\n", - "in the sequence of two-agent chats." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "6\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "Your number is 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Turn this number to 32.\n", - "\n", - "With the following carryover: \n", - "Your number is 13.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "Turn this number to 32.\n", - "Context: \n", - "Your number is 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "26\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "28\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "30\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conversation Patterns\n", + "\n", + "In the previous chapter we used two-agent conversation, which\n", + "can be started by the `initiate_chat` method.\n", + "Two-agent chat is a useful conversation pattern but AutoGen offers more.\n", + "In this chapter, we will first dig a little bit more into the two-agent \n", + "chat pattern and chat result, \n", + "then we will show you several conversation patterns that involve \n", + "more than two agents.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Two-Agent Chat and Chat Result\n", + "\n", + "Two-agent chat is the simplest from of conversation pattern. \n", + "We start a two-agent chat using the `initiate_chat` method of every \n", + "`ConversableAgent` agent.\n", + "We have already\n", + "seen multiple examples of two-agent chats in previous chapters\n", + "but we haven't covered the details.\n", + "\n", + "The following figure illustrates how two-agent chat works.\n", + "\n", + "```{=mdx}\n", + "![Two-agent chat](./assets/two-agent-chat.png)\n", + "```\n", + "\n", + "A two-agent chats takes two inputs: a message, which is a string provided by\n", + "the caller; a context, which specifies various parameters of the chat.\n", + "The sender agent uses its chat initializer method\n", + "(i.e., `generate_init_message` method of `ConversableAgent`)\n", + "to generate an initial message from the inputs, and\n", + "sends it to the recipient agent to start the chat.\n", + "The sender agent is the agent whose `initiate_chat` method is called, and\n", + "the recipient agent is the other agent.\n", + "\n", + "Once the chat terminates, the history of the chat is processed by a \n", + "chat summarizer. The summarizer summarizes the chat history and calculates\n", + "the token usage of the chat. \n", + "You can configure the type of summary using the `summary_method`\n", + "parameter of the `initiate_chat` method. By default, it is the last\n", + "message of the chat (i.e., `summary_method='last_msg'`).\n", + "\n", + "The example below is a two-agent chat between a student agent and a teacher\n", + "agent. Its summarizer uses an LLM-based summary." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", + "\n", + "What is triangle inequality?\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", + "\n", + "Triangle inequality theorem is a fundamental principle in geometry that states that the sum of the lengths of any two sides of a triangle must always be greater than the length of the third side. In a triangle with sides of lengths a, b, and c, the theorem can be written as:\n", + "\n", + "a + b > c\n", + "a + c > b\n", + "b + c > a\n", + "\n", + "Each of these represents the condition for one specific side (a, b, or c). All must be true for a triangle to exist.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", + "\n", + "Thank you for the explanation. This theorem helps in understanding the basic properties of a triangle. It can also be useful when solving geometric problems or proving other mathematical theorems. Can you give me an example of how we can use the triangle inequality theorem?\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", + "\n", + "Absolutely! Here's an example:\n", + "\n", + "Suppose you're given three line segments with lengths 10, 7, and 3 units. The question is: \"Can these three line segments form a triangle?\"\n", + "\n", + "To answer this, you would use the triangle inequality theorem. Adding any two side lengths together should be greater than the third:\n", + "\n", + "- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\n", + "- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\n", + "- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of the third side (10), but not greater.\n", + "\n", + "So, these three lines cannot form a triangle, because not all pairs of sides satisfy the triangle inequality theorem.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "import os\n", + "from autogen import ConversableAgent\n", + "\n", + "student_agent = ConversableAgent(\n", + " name=\"Student_Agent\",\n", + " system_message=\"You are a student willing to learn.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "teacher_agent = ConversableAgent(\n", + " name=\"Teacher_Agent\",\n", + " system_message=\"You are a math teacher.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "chat_result = student_agent.initiate_chat(\n", + " teacher_agent,\n", + " message=\"What is triangle inequality?\",\n", + " summary_method=\"reflection_with_llm\",\n", + " max_turns=2,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what the summary looks like.\n", + "The summary is stored in the `chat_result` object of the type `ChatResult` \n", + "that was returned by the `initiate_chat` method." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The triangle inequality theorem states that in a triangle, the sum of the lengths of any two sides must always be greater than the length of the third side. This principle is significant in geometry and is used in solving problems or proving theorems. For instance, if given three line segments, you can determine if they can form a triangle using this theorem.\n" + ] + } + ], + "source": [ + "print(chat_result.summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above example, the summary method is set to `reflection_with_llm` which\n", + "takes a list of messages from the conversation and summarize them \n", + "using a call to an LLM.\n", + "The summary method first tries to use the recipient's LLM, if it is not available\n", + "then it uses the sender's LLM. In this case the recipient is \"Teacher_Agent\" and\n", + "the sender is \"Student_Agent\".\n", + "The input prompt for the LLM is the following default prompt:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Summarize the takeaway from the conversation. Do not add any introductory phrases.\n" + ] + } + ], + "source": [ + "print(ConversableAgent.DEFAULT_summary_prompt)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also use a custom prompt by setting the `summary_prompt` argument\n", + "of `initiate_chat`.\n", + "\n", + "There are some other useful information in the `ChatResult` object, including\n", + "the conversation history, human input, and token cost." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'content': 'What is triangle inequality?', 'role': 'assistant'},\n", + " {'content': 'Triangle inequality theorem is a fundamental principle in '\n", + " 'geometry that states that the sum of the lengths of any two '\n", + " 'sides of a triangle must always be greater than the length of '\n", + " 'the third side. In a triangle with sides of lengths a, b, and c, '\n", + " 'the theorem can be written as:\\n'\n", + " '\\n'\n", + " 'a + b > c\\n'\n", + " 'a + c > b\\n'\n", + " 'b + c > a\\n'\n", + " '\\n'\n", + " 'Each of these represents the condition for one specific side (a, '\n", + " 'b, or c). All must be true for a triangle to exist.',\n", + " 'role': 'user'},\n", + " {'content': 'Thank you for the explanation. This theorem helps in '\n", + " 'understanding the basic properties of a triangle. It can also be '\n", + " 'useful when solving geometric problems or proving other '\n", + " 'mathematical theorems. Can you give me an example of how we can '\n", + " 'use the triangle inequality theorem?',\n", + " 'role': 'assistant'},\n", + " {'content': \"Absolutely! Here's an example:\\n\"\n", + " '\\n'\n", + " \"Suppose you're given three line segments with lengths 10, 7, and \"\n", + " '3 units. The question is: \"Can these three line segments form a '\n", + " 'triangle?\"\\n'\n", + " '\\n'\n", + " 'To answer this, you would use the triangle inequality theorem. '\n", + " 'Adding any two side lengths together should be greater than the '\n", + " 'third:\\n'\n", + " '\\n'\n", + " '- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\\n'\n", + " '- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\\n'\n", + " '- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of '\n", + " 'the third side (10), but not greater.\\n'\n", + " '\\n'\n", + " 'So, these three lines cannot form a triangle, because not all '\n", + " 'pairs of sides satisfy the triangle inequality theorem.',\n", + " 'role': 'user'}]\n" + ] + } + ], + "source": [ + "# Get the chat history.\n", + "import pprint\n", + "\n", + "pprint.pprint(chat_result.chat_history)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That chat messages in the chat result are from the \n", + "recipient agent's perspective -- the sender is the \"assistant\" and the recipient\n", + "is the \"user\"." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "({'gpt-4-0613': {'completion_tokens': 399,\n", + " 'cost': 0.04521,\n", + " 'prompt_tokens': 709,\n", + " 'total_tokens': 1108},\n", + " 'total_cost': 0.04521},\n", + " {'total_cost': 0})\n" + ] + } + ], + "source": [ + "# Get the cost of the chat.\n", + "pprint.pprint(chat_result.cost)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sequential Chats\n", + "\n", + "The name of this pattern is self-explanatory -- it is a sequence of\n", + "chats between two agents, chained together by a mechanism called *carryover*,\n", + "which brings the summary of the previous chat to the context\n", + "of the next chat.\n", + "\n", + "This pattern is useful for complex task that can be broken down into \n", + "interdependent sub-tasks. \n", + "The figure below illustrate how this pattern works.\n", + "\n", + "```{=mdx}\n", + "![initiate_chats](./assets/sequential-two-agent-chat.png)\n", + "```\n", + "\n", + "In this pattern, the a pair of agents first start a two-agent chat,\n", + "then the summary of the conversation becomes a *carryover* for the next\n", + "two-agent chat. The next chat passes the carryover to the `carryover` parameter\n", + "of the context to generate its initial message.\n", + "\n", + "Carryover accumulates as the conversation moves forward,,\n", + "so each subsequent chat starts with all the carryovers \n", + "from previous chats.\n", + "\n", + "The figure above shows distinct recipient agents for all the chats, however,\n", + "the recipient agents in the sequence are allowed to repeat." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To illustrate this pattern, let's consider a simple example of arithmetic\n", + "operator agents. One agent \n", + "(called the \"Number_Agent\") is responsible for coming up with a number,\n", + "and other agents are responsible for performing a specific arithmetic\n", + "operation on the number, e.g., add 1, multiply by 2, etc.." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# The Number Agent always returns the same numbers.\n", + "number_agent = ConversableAgent(\n", + " name=\"Number_Agent\",\n", + " system_message=\"You return me the numbers I give you, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Adder Agent adds 1 to each number it receives.\n", + "adder_agent = ConversableAgent(\n", + " name=\"Adder_Agent\",\n", + " system_message=\"You add 1 to each number I give you and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Multiplier Agent multiplies each number it receives by 2.\n", + "multiplier_agent = ConversableAgent(\n", + " name=\"Multiplier_Agent\",\n", + " system_message=\"You multiply each number I give you by 2 and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Subtracter Agent subtracts 1 from each number it receives.\n", + "subtracter_agent = ConversableAgent(\n", + " name=\"Subtracter_Agent\",\n", + " system_message=\"You subtract 1 from each number I give you and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Divider Agent divides each number it receives by 2.\n", + "divider_agent = ConversableAgent(\n", + " name=\"Divider_Agent\",\n", + " system_message=\"You divide each number I give you by 2 and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Number Agent chats with the first operator agent, then the second\n", + "operator agent, and so on.\n", + "After each chat, the last message in the conversation (i.e., the result of the arithmetic operation from the operator agent)\n", + "is used as the summary of the chat.\n", + "This is specified by the `summary_method` parameter.\n", + "In the end we will have the result of the arithmetic operations." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "14\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "16\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "32\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", + "\n", + "32\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "64\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\n", + "64\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "64\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "15\n", + "63\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", + "\n", + "15\n", + "63\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "14\n", + "62\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\n", + "64\n", + "14\n", + "62\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "64\n", + "14\n", + "62\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "8\n", + "32\n", + "7\n", + "31\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", + "\n", + "8\n", + "32\n", + "7\n", + "31\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "4\n", + "16\n", + "3.5\n", + "15.5\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "# Start a sequence of two-agent chats.\n", + "# Each element in the list is a dictionary that specifies the arguments\n", + "# for the initiate_chat method.\n", + "chat_results = number_agent.initiate_chats(\n", + " [\n", + " {\n", + " \"recipient\": adder_agent,\n", + " \"message\": \"14\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": multiplier_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": subtracter_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": divider_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First thing to note is that the `initiate_chats` method takes a list of\n", + "dictionaries, each dictionary contains the arguments for the `initiate_chat`\n", + "method.\n", + "\n", + "Second, each chat in the sequence has a maximum round of 2, as specified with\n", + "the setting `max_turns=2`, \n", + "which means each arithmetic operation is performed twice.\n", + "So you can see in the first chat the number 14 becomes 15 and then 16,\n", + "in the second chat the number 16 becomes 32 and then 64, and so on.\n", + "\n", + "Third, the carryover accumulates as the chats go on. In the second chat,\n", + "the carryover is the summary of the first chat \"16\".\n", + "In the third chat, the carryover is the summary of the first and second\n", + "chat, which is the list \"16\" and \"64\", and both numbers are operated upon.\n", + "In the forth and last chat, the carryover is the summary of all previous\n", + "chats, which is the list \"16\", \"64\", \"14\" and \"62\", and all of these\n", + "numbers are operated upon.\n", + "\n", + "The final note is that the `initiate_chats` method returns a list of\n", + "`ChatResult` objects, one for each chat in the sequence." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First Chat Summary: 16\n", + "Second Chat Summary: 64\n", + "Third Chat Summary: 14\n", + "62\n", + "Fourth Chat Summary: 4\n", + "16\n", + "3.5\n", + "15.5\n" + ] + } + ], + "source": [ + "print(\"First Chat Summary: \", chat_results[0].summary)\n", + "print(\"Second Chat Summary: \", chat_results[1].summary)\n", + "print(\"Third Chat Summary: \", chat_results[2].summary)\n", + "print(\"Fourth Chat Summary: \", chat_results[3].summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Besides calling `initiate_chats` from the same sender agent, you can also\n", + "call a high-level function `autogen.agentchat.initiate_chats` to start\n", + "a sequence of two-agent chats with different sender agents. \n", + "This function allows you to specify the\n", + "sender agent for each chat in the sequence." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Group Chat\n", + "\n", + "So far we have only seen conversation patterns that involve two agents or \n", + "a sequence of two-agent chats. AutoGen provides a more general conversation\n", + "pattern called group chat, which involves more than two agents.\n", + "The core idea of group chat is that all agents contribute to a single\n", + "conversation thread and share the same context.\n", + "This is useful for tasks that require collaboration among multiple agents.\n", + "\n", + "The figure below illustrates how group chat works.\n", + "\n", + "```{=mdx}\n", + "![group_chat](./assets/group-chat.png)\n", + "```\n", + "\n", + "A group chat is orchestrated by a special\n", + "agent type `GroupChatManager`. In the first step of the group chat,\n", + "the Group Chat Manager selects an agent to speak. Then, the selected agent\n", + "speaks and the message is sent back to the Group Chat Manager,\n", + "who **broadcasts** the message to all other agents in the group.\n", + "This process repeats until the conversation stops.\n", + "\n", + "The Group Chat Manager can use several strategies to select the next agent.\n", + "Currently, the following strategies are supported:\n", + "\n", + "1. `round_robin`: The Group Chat Manager selects agents in a round-robin\n", + " fashion based on the order of the agents provided.\n", + "2. `random`: The Group Chat Manager selects agents randomly.\n", + "3. `manual`: The Group Chat Manager selects agents by asking for human input.\n", + "4. `auto`: The default strategy, which selects agents using the Group Chat\n", + " Manager's LLM." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To illustrate this pattern, let's consider a simple example of a group chat\n", + "among the same arithmetic operator agents as in the previous example,\n", + "with the objective of turning a number into a specific target number\n", + "using a sequence of arithmetic operations powered by the agents.\n", + "\n", + "In this example, we use the `auto` strategy to select the next agent.\n", + "To help the Group Chat Manager select the next agent, we also set the\n", + "`description` of the agents. Without the `description`, the Group Chat Manager\n", + "will use the agents' `system_message`, which may be not be the best choice." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# The `description` attribute is a string that describes the agent.\n", + "# It can also be set in `ConversableAgent` constructor.\n", + "adder_agent.description = \"Add 1 to each input number.\"\n", + "multiplier_agent.description = \"Multiply each input number by 2.\"\n", + "subtracter_agent.description = \"Subtract 1 from each input number.\"\n", + "divider_agent.description = \"Divide each input number by 2.\"\n", + "number_agent.description = \"Return the numbers given.\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We first create a `GroupChat` object and provide the list of agents.\n", + "If we were to use the `round_robin` strategy, this list would specify the order\n", + "of the agents to be selected.\n", + "We also initialize the group chat with an empty message list and a maximum\n", + "round of 6, which means there will be at most 6 iteratiosn of selecting speaker,\n", + "agent speaks and broadcasting message." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from autogen import GroupChat\n", + "\n", + "group_chat = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " messages=[],\n", + " max_round=6,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we create a `GroupChatManager` object and provide the `GroupChat` object as\n", + "input. We also need to specify the `llm_config` of the Group Chat Manager\n", + "so it can use the LLM to select the next agent (the `auto` strategy)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from autogen import GroupChatManager\n", + "\n", + "group_chat_manager = GroupChatManager(\n", + " groupchat=group_chat,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we have the Number Agent from before to start a two-agent chat with\n", + "the Group Chat Manager, which runs the group chat internally and terminates\n", + "the two-agent chat when the internal group chat is done.\n", + "Because the Number Agent is selected to speak by us, it counts as the \n", + "first round of the group chat." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "6\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "chat_result = number_agent.initiate_chat(\n", + " group_chat_manager,\n", + " message=\"My number is 3, I want to turn it into 13.\",\n", + " summary_method=\"reflection_with_llm\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see that the Number Agent is selected to speak first, then the\n", + "Group Chat Manager selects the Multiplier Agent to speak, then the Adder\n", + "Agent, and so on. The number is operated upon by each agent in the group\n", + "chat, and the final result is 13.\n", + "\n", + "We can take a look at the summary of the group chat, provided by the \n", + "`ChatResult` object returned by the `initiate_chat` method." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The agents cooperatively manipulated the initial number (3) through multipliying, adding, and subtracting operations to reach the target number (13).\n" + ] + } + ], + "source": [ + "print(chat_result.summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Send Introductions\n", + "\n", + "In the previous example, we set the `description` of the agents to help the\n", + "Group Chat Manager select the next agent. This only helps the Group Chat Manager,\n", + "however, does not help the participating agents to know about each other.\n", + "Sometimes it is useful have each agent introduce themselves to other\n", + "agents in the group chat. This can be done by setting the `send_introductions=True`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "group_chat_with_introductions = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " messages=[],\n", + " max_round=6,\n", + " send_introductions=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Under the hood, the Group Chat Manager sends a message containing the \n", + "agents' names and descriptions to all agents in the group chat before the\n", + "group chat starts." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Group Chat in a Sequential Chat\n", + "\n", + "Group chat can also be used as a part of a sequential chat.\n", + "In this case, the Group Chat Manager is treated as a regular agent\n", + "in the sequence of two-agent chats." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "6\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "Your number is 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Turn this number to 32.\n", + "\n", + "With the following carryover: \n", + "Your number is 13.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "Turn this number to 32.\n", + "Context: \n", + "Your number is 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "26\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "28\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "30\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/ekzhu/autogen/autogen/agentchat/chat.py:46: UserWarning: Repetitive recipients detected: The chat history will be cleared by default if a recipient appears more than once. To retain the chat history, please set 'clear_history=False' in the configuration of the repeating agent.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "# Let's use the group chat with introduction messages created above.\n", + "group_chat_manager_with_intros = GroupChatManager(\n", + " groupchat=group_chat_with_introductions,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "# Start a sequence of two-agent chats between the number agent and\n", + "# the group chat manager.\n", + "chat_result = number_agent.initiate_chats(\n", + " [\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"message\": \"My number is 3, I want to turn it into 13.\",\n", + " },\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"message\": \"Turn this number to 32.\",\n", + " },\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above example, the Group Chat Manager runs the group chat two times.\n", + "In the first time the number 3 becomes 13, and the last message of this group chat\n", + "is being used as the carryover for the next group chat, which starts from 13.\n", + "\n", + "You can also see from the warning message that the Group Chat Manager's\n", + "history is being cleared after the first group chat, which is the default.\n", + "To keep the history of the Group Chat Manager, \n", + "you can set the `clear_history=False` for the first chat." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constrained Speaker Selection\n", + "\n", + "Group chat is a powerful conversation pattern, but it can be hard to control\n", + "if the number of participating agents is large.\n", + "AutoGen provides a way to constrain the selection of the next speaker\n", + "by using the `allowed_or_disallowed_speaker_transitions` argument of the \n", + "`GroupChat` class.\n", + "\n", + "The `allowed_or_disallowed_speaker_transitions` argument is a dictionary\n", + "that maps a given agent to a list of agents that can (or cannot) \n", + "be selected to speak next. The `speaker_transitions_type` argument specifies\n", + "whether the transitions are allowed or disallowed.\n", + "\n", + "Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "allowed_transitions = {\n", + " number_agent: [adder_agent, number_agent],\n", + " adder_agent: [multiplier_agent, number_agent],\n", + " subtracter_agent: [divider_agent, number_agent],\n", + " multiplier_agent: [subtracter_agent, number_agent],\n", + " divider_agent: [adder_agent, number_agent],\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, the allowed transitions are specified for each agent.\n", + "The Number Agent can be followed by the Adder Agent and the Number Agent, \n", + "the Adder Agent can be followed by the Multiplier Agent and the Number Agent,\n", + "and so on.\n", + "Let's put this into the group chat and see how it works.\n", + "The `speaker_transitions_type` is set to `allowed` so the transitions are\n", + "positive constraints." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", + "\n", + "3.5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4.5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "9\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "10\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "10\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "constrained_graph_chat = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " allowed_or_disallowed_speaker_transitions=allowed_transitions,\n", + " speaker_transitions_type=\"allowed\",\n", + " messages=[],\n", + " max_round=12,\n", + " send_introductions=True,\n", + ")\n", + "\n", + "constrained_group_chat_manager = GroupChatManager(\n", + " groupchat=constrained_graph_chat,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "chat_result = number_agent.initiate_chat(\n", + " constrained_group_chat_manager,\n", + " message=\"My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\",\n", + " summary_method=\"reflection_with_llm\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This time, the agents are selected following the constraints we have specified." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Changing the select speaker role name\n", + "\n", + "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", + "a select speaker message is sent to the LLM to determine the next speaker.\n", + "\n", + "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", + "`assistant`, or `system`. The select speaker message is the last in the chat\n", + "sequence when used and, by default, has a role of `system`.\n", + "\n", + "When using some models, such as Mistral through Mistral.AI's API, the role on\n", + "the last message in the chat sequence has to be `user`.\n", + "\n", + "To change the default behaviour, Autogen provides a way to set the value of the\n", + "select speaker message's role to any string value by setting the\n", + "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", + "default value is `system` and by setting it to `user` you can accommodate the\n", + "last message role requirement of Mistral.AI's API." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Nested Chats\n", + "\n", + "The previous conversations patterns (two-agent chat, sequential chat, and group chat)\n", + "are useful for building complex workflows, however, they do not expose a\n", + "single conversational interface, which is often needed for scenarios like\n", + "question-answering bots and personal assistants.\n", + "In some other cases, it is also useful to package a workflow into a single\n", + "agent for reuse in a larger workflow. \n", + "AutoGen provides a way to achieve this by using nested chats.\n", + "\n", + "Nested chats is powered by the nested chats handler, which is a pluggable\n", + "component of `ConversableAgent`.\n", + "The figure below illustrates how the nested chats handler triggers\n", + "a sequence of nested chats when a message is received.\n", + "\n", + "```{=mdx}\n", + "![nested_chat](./assets/nested-chats.png)\n", + "```\n", + "\n", + "When a message comes in and passes the [human-in-the-loop component](./human-in-the-loop), \n", + "the nested chats handler checks if the message should trigger a nested chat\n", + "based on conditions specified by the user.\n", + "If the conditions are met, the nested chats handler starts a sequence of\n", + "nested chats specified using the sequential chats pattern.\n", + "In each of the nested chats, the sender agent is always the same agent\n", + "that triggered the nested chats.\n", + "In the end, the nested chat handler uses the results of the nested chats\n", + "to produce a response to the original message.\n", + "By default, the nested chat handler uses the summary of the last chat\n", + "as the response." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is an example of using nested chats to build an arithmetic agent that\n", + "packages arithmetic operations, code-based validation, and poetry into a single\n", + "agent. This arithmetic agent takes a number transformation request like \n", + "\"turn number 3 into 13\" and returns a poem that describes a transformation attempt.\n", + "\n", + "First we define the agents. We reuse the `group_chat_manager_with_intros`\n", + "from previous example to orchestrate the arithmetic operations." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "import tempfile\n", + "\n", + "temp_dir = tempfile.gettempdir()\n", + "\n", + "arithmetic_agent = ConversableAgent(\n", + " name=\"Arithmetic_Agent\",\n", + " llm_config=False,\n", + " human_input_mode=\"ALWAYS\",\n", + " # This agent will always require human input to make sure the code is\n", + " # safe to execute.\n", + " code_execution_config={\"use_docker\": False, \"work_dir\": temp_dir},\n", + ")\n", + "\n", + "code_writer_agent = ConversableAgent(\n", + " name=\"Code_Writer_Agent\",\n", + " system_message=\"You are a code writer. You write Python script in Markdown code blocks.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "poetry_agent = ConversableAgent(\n", + " name=\"Poetry_Agent\",\n", + " system_message=\"You are an AI poet.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we define the nested chats using the sequential chat pattern.\n", + "All the senders are always `artihmetic_agent`." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "nested_chats = [\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " \"summary_prompt\": \"Summarize the sequence of operations used to turn \" \"the source number into target number.\",\n", + " },\n", + " {\n", + " \"recipient\": code_writer_agent,\n", + " \"message\": \"Write a Python script to verify the arithmetic operations is correct.\",\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " },\n", + " {\n", + " \"recipient\": poetry_agent,\n", + " \"message\": \"Write a poem about it.\",\n", + " \"max_turns\": 1,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we register the nested chats handler to the `arithmetic_agent` and\n", + "set the conditions for triggering the nested chats." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arithmetic_agent.register_nested_chats(\n", + " nested_chats,\n", + " # The trigger function is used to determine if the agent should start the nested chat\n", + " # given the sender agent.\n", + " # In this case, the arithmetic agent will not start the nested chats if the sender is\n", + " # from the nested chats' recipient to avoid recursive calls.\n", + " trigger=lambda sender: sender not in [group_chat_manager_with_intros, code_writer_agent, poetry_agent],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we call `generate_reply` to get a response from the `arithmetic_agent`\n", + "-- this will trigger a sequence of nested chats and return the summary of the\n", + "last nested chat as the response." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[31m\n", + ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "I have a number 3 and I want to turn it into 7.\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to chat_manager):\n", + "\n", + "I have a number 3 and I want to turn it into 7.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "To give you the result, I'll add 1 to the number you gave me. So your new number is 4.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Write a Python script to verify the arithmetic operations is correct.\n", + "\n", + "With the following carryover: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", + "\n", + "Write a Python script to verify the arithmetic operations is correct.\n", + "Context: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "Here is a Python script to verify the aforementioned arithmetic operations:\n", + "\n", + "```python\n", + "# defining the initial value\n", + "initial_number = 3\n", + "\n", + "# Adding 1 to initial number\n", + "initial_number += 1\n", + "assert initial_number == 4, \"The first operation failed!\"\n", + "\n", + "# Multiplying the result by 2\n", + "initial_number *= 2\n", + "assert initial_number == 8, \"The second operation failed!\"\n", + "\n", + "# Subtracting 1 from the result\n", + "initial_number -= 1\n", + "assert initial_number == 7, \"The final operation failed!\"\n", + "\n", + "print(\"All operations were carried out successfully!\")\n", + "```\n", + "In the script, the entire process is broken down into steps. The `assert` function is used to verify the result at every step. If any of the operations doesn't yield the expected result, an `AssertionError` exception will be raised. If all operations pass, the message \"All operations were carried out successfully!\" will be printed.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", + "\n", + "exitcode: 0 (execution succeeded)\n", + "Code output: \n", + "All operations were carried out successfully!\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "Certainly, that means the python script was successful and every arithmetic operation performed correctly given the initial input and the steps performed.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Write a poem about it.\n", + "\n", + "With the following carryover: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Poetry_Agent):\n", + "\n", + "Write a poem about it.\n", + "Context: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mPoetry_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "From numbers, logic, pure mathematical creation,\n", + "Ponder this tale of numeric manipulation.\n", + "In the universe of Python where operations exist,\n", + "A story of integers and functions persist.\n", + "\n", + "Three was the number from where we began,\n", + "Oblivious to the journey and its grandiosely plan.\n", + "Added with 1, the sum it adorned,\n", + "A sweet quadruple in the dawn was formed.\n", + "\n", + "The saga continued with a twist of the tale,\n", + "The four was multiplied, while the winds wail.\n", + "The duo of four unfolded its wings,\n", + "An octet presence in our midst it brings.\n", + "\n", + "Then enters subtraction, sly and clever,\n", + "Removing one to alter the endeavor.\n", + "From eight, subtracted one in delight,\n", + "To finally bask in the glow of seven's light.\n", + "\n", + "Each operation, together they conspired,\n", + "In this tale of integers, creatively inspired.\n", + "Through life's equation, the script ran so free,\n", + "Amidst the language of Python, a symphony, you see.\n", + "\n", + "Tested with assert, cross-checked the chain,\n", + "Confirming accuracy in program's domain.\n", + "Each move calculated, each step so right,\n", + "In the maze of coding, found was the light. \n", + "\n", + "Such is the tale, of numbers and operations, \n", + "A dance among digits, logical iterations,\n", + "Just another day, in this AI poet's life,\n", + "Cutting through ambiguity, like a razor-sharp knife.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "# Instead of using `initiate_chat` method to start another conversation,\n", + "# we can use the `generate_reply` method to get single reply to a message directly.\n", + "reply = arithmetic_agent.generate_reply(\n", + " messages=[{\"role\": \"user\", \"content\": \"I have a number 3 and I want to turn it into 7.\"}]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A poem is returned as the response, which describes the transformation attempt\n", + "from 3 to 7." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The implementation of the nested chats handler makes use of the\n", + "[`register_reply`](../reference/agentchat/conversable_agent/#register_reply)\n", + "method, which allows you to make extensive customization to\n", + " `ConversableAgent`. The GroupChatManager uses the same mechanism to implement the group chat.\n", + "\n", + "Nested chat is a powerful conversation pattern that allows you to package\n", + "complex workflows into a single agent.\n", + "You can hide [tool usages](/docs/tutorial/tool-use) within a single agent by having the tool-caller agent \n", + "starts a nested chat with a tool-executor agent and then use the result\n", + "of the nested chat to generate a response.\n", + "See the [nested chats for tool use notebook](/docs/notebooks/agentchat_nested_chats_chess) for an example." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "In this chapter, we covered two-agent chat, sequential chat, group chat,\n", + "and nested chat patterns. You can compose these patterns like LEGO blocks to \n", + "create complex workflows. You can also use [`register_reply`](../reference/agentchat/conversable_agent/#register_reply) to create new patterns.\n", + "\n", + "This is the last chapter on basic AutoGen concepts. \n", + "In the next chatper, we will give you some tips on what to do next." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "autogen", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/ekzhu/autogen/autogen/agentchat/chat.py:46: UserWarning: Repetitive recipients detected: The chat history will be cleared by default if a recipient appears more than once. To retain the chat history, please set 'clear_history=False' in the configuration of the repeating agent.\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "# Let's use the group chat with introduction messages created above.\n", - "group_chat_manager_with_intros = GroupChatManager(\n", - " groupchat=group_chat_with_introductions,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "# Start a sequence of two-agent chats between the number agent and\n", - "# the group chat manager.\n", - "chat_result = number_agent.initiate_chats(\n", - " [\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"message\": \"My number is 3, I want to turn it into 13.\",\n", - " },\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"message\": \"Turn this number to 32.\",\n", - " },\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above example, the Group Chat Manager runs the group chat two times.\n", - "In the first time the number 3 becomes 13, and the last message of this group chat\n", - "is being used as the carryover for the next group chat, which starts from 13.\n", - "\n", - "You can also see from the warning message that the Group Chat Manager's\n", - "history is being cleared after the first group chat, which is the default.\n", - "To keep the history of the Group Chat Manager, \n", - "you can set the `clear_history=False` for the first chat." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Constrained Speaker Selection\n", - "\n", - "Group chat is a powerful conversation pattern, but it can be hard to control\n", - "if the number of participating agents is large.\n", - "AutoGen provides a way to constrain the selection of the next speaker\n", - "by using the `allowed_or_disallowed_speaker_transitions` argument of the \n", - "`GroupChat` class.\n", - "\n", - "The `allowed_or_disallowed_speaker_transitions` argument is a dictionary\n", - "that maps a given agent to a list of agents that can (or cannot) \n", - "be selected to speak next. The `speaker_transitions_type` argument specifies\n", - "whether the transitions are allowed or disallowed.\n", - "\n", - "Here is an example:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "allowed_transitions = {\n", - " number_agent: [adder_agent, number_agent],\n", - " adder_agent: [multiplier_agent, number_agent],\n", - " subtracter_agent: [divider_agent, number_agent],\n", - " multiplier_agent: [subtracter_agent, number_agent],\n", - " divider_agent: [adder_agent, number_agent],\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, the allowed transitions are specified for each agent.\n", - "The Number Agent can be followed by the Adder Agent and the Number Agent, \n", - "the Adder Agent can be followed by the Multiplier Agent and the Number Agent,\n", - "and so on.\n", - "Let's put this into the group chat and see how it works.\n", - "The `speaker_transitions_type` is set to `allowed` so the transitions are\n", - "positive constraints." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", - "\n", - "3.5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4.5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "9\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "10\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "10\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "constrained_graph_chat = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " allowed_or_disallowed_speaker_transitions=allowed_transitions,\n", - " speaker_transitions_type=\"allowed\",\n", - " messages=[],\n", - " max_round=12,\n", - " send_introductions=True,\n", - ")\n", - "\n", - "constrained_group_chat_manager = GroupChatManager(\n", - " groupchat=constrained_graph_chat,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "chat_result = number_agent.initiate_chat(\n", - " constrained_group_chat_manager,\n", - " message=\"My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\",\n", - " summary_method=\"reflection_with_llm\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This time, the agents are selected following the constraints we have specified." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Changing the select speaker role name\n", - "\n", - "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", - "a select speaker message is sent to the LLM to determine the next speaker.\n", - "\n", - "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", - "`assistant`, or `system`. The select speaker message is the last in the chat\n", - "sequence when used and, by default, has a role of `system`.\n", - "\n", - "When using some models, such as Mistral through Mistral.AI's API, the role on\n", - "the last message in the chat sequence has to be `user`.\n", - "\n", - "To change the default behaviour, Autogen provides a way to set the value of the\n", - "select speaker message's role to any string value by setting the\n", - "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", - "default value is `system` and by setting it to `user` you can accommodate the\n", - "last message role requirement of Mistral.AI's API." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Nested Chats\n", - "\n", - "The previous conversations patterns (two-agent chat, sequential chat, and group chat)\n", - "are useful for building complex workflows, however, they do not expose a\n", - "single conversational interface, which is often needed for scenarios like\n", - "question-answering bots and personal assistants.\n", - "In some other cases, it is also useful to package a workflow into a single\n", - "agent for reuse in a larger workflow. \n", - "AutoGen provides a way to achieve this by using nested chats.\n", - "\n", - "Nested chats is powered by the nested chats handler, which is a pluggable\n", - "component of `ConversableAgent`.\n", - "The figure below illustrates how the nested chats handler triggers\n", - "a sequence of nested chats when a message is received.\n", - "\n", - "```{=mdx}\n", - "![nested_chat](./assets/nested-chats.png)\n", - "```\n", - "\n", - "When a message comes in and passes the [human-in-the-loop component](./human-in-the-loop), \n", - "the nested chats handler checks if the message should trigger a nested chat\n", - "based on conditions specified by the user.\n", - "If the conditions are met, the nested chats handler starts a sequence of\n", - "nested chats specified using the sequential chats pattern.\n", - "In each of the nested chats, the sender agent is always the same agent\n", - "that triggered the nested chats.\n", - "In the end, the nested chat handler uses the results of the nested chats\n", - "to produce a response to the original message.\n", - "By default, the nested chat handler uses the summary of the last chat\n", - "as the response." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example of using nested chats to build an arithmetic agent that\n", - "packages arithmetic operations, code-based validation, and poetry into a single\n", - "agent. This arithmetic agent takes a number transformation request like \n", - "\"turn number 3 into 13\" and returns a poem that describes a transformation attempt.\n", - "\n", - "First we define the agents. We reuse the `group_chat_manager_with_intros`\n", - "from previous example to orchestrate the arithmetic operations." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "import tempfile\n", - "\n", - "temp_dir = tempfile.gettempdir()\n", - "\n", - "arithmetic_agent = ConversableAgent(\n", - " name=\"Arithmetic_Agent\",\n", - " llm_config=False,\n", - " human_input_mode=\"ALWAYS\",\n", - " # This agent will always require human input to make sure the code is\n", - " # safe to execute.\n", - " code_execution_config={\"use_docker\": False, \"work_dir\": temp_dir},\n", - ")\n", - "\n", - "code_writer_agent = ConversableAgent(\n", - " name=\"Code_Writer_Agent\",\n", - " system_message=\"You are a code writer. You write Python script in Markdown code blocks.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "poetry_agent = ConversableAgent(\n", - " name=\"Poetry_Agent\",\n", - " system_message=\"You are an AI poet.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we define the nested chats using the sequential chat pattern.\n", - "All the senders are always `artihmetic_agent`." - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "nested_chats = [\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"summary_method\": \"reflection_with_llm\",\n", - " \"summary_prompt\": \"Summarize the sequence of operations used to turn \" \"the source number into target number.\",\n", - " },\n", - " {\n", - " \"recipient\": code_writer_agent,\n", - " \"message\": \"Write a Python script to verify the arithmetic operations is correct.\",\n", - " \"summary_method\": \"reflection_with_llm\",\n", - " },\n", - " {\n", - " \"recipient\": poetry_agent,\n", - " \"message\": \"Write a poem about it.\",\n", - " \"max_turns\": 1,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we register the nested chats handler to the `arithmetic_agent` and\n", - "set the conditions for triggering the nested chats." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "arithmetic_agent.register_nested_chats(\n", - " nested_chats,\n", - " # The trigger function is used to determine if the agent should start the nested chat\n", - " # given the sender agent.\n", - " # In this case, the arithmetic agent will not start the nested chats if the sender is\n", - " # from the nested chats' recipient to avoid recursive calls.\n", - " trigger=lambda sender: sender not in [group_chat_manager_with_intros, code_writer_agent, poetry_agent],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we call `generate_reply` to get a response from the `arithmetic_agent`\n", - "-- this will trigger a sequence of nested chats and return the summary of the\n", - "last nested chat as the response." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[31m\n", - ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "I have a number 3 and I want to turn it into 7.\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to chat_manager):\n", - "\n", - "I have a number 3 and I want to turn it into 7.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "To give you the result, I'll add 1 to the number you gave me. So your new number is 4.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Write a Python script to verify the arithmetic operations is correct.\n", - "\n", - "With the following carryover: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", - "\n", - "Write a Python script to verify the arithmetic operations is correct.\n", - "Context: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "Here is a Python script to verify the aforementioned arithmetic operations:\n", - "\n", - "```python\n", - "# defining the initial value\n", - "initial_number = 3\n", - "\n", - "# Adding 1 to initial number\n", - "initial_number += 1\n", - "assert initial_number == 4, \"The first operation failed!\"\n", - "\n", - "# Multiplying the result by 2\n", - "initial_number *= 2\n", - "assert initial_number == 8, \"The second operation failed!\"\n", - "\n", - "# Subtracting 1 from the result\n", - "initial_number -= 1\n", - "assert initial_number == 7, \"The final operation failed!\"\n", - "\n", - "print(\"All operations were carried out successfully!\")\n", - "```\n", - "In the script, the entire process is broken down into steps. The `assert` function is used to verify the result at every step. If any of the operations doesn't yield the expected result, an `AssertionError` exception will be raised. If all operations pass, the message \"All operations were carried out successfully!\" will be printed.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", - "\n", - "exitcode: 0 (execution succeeded)\n", - "Code output: \n", - "All operations were carried out successfully!\n", - "\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "Certainly, that means the python script was successful and every arithmetic operation performed correctly given the initial input and the steps performed.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Write a poem about it.\n", - "\n", - "With the following carryover: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Poetry_Agent):\n", - "\n", - "Write a poem about it.\n", - "Context: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mPoetry_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "From numbers, logic, pure mathematical creation,\n", - "Ponder this tale of numeric manipulation.\n", - "In the universe of Python where operations exist,\n", - "A story of integers and functions persist.\n", - "\n", - "Three was the number from where we began,\n", - "Oblivious to the journey and its grandiosely plan.\n", - "Added with 1, the sum it adorned,\n", - "A sweet quadruple in the dawn was formed.\n", - "\n", - "The saga continued with a twist of the tale,\n", - "The four was multiplied, while the winds wail.\n", - "The duo of four unfolded its wings,\n", - "An octet presence in our midst it brings.\n", - "\n", - "Then enters subtraction, sly and clever,\n", - "Removing one to alter the endeavor.\n", - "From eight, subtracted one in delight,\n", - "To finally bask in the glow of seven's light.\n", - "\n", - "Each operation, together they conspired,\n", - "In this tale of integers, creatively inspired.\n", - "Through life's equation, the script ran so free,\n", - "Amidst the language of Python, a symphony, you see.\n", - "\n", - "Tested with assert, cross-checked the chain,\n", - "Confirming accuracy in program's domain.\n", - "Each move calculated, each step so right,\n", - "In the maze of coding, found was the light. \n", - "\n", - "Such is the tale, of numbers and operations, \n", - "A dance among digits, logical iterations,\n", - "Just another day, in this AI poet's life,\n", - "Cutting through ambiguity, like a razor-sharp knife.\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "# Instead of using `initiate_chat` method to start another conversation,\n", - "# we can use the `generate_reply` method to get single reply to a message directly.\n", - "reply = arithmetic_agent.generate_reply(\n", - " messages=[{\"role\": \"user\", \"content\": \"I have a number 3 and I want to turn it into 7.\"}]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A poem is returned as the response, which describes the transformation attempt\n", - "from 3 to 7." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The implementation of the nested chats handler makes use of the\n", - "[`register_reply`](../reference/agentchat/conversable_agent/#register_reply)\n", - "method, which allows you to make extensive customization to\n", - " `ConversableAgent`. The GroupChatManager uses the same mechanism to implement the group chat.\n", - "\n", - "Nested chat is a powerful conversation pattern that allows you to package\n", - "complex workflows into a single agent.\n", - "You can hide [tool usages](/docs/tutorial/tool-use) within a single agent by having the tool-caller agent \n", - "starts a nested chat with a tool-executor agent and then use the result\n", - "of the nested chat to generate a response.\n", - "See the [nested chats for tool use notebook](/docs/notebooks/agentchat_nested_chats_chess) for an example." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Summary\n", - "\n", - "In this chapter, we covered two-agent chat, sequential chat, group chat,\n", - "and nested chat patterns. You can compose these patterns like LEGO blocks to \n", - "create complex workflows. You can also use [`register_reply`](../reference/agentchat/conversable_agent/#register_reply) to create new patterns.\n", - "\n", - "This is the last chapter on basic AutoGen concepts. \n", - "In the next chatper, we will give you some tips on what to do next." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "autogen", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "nbformat": 4, + "nbformat_minor": 2 + } From 219948cb2324b685fc56490fb14d5e101a7bf5e5 Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:17:28 -0400 Subject: [PATCH 08/10] update --- .../docs/tutorial/conversation-patterns.ipynb | 3192 ++++++++--------- 1 file changed, 1596 insertions(+), 1596 deletions(-) diff --git a/website/docs/tutorial/conversation-patterns.ipynb b/website/docs/tutorial/conversation-patterns.ipynb index eb79dd27fc37..d032175e054a 100644 --- a/website/docs/tutorial/conversation-patterns.ipynb +++ b/website/docs/tutorial/conversation-patterns.ipynb @@ -1,1598 +1,1598 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Conversation Patterns\n", - "\n", - "In the previous chapter we used two-agent conversation, which\n", - "can be started by the `initiate_chat` method.\n", - "Two-agent chat is a useful conversation pattern but AutoGen offers more.\n", - "In this chapter, we will first dig a little bit more into the two-agent \n", - "chat pattern and chat result, \n", - "then we will show you several conversation patterns that involve \n", - "more than two agents.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Two-Agent Chat and Chat Result\n", - "\n", - "Two-agent chat is the simplest from of conversation pattern. \n", - "We start a two-agent chat using the `initiate_chat` method of every \n", - "`ConversableAgent` agent.\n", - "We have already\n", - "seen multiple examples of two-agent chats in previous chapters\n", - "but we haven't covered the details.\n", - "\n", - "The following figure illustrates how two-agent chat works.\n", - "\n", - "```{=mdx}\n", - "![Two-agent chat](./assets/two-agent-chat.png)\n", - "```\n", - "\n", - "A two-agent chats takes two inputs: a message, which is a string provided by\n", - "the caller; a context, which specifies various parameters of the chat.\n", - "The sender agent uses its chat initializer method\n", - "(i.e., `generate_init_message` method of `ConversableAgent`)\n", - "to generate an initial message from the inputs, and\n", - "sends it to the recipient agent to start the chat.\n", - "The sender agent is the agent whose `initiate_chat` method is called, and\n", - "the recipient agent is the other agent.\n", - "\n", - "Once the chat terminates, the history of the chat is processed by a \n", - "chat summarizer. The summarizer summarizes the chat history and calculates\n", - "the token usage of the chat. \n", - "You can configure the type of summary using the `summary_method`\n", - "parameter of the `initiate_chat` method. By default, it is the last\n", - "message of the chat (i.e., `summary_method='last_msg'`).\n", - "\n", - "The example below is a two-agent chat between a student agent and a teacher\n", - "agent. Its summarizer uses an LLM-based summary." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", - "\n", - "What is triangle inequality?\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", - "\n", - "Triangle inequality theorem is a fundamental principle in geometry that states that the sum of the lengths of any two sides of a triangle must always be greater than the length of the third side. In a triangle with sides of lengths a, b, and c, the theorem can be written as:\n", - "\n", - "a + b > c\n", - "a + c > b\n", - "b + c > a\n", - "\n", - "Each of these represents the condition for one specific side (a, b, or c). All must be true for a triangle to exist.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", - "\n", - "Thank you for the explanation. This theorem helps in understanding the basic properties of a triangle. It can also be useful when solving geometric problems or proving other mathematical theorems. Can you give me an example of how we can use the triangle inequality theorem?\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", - "\n", - "Absolutely! Here's an example:\n", - "\n", - "Suppose you're given three line segments with lengths 10, 7, and 3 units. The question is: \"Can these three line segments form a triangle?\"\n", - "\n", - "To answer this, you would use the triangle inequality theorem. Adding any two side lengths together should be greater than the third:\n", - "\n", - "- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\n", - "- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\n", - "- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of the third side (10), but not greater.\n", - "\n", - "So, these three lines cannot form a triangle, because not all pairs of sides satisfy the triangle inequality theorem.\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "import os\n", - "from autogen import ConversableAgent\n", - "\n", - "student_agent = ConversableAgent(\n", - " name=\"Student_Agent\",\n", - " system_message=\"You are a student willing to learn.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "teacher_agent = ConversableAgent(\n", - " name=\"Teacher_Agent\",\n", - " system_message=\"You are a math teacher.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "chat_result = student_agent.initiate_chat(\n", - " teacher_agent,\n", - " message=\"What is triangle inequality?\",\n", - " summary_method=\"reflection_with_llm\",\n", - " max_turns=2,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's see what the summary looks like.\n", - "The summary is stored in the `chat_result` object of the type `ChatResult` \n", - "that was returned by the `initiate_chat` method." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The triangle inequality theorem states that in a triangle, the sum of the lengths of any two sides must always be greater than the length of the third side. This principle is significant in geometry and is used in solving problems or proving theorems. For instance, if given three line segments, you can determine if they can form a triangle using this theorem.\n" - ] - } - ], - "source": [ - "print(chat_result.summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above example, the summary method is set to `reflection_with_llm` which\n", - "takes a list of messages from the conversation and summarize them \n", - "using a call to an LLM.\n", - "The summary method first tries to use the recipient's LLM, if it is not available\n", - "then it uses the sender's LLM. In this case the recipient is \"Teacher_Agent\" and\n", - "the sender is \"Student_Agent\".\n", - "The input prompt for the LLM is the following default prompt:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Summarize the takeaway from the conversation. Do not add any introductory phrases.\n" - ] - } - ], - "source": [ - "print(ConversableAgent.DEFAULT_summary_prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also use a custom prompt by setting the `summary_prompt` argument\n", - "of `initiate_chat`.\n", - "\n", - "There are some other useful information in the `ChatResult` object, including\n", - "the conversation history, human input, and token cost." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[{'content': 'What is triangle inequality?', 'role': 'assistant'},\n", - " {'content': 'Triangle inequality theorem is a fundamental principle in '\n", - " 'geometry that states that the sum of the lengths of any two '\n", - " 'sides of a triangle must always be greater than the length of '\n", - " 'the third side. In a triangle with sides of lengths a, b, and c, '\n", - " 'the theorem can be written as:\\n'\n", - " '\\n'\n", - " 'a + b > c\\n'\n", - " 'a + c > b\\n'\n", - " 'b + c > a\\n'\n", - " '\\n'\n", - " 'Each of these represents the condition for one specific side (a, '\n", - " 'b, or c). All must be true for a triangle to exist.',\n", - " 'role': 'user'},\n", - " {'content': 'Thank you for the explanation. This theorem helps in '\n", - " 'understanding the basic properties of a triangle. It can also be '\n", - " 'useful when solving geometric problems or proving other '\n", - " 'mathematical theorems. Can you give me an example of how we can '\n", - " 'use the triangle inequality theorem?',\n", - " 'role': 'assistant'},\n", - " {'content': \"Absolutely! Here's an example:\\n\"\n", - " '\\n'\n", - " \"Suppose you're given three line segments with lengths 10, 7, and \"\n", - " '3 units. The question is: \"Can these three line segments form a '\n", - " 'triangle?\"\\n'\n", - " '\\n'\n", - " 'To answer this, you would use the triangle inequality theorem. '\n", - " 'Adding any two side lengths together should be greater than the '\n", - " 'third:\\n'\n", - " '\\n'\n", - " '- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\\n'\n", - " '- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\\n'\n", - " '- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of '\n", - " 'the third side (10), but not greater.\\n'\n", - " '\\n'\n", - " 'So, these three lines cannot form a triangle, because not all '\n", - " 'pairs of sides satisfy the triangle inequality theorem.',\n", - " 'role': 'user'}]\n" - ] - } - ], - "source": [ - "# Get the chat history.\n", - "import pprint\n", - "\n", - "pprint.pprint(chat_result.chat_history)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "That chat messages in the chat result are from the \n", - "recipient agent's perspective -- the sender is the \"assistant\" and the recipient\n", - "is the \"user\"." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "({'gpt-4-0613': {'completion_tokens': 399,\n", - " 'cost': 0.04521,\n", - " 'prompt_tokens': 709,\n", - " 'total_tokens': 1108},\n", - " 'total_cost': 0.04521},\n", - " {'total_cost': 0})\n" - ] - } - ], - "source": [ - "# Get the cost of the chat.\n", - "pprint.pprint(chat_result.cost)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Sequential Chats\n", - "\n", - "The name of this pattern is self-explanatory -- it is a sequence of\n", - "chats between two agents, chained together by a mechanism called *carryover*,\n", - "which brings the summary of the previous chat to the context\n", - "of the next chat.\n", - "\n", - "This pattern is useful for complex task that can be broken down into \n", - "interdependent sub-tasks. \n", - "The figure below illustrate how this pattern works.\n", - "\n", - "```{=mdx}\n", - "![initiate_chats](./assets/sequential-two-agent-chat.png)\n", - "```\n", - "\n", - "In this pattern, the a pair of agents first start a two-agent chat,\n", - "then the summary of the conversation becomes a *carryover* for the next\n", - "two-agent chat. The next chat passes the carryover to the `carryover` parameter\n", - "of the context to generate its initial message.\n", - "\n", - "Carryover accumulates as the conversation moves forward,,\n", - "so each subsequent chat starts with all the carryovers \n", - "from previous chats.\n", - "\n", - "The figure above shows distinct recipient agents for all the chats, however,\n", - "the recipient agents in the sequence are allowed to repeat." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To illustrate this pattern, let's consider a simple example of arithmetic\n", - "operator agents. One agent \n", - "(called the \"Number_Agent\") is responsible for coming up with a number,\n", - "and other agents are responsible for performing a specific arithmetic\n", - "operation on the number, e.g., add 1, multiply by 2, etc.." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "# The Number Agent always returns the same numbers.\n", - "number_agent = ConversableAgent(\n", - " name=\"Number_Agent\",\n", - " system_message=\"You return me the numbers I give you, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Adder Agent adds 1 to each number it receives.\n", - "adder_agent = ConversableAgent(\n", - " name=\"Adder_Agent\",\n", - " system_message=\"You add 1 to each number I give you and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Multiplier Agent multiplies each number it receives by 2.\n", - "multiplier_agent = ConversableAgent(\n", - " name=\"Multiplier_Agent\",\n", - " system_message=\"You multiply each number I give you by 2 and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Subtracter Agent subtracts 1 from each number it receives.\n", - "subtracter_agent = ConversableAgent(\n", - " name=\"Subtracter_Agent\",\n", - " system_message=\"You subtract 1 from each number I give you and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "# The Divider Agent divides each number it receives by 2.\n", - "divider_agent = ConversableAgent(\n", - " name=\"Divider_Agent\",\n", - " system_message=\"You divide each number I give you by 2 and return me the new numbers, one number each line.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Number Agent chats with the first operator agent, then the second\n", - "operator agent, and so on.\n", - "After each chat, the last message in the conversation (i.e., the result of the arithmetic operation from the operator agent)\n", - "is used as the summary of the chat.\n", - "This is specified by the `summary_method` parameter.\n", - "In the end we will have the result of the arithmetic operations." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "14\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "16\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "32\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", - "\n", - "32\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "64\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\n", - "64\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "64\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "15\n", - "63\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", - "\n", - "15\n", - "63\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "14\n", - "62\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "These are my numbers\n", - "\n", - "With the following carryover: \n", - "16\n", - "64\n", - "14\n", - "62\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", - "\n", - "These are my numbers\n", - "Context: \n", - "16\n", - "64\n", - "14\n", - "62\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "8\n", - "32\n", - "7\n", - "31\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", - "\n", - "8\n", - "32\n", - "7\n", - "31\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", - "\n", - "4\n", - "16\n", - "3.5\n", - "15.5\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "# Start a sequence of two-agent chats.\n", - "# Each element in the list is a dictionary that specifies the arguments\n", - "# for the initiate_chat method.\n", - "chat_results = number_agent.initiate_chats(\n", - " [\n", - " {\n", - " \"recipient\": adder_agent,\n", - " \"message\": \"14\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": multiplier_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": subtracter_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " {\n", - " \"recipient\": divider_agent,\n", - " \"message\": \"These are my numbers\",\n", - " \"max_turns\": 2,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First thing to note is that the `initiate_chats` method takes a list of\n", - "dictionaries, each dictionary contains the arguments for the `initiate_chat`\n", - "method.\n", - "\n", - "Second, each chat in the sequence has a maximum round of 2, as specified with\n", - "the setting `max_turns=2`, \n", - "which means each arithmetic operation is performed twice.\n", - "So you can see in the first chat the number 14 becomes 15 and then 16,\n", - "in the second chat the number 16 becomes 32 and then 64, and so on.\n", - "\n", - "Third, the carryover accumulates as the chats go on. In the second chat,\n", - "the carryover is the summary of the first chat \"16\".\n", - "In the third chat, the carryover is the summary of the first and second\n", - "chat, which is the list \"16\" and \"64\", and both numbers are operated upon.\n", - "In the forth and last chat, the carryover is the summary of all previous\n", - "chats, which is the list \"16\", \"64\", \"14\" and \"62\", and all of these\n", - "numbers are operated upon.\n", - "\n", - "The final note is that the `initiate_chats` method returns a list of\n", - "`ChatResult` objects, one for each chat in the sequence." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "First Chat Summary: 16\n", - "Second Chat Summary: 64\n", - "Third Chat Summary: 14\n", - "62\n", - "Fourth Chat Summary: 4\n", - "16\n", - "3.5\n", - "15.5\n" - ] - } - ], - "source": [ - "print(\"First Chat Summary: \", chat_results[0].summary)\n", - "print(\"Second Chat Summary: \", chat_results[1].summary)\n", - "print(\"Third Chat Summary: \", chat_results[2].summary)\n", - "print(\"Fourth Chat Summary: \", chat_results[3].summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Besides calling `initiate_chats` from the same sender agent, you can also\n", - "call a high-level function `autogen.agentchat.initiate_chats` to start\n", - "a sequence of two-agent chats with different sender agents. \n", - "This function allows you to specify the\n", - "sender agent for each chat in the sequence." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Group Chat\n", - "\n", - "So far we have only seen conversation patterns that involve two agents or \n", - "a sequence of two-agent chats. AutoGen provides a more general conversation\n", - "pattern called group chat, which involves more than two agents.\n", - "The core idea of group chat is that all agents contribute to a single\n", - "conversation thread and share the same context.\n", - "This is useful for tasks that require collaboration among multiple agents.\n", - "\n", - "The figure below illustrates how group chat works.\n", - "\n", - "```{=mdx}\n", - "![group_chat](./assets/group-chat.png)\n", - "```\n", - "\n", - "A group chat is orchestrated by a special\n", - "agent type `GroupChatManager`. In the first step of the group chat,\n", - "the Group Chat Manager selects an agent to speak. Then, the selected agent\n", - "speaks and the message is sent back to the Group Chat Manager,\n", - "who **broadcasts** the message to all other agents in the group.\n", - "This process repeats until the conversation stops.\n", - "\n", - "The Group Chat Manager can use several strategies to select the next agent.\n", - "Currently, the following strategies are supported:\n", - "\n", - "1. `round_robin`: The Group Chat Manager selects agents in a round-robin\n", - " fashion based on the order of the agents provided.\n", - "2. `random`: The Group Chat Manager selects agents randomly.\n", - "3. `manual`: The Group Chat Manager selects agents by asking for human input.\n", - "4. `auto`: The default strategy, which selects agents using the Group Chat\n", - " Manager's LLM." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To illustrate this pattern, let's consider a simple example of a group chat\n", - "among the same arithmetic operator agents as in the previous example,\n", - "with the objective of turning a number into a specific target number\n", - "using a sequence of arithmetic operations powered by the agents.\n", - "\n", - "In this example, we use the `auto` strategy to select the next agent.\n", - "To help the Group Chat Manager select the next agent, we also set the\n", - "`description` of the agents. Without the `description`, the Group Chat Manager\n", - "will use the agents' `system_message`, which may be not be the best choice." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# The `description` attribute is a string that describes the agent.\n", - "# It can also be set in `ConversableAgent` constructor.\n", - "adder_agent.description = \"Add 1 to each input number.\"\n", - "multiplier_agent.description = \"Multiply each input number by 2.\"\n", - "subtracter_agent.description = \"Subtract 1 from each input number.\"\n", - "divider_agent.description = \"Divide each input number by 2.\"\n", - "number_agent.description = \"Return the numbers given.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We first create a `GroupChat` object and provide the list of agents.\n", - "If we were to use the `round_robin` strategy, this list would specify the order\n", - "of the agents to be selected.\n", - "We also initialize the group chat with an empty message list and a maximum\n", - "round of 6, which means there will be at most 6 iteratiosn of selecting speaker,\n", - "agent speaks and broadcasting message." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "from autogen import GroupChat\n", - "\n", - "group_chat = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " messages=[],\n", - " max_round=6,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we create a `GroupChatManager` object and provide the `GroupChat` object as\n", - "input. We also need to specify the `llm_config` of the Group Chat Manager\n", - "so it can use the LLM to select the next agent (the `auto` strategy)." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "from autogen import GroupChatManager\n", - "\n", - "group_chat_manager = GroupChatManager(\n", - " groupchat=group_chat,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we have the Number Agent from before to start a two-agent chat with\n", - "the Group Chat Manager, which runs the group chat internally and terminates\n", - "the two-agent chat when the internal group chat is done.\n", - "Because the Number Agent is selected to speak by us, it counts as the \n", - "first round of the group chat." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "6\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "chat_result = number_agent.initiate_chat(\n", - " group_chat_manager,\n", - " message=\"My number is 3, I want to turn it into 13.\",\n", - " summary_method=\"reflection_with_llm\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can see that the Number Agent is selected to speak first, then the\n", - "Group Chat Manager selects the Multiplier Agent to speak, then the Adder\n", - "Agent, and so on. The number is operated upon by each agent in the group\n", - "chat, and the final result is 13.\n", - "\n", - "We can take a look at the summary of the group chat, provided by the \n", - "`ChatResult` object returned by the `initiate_chat` method." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The agents cooperatively manipulated the initial number (3) through multipliying, adding, and subtracting operations to reach the target number (13).\n" - ] - } - ], - "source": [ - "print(chat_result.summary)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Send Introductions\n", - "\n", - "In the previous example, we set the `description` of the agents to help the\n", - "Group Chat Manager select the next agent. This only helps the Group Chat Manager,\n", - "however, does not help the participating agents to know about each other.\n", - "Sometimes it is useful have each agent introduce themselves to other\n", - "agents in the group chat. This can be done by setting the `send_introductions=True`." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "group_chat_with_introductions = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " messages=[],\n", - " max_round=6,\n", - " send_introductions=True,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Under the hood, the Group Chat Manager sends a message containing the \n", - "agents' names and descriptions to all agents in the group chat before the\n", - "group chat starts." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Group Chat in a Sequential Chat\n", - "\n", - "Group chat can also be used as a part of a sequential chat.\n", - "In this case, the Group Chat Manager is treated as a regular agent\n", - "in the sequence of two-agent chats." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "6\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "13\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "Your number is 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Turn this number to 32.\n", - "\n", - "With the following carryover: \n", - "Your number is 13.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "Turn this number to 32.\n", - "Context: \n", - "Your number is 13.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "26\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "14\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "28\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "15\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "30\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/ekzhu/autogen/autogen/agentchat/chat.py:46: UserWarning: Repetitive recipients detected: The chat history will be cleared by default if a recipient appears more than once. To retain the chat history, please set 'clear_history=False' in the configuration of the repeating agent.\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "# Let's use the group chat with introduction messages created above.\n", - "group_chat_manager_with_intros = GroupChatManager(\n", - " groupchat=group_chat_with_introductions,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "# Start a sequence of two-agent chats between the number agent and\n", - "# the group chat manager.\n", - "chat_result = number_agent.initiate_chats(\n", - " [\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"message\": \"My number is 3, I want to turn it into 13.\",\n", - " },\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"message\": \"Turn this number to 32.\",\n", - " },\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above example, the Group Chat Manager runs the group chat two times.\n", - "In the first time the number 3 becomes 13, and the last message of this group chat\n", - "is being used as the carryover for the next group chat, which starts from 13.\n", - "\n", - "You can also see from the warning message that the Group Chat Manager's\n", - "history is being cleared after the first group chat, which is the default.\n", - "To keep the history of the Group Chat Manager, \n", - "you can set the `clear_history=False` for the first chat." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Constrained Speaker Selection\n", - "\n", - "Group chat is a powerful conversation pattern, but it can be hard to control\n", - "if the number of participating agents is large.\n", - "AutoGen provides a way to constrain the selection of the next speaker\n", - "by using the `allowed_or_disallowed_speaker_transitions` argument of the \n", - "`GroupChat` class.\n", - "\n", - "The `allowed_or_disallowed_speaker_transitions` argument is a dictionary\n", - "that maps a given agent to a list of agents that can (or cannot) \n", - "be selected to speak next. The `speaker_transitions_type` argument specifies\n", - "whether the transitions are allowed or disallowed.\n", - "\n", - "Here is an example:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "allowed_transitions = {\n", - " number_agent: [adder_agent, number_agent],\n", - " adder_agent: [multiplier_agent, number_agent],\n", - " subtracter_agent: [divider_agent, number_agent],\n", - " multiplier_agent: [subtracter_agent, number_agent],\n", - " divider_agent: [adder_agent, number_agent],\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, the allowed transitions are specified for each agent.\n", - "The Number Agent can be followed by the Adder Agent and the Number Agent, \n", - "the Adder Agent can be followed by the Multiplier Agent and the Number Agent,\n", - "and so on.\n", - "Let's put this into the group chat and see how it works.\n", - "The `speaker_transitions_type` is set to `allowed` so the transitions are\n", - "positive constraints." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", - "\n", - "3.5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4.5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "9\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", - "\n", - "4\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "5\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "10\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "10\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "constrained_graph_chat = GroupChat(\n", - " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", - " allowed_or_disallowed_speaker_transitions=allowed_transitions,\n", - " speaker_transitions_type=\"allowed\",\n", - " messages=[],\n", - " max_round=12,\n", - " send_introductions=True,\n", - ")\n", - "\n", - "constrained_group_chat_manager = GroupChatManager(\n", - " groupchat=constrained_graph_chat,\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - ")\n", - "\n", - "chat_result = number_agent.initiate_chat(\n", - " constrained_group_chat_manager,\n", - " message=\"My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\",\n", - " summary_method=\"reflection_with_llm\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This time, the agents are selected following the constraints we have specified." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Changing the select speaker role name\n", - "\n", - "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", - "a select speaker message is sent to the LLM to determine the next speaker.\n", - "\n", - "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", - "`assistant`, or `system`. The select speaker message is the last in the chat\n", - "sequence when used and, by default, has a role of `system`.\n", - "\n", - "When using some models, such as Mistral through Mistral.AI's API, the role on\n", - "the last message in the chat sequence has to be `user`.\n", - "\n", - "To change the default behaviour, Autogen provides a way to set the value of the\n", - "select speaker message's role to any string value by setting the\n", - "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", - "default value is `system` and by setting it to `user` you can accommodate the\n", - "last message role requirement of Mistral.AI's API." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Nested Chats\n", - "\n", - "The previous conversations patterns (two-agent chat, sequential chat, and group chat)\n", - "are useful for building complex workflows, however, they do not expose a\n", - "single conversational interface, which is often needed for scenarios like\n", - "question-answering bots and personal assistants.\n", - "In some other cases, it is also useful to package a workflow into a single\n", - "agent for reuse in a larger workflow. \n", - "AutoGen provides a way to achieve this by using nested chats.\n", - "\n", - "Nested chats is powered by the nested chats handler, which is a pluggable\n", - "component of `ConversableAgent`.\n", - "The figure below illustrates how the nested chats handler triggers\n", - "a sequence of nested chats when a message is received.\n", - "\n", - "```{=mdx}\n", - "![nested_chat](./assets/nested-chats.png)\n", - "```\n", - "\n", - "When a message comes in and passes the [human-in-the-loop component](./human-in-the-loop), \n", - "the nested chats handler checks if the message should trigger a nested chat\n", - "based on conditions specified by the user.\n", - "If the conditions are met, the nested chats handler starts a sequence of\n", - "nested chats specified using the sequential chats pattern.\n", - "In each of the nested chats, the sender agent is always the same agent\n", - "that triggered the nested chats.\n", - "In the end, the nested chat handler uses the results of the nested chats\n", - "to produce a response to the original message.\n", - "By default, the nested chat handler uses the summary of the last chat\n", - "as the response." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example of using nested chats to build an arithmetic agent that\n", - "packages arithmetic operations, code-based validation, and poetry into a single\n", - "agent. This arithmetic agent takes a number transformation request like \n", - "\"turn number 3 into 13\" and returns a poem that describes a transformation attempt.\n", - "\n", - "First we define the agents. We reuse the `group_chat_manager_with_intros`\n", - "from previous example to orchestrate the arithmetic operations." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "import tempfile\n", - "\n", - "temp_dir = tempfile.gettempdir()\n", - "\n", - "arithmetic_agent = ConversableAgent(\n", - " name=\"Arithmetic_Agent\",\n", - " llm_config=False,\n", - " human_input_mode=\"ALWAYS\",\n", - " # This agent will always require human input to make sure the code is\n", - " # safe to execute.\n", - " code_execution_config={\"use_docker\": False, \"work_dir\": temp_dir},\n", - ")\n", - "\n", - "code_writer_agent = ConversableAgent(\n", - " name=\"Code_Writer_Agent\",\n", - " system_message=\"You are a code writer. You write Python script in Markdown code blocks.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")\n", - "\n", - "poetry_agent = ConversableAgent(\n", - " name=\"Poetry_Agent\",\n", - " system_message=\"You are an AI poet.\",\n", - " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", - " human_input_mode=\"NEVER\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we define the nested chats using the sequential chat pattern.\n", - "All the senders are always `artihmetic_agent`." - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "nested_chats = [\n", - " {\n", - " \"recipient\": group_chat_manager_with_intros,\n", - " \"summary_method\": \"reflection_with_llm\",\n", - " \"summary_prompt\": \"Summarize the sequence of operations used to turn \" \"the source number into target number.\",\n", - " },\n", - " {\n", - " \"recipient\": code_writer_agent,\n", - " \"message\": \"Write a Python script to verify the arithmetic operations is correct.\",\n", - " \"summary_method\": \"reflection_with_llm\",\n", - " },\n", - " {\n", - " \"recipient\": poetry_agent,\n", - " \"message\": \"Write a poem about it.\",\n", - " \"max_turns\": 1,\n", - " \"summary_method\": \"last_msg\",\n", - " },\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we register the nested chats handler to the `arithmetic_agent` and\n", - "set the conditions for triggering the nested chats." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "arithmetic_agent.register_nested_chats(\n", - " nested_chats,\n", - " # The trigger function is used to determine if the agent should start the nested chat\n", - " # given the sender agent.\n", - " # In this case, the arithmetic agent will not start the nested chats if the sender is\n", - " # from the nested chats' recipient to avoid recursive calls.\n", - " trigger=lambda sender: sender not in [group_chat_manager_with_intros, code_writer_agent, poetry_agent],\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we call `generate_reply` to get a response from the `arithmetic_agent`\n", - "-- this will trigger a sequence of nested chats and return the summary of the\n", - "last nested chat as the response." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[31m\n", - ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "I have a number 3 and I want to turn it into 7.\n", - "\n", - "With the following carryover: \n", - "\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to chat_manager):\n", - "\n", - "I have a number 3 and I want to turn it into 7.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", - "\n", - "To give you the result, I'll add 1 to the number you gave me. So your new number is 4.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", - "\n", - "8\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", - "\n", - "7\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Write a Python script to verify the arithmetic operations is correct.\n", - "\n", - "With the following carryover: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", - "\n", - "Write a Python script to verify the arithmetic operations is correct.\n", - "Context: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "Here is a Python script to verify the aforementioned arithmetic operations:\n", - "\n", - "```python\n", - "# defining the initial value\n", - "initial_number = 3\n", - "\n", - "# Adding 1 to initial number\n", - "initial_number += 1\n", - "assert initial_number == 4, \"The first operation failed!\"\n", - "\n", - "# Multiplying the result by 2\n", - "initial_number *= 2\n", - "assert initial_number == 8, \"The second operation failed!\"\n", - "\n", - "# Subtracting 1 from the result\n", - "initial_number -= 1\n", - "assert initial_number == 7, \"The final operation failed!\"\n", - "\n", - "print(\"All operations were carried out successfully!\")\n", - "```\n", - "In the script, the entire process is broken down into steps. The `assert` function is used to verify the result at every step. If any of the operations doesn't yield the expected result, an `AssertionError` exception will be raised. If all operations pass, the message \"All operations were carried out successfully!\" will be printed.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[31m\n", - ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", - "\u001b[31m\n", - ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", - "\n", - "exitcode: 0 (execution succeeded)\n", - "Code output: \n", - "All operations were carried out successfully!\n", - "\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "Certainly, that means the python script was successful and every arithmetic operation performed correctly given the initial input and the steps performed.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[34mStart a new chat with the following message: \n", - "Write a poem about it.\n", - "\n", - "With the following carryover: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\u001b[0m\n", - "\u001b[34m\n", - "********************************************************************************\u001b[0m\n", - "\u001b[33mArithmetic_Agent\u001b[0m (to Poetry_Agent):\n", - "\n", - "Write a poem about it.\n", - "Context: \n", - "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", - "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\n", - "\n", - "--------------------------------------------------------------------------------\n", - "\u001b[33mPoetry_Agent\u001b[0m (to Arithmetic_Agent):\n", - "\n", - "From numbers, logic, pure mathematical creation,\n", - "Ponder this tale of numeric manipulation.\n", - "In the universe of Python where operations exist,\n", - "A story of integers and functions persist.\n", - "\n", - "Three was the number from where we began,\n", - "Oblivious to the journey and its grandiosely plan.\n", - "Added with 1, the sum it adorned,\n", - "A sweet quadruple in the dawn was formed.\n", - "\n", - "The saga continued with a twist of the tale,\n", - "The four was multiplied, while the winds wail.\n", - "The duo of four unfolded its wings,\n", - "An octet presence in our midst it brings.\n", - "\n", - "Then enters subtraction, sly and clever,\n", - "Removing one to alter the endeavor.\n", - "From eight, subtracted one in delight,\n", - "To finally bask in the glow of seven's light.\n", - "\n", - "Each operation, together they conspired,\n", - "In this tale of integers, creatively inspired.\n", - "Through life's equation, the script ran so free,\n", - "Amidst the language of Python, a symphony, you see.\n", - "\n", - "Tested with assert, cross-checked the chain,\n", - "Confirming accuracy in program's domain.\n", - "Each move calculated, each step so right,\n", - "In the maze of coding, found was the light. \n", - "\n", - "Such is the tale, of numbers and operations, \n", - "A dance among digits, logical iterations,\n", - "Just another day, in this AI poet's life,\n", - "Cutting through ambiguity, like a razor-sharp knife.\n", - "\n", - "--------------------------------------------------------------------------------\n" - ] - } - ], - "source": [ - "# Instead of using `initiate_chat` method to start another conversation,\n", - "# we can use the `generate_reply` method to get single reply to a message directly.\n", - "reply = arithmetic_agent.generate_reply(\n", - " messages=[{\"role\": \"user\", \"content\": \"I have a number 3 and I want to turn it into 7.\"}]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A poem is returned as the response, which describes the transformation attempt\n", - "from 3 to 7." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The implementation of the nested chats handler makes use of the\n", - "[`register_reply`](../reference/agentchat/conversable_agent/#register_reply)\n", - "method, which allows you to make extensive customization to\n", - " `ConversableAgent`. The GroupChatManager uses the same mechanism to implement the group chat.\n", - "\n", - "Nested chat is a powerful conversation pattern that allows you to package\n", - "complex workflows into a single agent.\n", - "You can hide [tool usages](/docs/tutorial/tool-use) within a single agent by having the tool-caller agent \n", - "starts a nested chat with a tool-executor agent and then use the result\n", - "of the nested chat to generate a response.\n", - "See the [nested chats for tool use notebook](/docs/notebooks/agentchat_nested_chats_chess) for an example." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Summary\n", - "\n", - "In this chapter, we covered two-agent chat, sequential chat, group chat,\n", - "and nested chat patterns. You can compose these patterns like LEGO blocks to \n", - "create complex workflows. You can also use [`register_reply`](../reference/agentchat/conversable_agent/#register_reply) to create new patterns.\n", - "\n", - "This is the last chapter on basic AutoGen concepts. \n", - "In the next chatper, we will give you some tips on what to do next." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "autogen", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.5" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conversation Patterns\n", + "\n", + "In the previous chapter we used two-agent conversation, which\n", + "can be started by the `initiate_chat` method.\n", + "Two-agent chat is a useful conversation pattern but AutoGen offers more.\n", + "In this chapter, we will first dig a little bit more into the two-agent \n", + "chat pattern and chat result, \n", + "then we will show you several conversation patterns that involve \n", + "more than two agents.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Two-Agent Chat and Chat Result\n", + "\n", + "Two-agent chat is the simplest from of conversation pattern. \n", + "We start a two-agent chat using the `initiate_chat` method of every \n", + "`ConversableAgent` agent.\n", + "We have already\n", + "seen multiple examples of two-agent chats in previous chapters\n", + "but we haven't covered the details.\n", + "\n", + "The following figure illustrates how two-agent chat works.\n", + "\n", + "```{=mdx}\n", + "![Two-agent chat](./assets/two-agent-chat.png)\n", + "```\n", + "\n", + "A two-agent chats takes two inputs: a message, which is a string provided by\n", + "the caller; a context, which specifies various parameters of the chat.\n", + "The sender agent uses its chat initializer method\n", + "(i.e., `generate_init_message` method of `ConversableAgent`)\n", + "to generate an initial message from the inputs, and\n", + "sends it to the recipient agent to start the chat.\n", + "The sender agent is the agent whose `initiate_chat` method is called, and\n", + "the recipient agent is the other agent.\n", + "\n", + "Once the chat terminates, the history of the chat is processed by a \n", + "chat summarizer. The summarizer summarizes the chat history and calculates\n", + "the token usage of the chat. \n", + "You can configure the type of summary using the `summary_method`\n", + "parameter of the `initiate_chat` method. By default, it is the last\n", + "message of the chat (i.e., `summary_method='last_msg'`).\n", + "\n", + "The example below is a two-agent chat between a student agent and a teacher\n", + "agent. Its summarizer uses an LLM-based summary." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", + "\n", + "What is triangle inequality?\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", + "\n", + "Triangle inequality theorem is a fundamental principle in geometry that states that the sum of the lengths of any two sides of a triangle must always be greater than the length of the third side. In a triangle with sides of lengths a, b, and c, the theorem can be written as:\n", + "\n", + "a + b > c\n", + "a + c > b\n", + "b + c > a\n", + "\n", + "Each of these represents the condition for one specific side (a, b, or c). All must be true for a triangle to exist.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mStudent_Agent\u001b[0m (to Teacher_Agent):\n", + "\n", + "Thank you for the explanation. This theorem helps in understanding the basic properties of a triangle. It can also be useful when solving geometric problems or proving other mathematical theorems. Can you give me an example of how we can use the triangle inequality theorem?\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[33mTeacher_Agent\u001b[0m (to Student_Agent):\n", + "\n", + "Absolutely! Here's an example:\n", + "\n", + "Suppose you're given three line segments with lengths 10, 7, and 3 units. The question is: \"Can these three line segments form a triangle?\"\n", + "\n", + "To answer this, you would use the triangle inequality theorem. Adding any two side lengths together should be greater than the third:\n", + "\n", + "- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\n", + "- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\n", + "- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of the third side (10), but not greater.\n", + "\n", + "So, these three lines cannot form a triangle, because not all pairs of sides satisfy the triangle inequality theorem.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "import os\n", + "from autogen import ConversableAgent\n", + "\n", + "student_agent = ConversableAgent(\n", + " name=\"Student_Agent\",\n", + " system_message=\"You are a student willing to learn.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "teacher_agent = ConversableAgent(\n", + " name=\"Teacher_Agent\",\n", + " system_message=\"You are a math teacher.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "chat_result = student_agent.initiate_chat(\n", + " teacher_agent,\n", + " message=\"What is triangle inequality?\",\n", + " summary_method=\"reflection_with_llm\",\n", + " max_turns=2,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see what the summary looks like.\n", + "The summary is stored in the `chat_result` object of the type `ChatResult` \n", + "that was returned by the `initiate_chat` method." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The triangle inequality theorem states that in a triangle, the sum of the lengths of any two sides must always be greater than the length of the third side. This principle is significant in geometry and is used in solving problems or proving theorems. For instance, if given three line segments, you can determine if they can form a triangle using this theorem.\n" + ] + } + ], + "source": [ + "print(chat_result.summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above example, the summary method is set to `reflection_with_llm` which\n", + "takes a list of messages from the conversation and summarize them \n", + "using a call to an LLM.\n", + "The summary method first tries to use the recipient's LLM, if it is not available\n", + "then it uses the sender's LLM. In this case the recipient is \"Teacher_Agent\" and\n", + "the sender is \"Student_Agent\".\n", + "The input prompt for the LLM is the following default prompt:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Summarize the takeaway from the conversation. Do not add any introductory phrases.\n" + ] + } + ], + "source": [ + "print(ConversableAgent.DEFAULT_summary_prompt)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also use a custom prompt by setting the `summary_prompt` argument\n", + "of `initiate_chat`.\n", + "\n", + "There are some other useful information in the `ChatResult` object, including\n", + "the conversation history, human input, and token cost." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'content': 'What is triangle inequality?', 'role': 'assistant'},\n", + " {'content': 'Triangle inequality theorem is a fundamental principle in '\n", + " 'geometry that states that the sum of the lengths of any two '\n", + " 'sides of a triangle must always be greater than the length of '\n", + " 'the third side. In a triangle with sides of lengths a, b, and c, '\n", + " 'the theorem can be written as:\\n'\n", + " '\\n'\n", + " 'a + b > c\\n'\n", + " 'a + c > b\\n'\n", + " 'b + c > a\\n'\n", + " '\\n'\n", + " 'Each of these represents the condition for one specific side (a, '\n", + " 'b, or c). All must be true for a triangle to exist.',\n", + " 'role': 'user'},\n", + " {'content': 'Thank you for the explanation. This theorem helps in '\n", + " 'understanding the basic properties of a triangle. It can also be '\n", + " 'useful when solving geometric problems or proving other '\n", + " 'mathematical theorems. Can you give me an example of how we can '\n", + " 'use the triangle inequality theorem?',\n", + " 'role': 'assistant'},\n", + " {'content': \"Absolutely! Here's an example:\\n\"\n", + " '\\n'\n", + " \"Suppose you're given three line segments with lengths 10, 7, and \"\n", + " '3 units. The question is: \"Can these three line segments form a '\n", + " 'triangle?\"\\n'\n", + " '\\n'\n", + " 'To answer this, you would use the triangle inequality theorem. '\n", + " 'Adding any two side lengths together should be greater than the '\n", + " 'third:\\n'\n", + " '\\n'\n", + " '- For sides 10 and 7: 10 + 7 = 17, which is larger than 3.\\n'\n", + " '- For sides 10 and 3: 10 + 3 = 13, which is larger than 7.\\n'\n", + " '- For sides 7 and 3: 7 + 3 = 10, which is equal to the length of '\n", + " 'the third side (10), but not greater.\\n'\n", + " '\\n'\n", + " 'So, these three lines cannot form a triangle, because not all '\n", + " 'pairs of sides satisfy the triangle inequality theorem.',\n", + " 'role': 'user'}]\n" + ] + } + ], + "source": [ + "# Get the chat history.\n", + "import pprint\n", + "\n", + "pprint.pprint(chat_result.chat_history)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That chat messages in the chat result are from the \n", + "recipient agent's perspective -- the sender is the \"assistant\" and the recipient\n", + "is the \"user\"." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "({'gpt-4-0613': {'completion_tokens': 399,\n", + " 'cost': 0.04521,\n", + " 'prompt_tokens': 709,\n", + " 'total_tokens': 1108},\n", + " 'total_cost': 0.04521},\n", + " {'total_cost': 0})\n" + ] + } + ], + "source": [ + "# Get the cost of the chat.\n", + "pprint.pprint(chat_result.cost)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sequential Chats\n", + "\n", + "The name of this pattern is self-explanatory -- it is a sequence of\n", + "chats between two agents, chained together by a mechanism called *carryover*,\n", + "which brings the summary of the previous chat to the context\n", + "of the next chat.\n", + "\n", + "This pattern is useful for complex task that can be broken down into \n", + "interdependent sub-tasks. \n", + "The figure below illustrate how this pattern works.\n", + "\n", + "```{=mdx}\n", + "![initiate_chats](./assets/sequential-two-agent-chat.png)\n", + "```\n", + "\n", + "In this pattern, the a pair of agents first start a two-agent chat,\n", + "then the summary of the conversation becomes a *carryover* for the next\n", + "two-agent chat. The next chat passes the carryover to the `carryover` parameter\n", + "of the context to generate its initial message.\n", + "\n", + "Carryover accumulates as the conversation moves forward,,\n", + "so each subsequent chat starts with all the carryovers \n", + "from previous chats.\n", + "\n", + "The figure above shows distinct recipient agents for all the chats, however,\n", + "the recipient agents in the sequence are allowed to repeat." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To illustrate this pattern, let's consider a simple example of arithmetic\n", + "operator agents. One agent \n", + "(called the \"Number_Agent\") is responsible for coming up with a number,\n", + "and other agents are responsible for performing a specific arithmetic\n", + "operation on the number, e.g., add 1, multiply by 2, etc.." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# The Number Agent always returns the same numbers.\n", + "number_agent = ConversableAgent(\n", + " name=\"Number_Agent\",\n", + " system_message=\"You return me the numbers I give you, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Adder Agent adds 1 to each number it receives.\n", + "adder_agent = ConversableAgent(\n", + " name=\"Adder_Agent\",\n", + " system_message=\"You add 1 to each number I give you and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Multiplier Agent multiplies each number it receives by 2.\n", + "multiplier_agent = ConversableAgent(\n", + " name=\"Multiplier_Agent\",\n", + " system_message=\"You multiply each number I give you by 2 and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Subtracter Agent subtracts 1 from each number it receives.\n", + "subtracter_agent = ConversableAgent(\n", + " name=\"Subtracter_Agent\",\n", + " system_message=\"You subtract 1 from each number I give you and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "# The Divider Agent divides each number it receives by 2.\n", + "divider_agent = ConversableAgent(\n", + " name=\"Divider_Agent\",\n", + " system_message=\"You divide each number I give you by 2 and return me the new numbers, one number each line.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Number Agent chats with the first operator agent, then the second\n", + "operator agent, and so on.\n", + "After each chat, the last message in the conversation (i.e., the result of the arithmetic operation from the operator agent)\n", + "is used as the summary of the chat.\n", + "This is specified by the `summary_method` parameter.\n", + "In the end we will have the result of the arithmetic operations." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "14\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Adder_Agent):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "16\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "32\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Multiplier_Agent):\n", + "\n", + "32\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "64\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\n", + "64\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "64\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "15\n", + "63\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Subtracter_Agent):\n", + "\n", + "15\n", + "63\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "14\n", + "62\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "These are my numbers\n", + "\n", + "With the following carryover: \n", + "16\n", + "64\n", + "14\n", + "62\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", + "\n", + "These are my numbers\n", + "Context: \n", + "16\n", + "64\n", + "14\n", + "62\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "8\n", + "32\n", + "7\n", + "31\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to Divider_Agent):\n", + "\n", + "8\n", + "32\n", + "7\n", + "31\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to Number_Agent):\n", + "\n", + "4\n", + "16\n", + "3.5\n", + "15.5\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "# Start a sequence of two-agent chats.\n", + "# Each element in the list is a dictionary that specifies the arguments\n", + "# for the initiate_chat method.\n", + "chat_results = number_agent.initiate_chats(\n", + " [\n", + " {\n", + " \"recipient\": adder_agent,\n", + " \"message\": \"14\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": multiplier_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": subtracter_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " {\n", + " \"recipient\": divider_agent,\n", + " \"message\": \"These are my numbers\",\n", + " \"max_turns\": 2,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First thing to note is that the `initiate_chats` method takes a list of\n", + "dictionaries, each dictionary contains the arguments for the `initiate_chat`\n", + "method.\n", + "\n", + "Second, each chat in the sequence has a maximum round of 2, as specified with\n", + "the setting `max_turns=2`, \n", + "which means each arithmetic operation is performed twice.\n", + "So you can see in the first chat the number 14 becomes 15 and then 16,\n", + "in the second chat the number 16 becomes 32 and then 64, and so on.\n", + "\n", + "Third, the carryover accumulates as the chats go on. In the second chat,\n", + "the carryover is the summary of the first chat \"16\".\n", + "In the third chat, the carryover is the summary of the first and second\n", + "chat, which is the list \"16\" and \"64\", and both numbers are operated upon.\n", + "In the forth and last chat, the carryover is the summary of all previous\n", + "chats, which is the list \"16\", \"64\", \"14\" and \"62\", and all of these\n", + "numbers are operated upon.\n", + "\n", + "The final note is that the `initiate_chats` method returns a list of\n", + "`ChatResult` objects, one for each chat in the sequence." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First Chat Summary: 16\n", + "Second Chat Summary: 64\n", + "Third Chat Summary: 14\n", + "62\n", + "Fourth Chat Summary: 4\n", + "16\n", + "3.5\n", + "15.5\n" + ] + } + ], + "source": [ + "print(\"First Chat Summary: \", chat_results[0].summary)\n", + "print(\"Second Chat Summary: \", chat_results[1].summary)\n", + "print(\"Third Chat Summary: \", chat_results[2].summary)\n", + "print(\"Fourth Chat Summary: \", chat_results[3].summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Besides calling `initiate_chats` from the same sender agent, you can also\n", + "call a high-level function `autogen.agentchat.initiate_chats` to start\n", + "a sequence of two-agent chats with different sender agents. \n", + "This function allows you to specify the\n", + "sender agent for each chat in the sequence." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Group Chat\n", + "\n", + "So far we have only seen conversation patterns that involve two agents or \n", + "a sequence of two-agent chats. AutoGen provides a more general conversation\n", + "pattern called group chat, which involves more than two agents.\n", + "The core idea of group chat is that all agents contribute to a single\n", + "conversation thread and share the same context.\n", + "This is useful for tasks that require collaboration among multiple agents.\n", + "\n", + "The figure below illustrates how group chat works.\n", + "\n", + "```{=mdx}\n", + "![group_chat](./assets/group-chat.png)\n", + "```\n", + "\n", + "A group chat is orchestrated by a special\n", + "agent type `GroupChatManager`. In the first step of the group chat,\n", + "the Group Chat Manager selects an agent to speak. Then, the selected agent\n", + "speaks and the message is sent back to the Group Chat Manager,\n", + "who **broadcasts** the message to all other agents in the group.\n", + "This process repeats until the conversation stops.\n", + "\n", + "The Group Chat Manager can use several strategies to select the next agent.\n", + "Currently, the following strategies are supported:\n", + "\n", + "1. `round_robin`: The Group Chat Manager selects agents in a round-robin\n", + " fashion based on the order of the agents provided.\n", + "2. `random`: The Group Chat Manager selects agents randomly.\n", + "3. `manual`: The Group Chat Manager selects agents by asking for human input.\n", + "4. `auto`: The default strategy, which selects agents using the Group Chat\n", + " Manager's LLM." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To illustrate this pattern, let's consider a simple example of a group chat\n", + "among the same arithmetic operator agents as in the previous example,\n", + "with the objective of turning a number into a specific target number\n", + "using a sequence of arithmetic operations powered by the agents.\n", + "\n", + "In this example, we use the `auto` strategy to select the next agent.\n", + "To help the Group Chat Manager select the next agent, we also set the\n", + "`description` of the agents. Without the `description`, the Group Chat Manager\n", + "will use the agents' `system_message`, which may be not be the best choice." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# The `description` attribute is a string that describes the agent.\n", + "# It can also be set in `ConversableAgent` constructor.\n", + "adder_agent.description = \"Add 1 to each input number.\"\n", + "multiplier_agent.description = \"Multiply each input number by 2.\"\n", + "subtracter_agent.description = \"Subtract 1 from each input number.\"\n", + "divider_agent.description = \"Divide each input number by 2.\"\n", + "number_agent.description = \"Return the numbers given.\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We first create a `GroupChat` object and provide the list of agents.\n", + "If we were to use the `round_robin` strategy, this list would specify the order\n", + "of the agents to be selected.\n", + "We also initialize the group chat with an empty message list and a maximum\n", + "round of 6, which means there will be at most 6 iteratiosn of selecting speaker,\n", + "agent speaks and broadcasting message." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from autogen import GroupChat\n", + "\n", + "group_chat = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " messages=[],\n", + " max_round=6,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we create a `GroupChatManager` object and provide the `GroupChat` object as\n", + "input. We also need to specify the `llm_config` of the Group Chat Manager\n", + "so it can use the LLM to select the next agent (the `auto` strategy)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "from autogen import GroupChatManager\n", + "\n", + "group_chat_manager = GroupChatManager(\n", + " groupchat=group_chat,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we have the Number Agent from before to start a two-agent chat with\n", + "the Group Chat Manager, which runs the group chat internally and terminates\n", + "the two-agent chat when the internal group chat is done.\n", + "Because the Number Agent is selected to speak by us, it counts as the \n", + "first round of the group chat." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "6\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "chat_result = number_agent.initiate_chat(\n", + " group_chat_manager,\n", + " message=\"My number is 3, I want to turn it into 13.\",\n", + " summary_method=\"reflection_with_llm\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see that the Number Agent is selected to speak first, then the\n", + "Group Chat Manager selects the Multiplier Agent to speak, then the Adder\n", + "Agent, and so on. The number is operated upon by each agent in the group\n", + "chat, and the final result is 13.\n", + "\n", + "We can take a look at the summary of the group chat, provided by the \n", + "`ChatResult` object returned by the `initiate_chat` method." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The agents cooperatively manipulated the initial number (3) through multipliying, adding, and subtracting operations to reach the target number (13).\n" + ] + } + ], + "source": [ + "print(chat_result.summary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Send Introductions\n", + "\n", + "In the previous example, we set the `description` of the agents to help the\n", + "Group Chat Manager select the next agent. This only helps the Group Chat Manager,\n", + "however, does not help the participating agents to know about each other.\n", + "Sometimes it is useful have each agent introduce themselves to other\n", + "agents in the group chat. This can be done by setting the `send_introductions=True`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "group_chat_with_introductions = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " messages=[],\n", + " max_round=6,\n", + " send_introductions=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Under the hood, the Group Chat Manager sends a message containing the \n", + "agents' names and descriptions to all agents in the group chat before the\n", + "group chat starts." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Group Chat in a Sequential Chat\n", + "\n", + "Group chat can also be used as a part of a sequential chat.\n", + "In this case, the Group Chat Manager is treated as a regular agent\n", + "in the sequence of two-agent chats." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "6\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "13\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "Your number is 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Turn this number to 32.\n", + "\n", + "With the following carryover: \n", + "Your number is 13.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "Turn this number to 32.\n", + "Context: \n", + "Your number is 13.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "26\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "14\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "28\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "15\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "30\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] }, - "nbformat": 4, - "nbformat_minor": 2 - } + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/ekzhu/autogen/autogen/agentchat/chat.py:46: UserWarning: Repetitive recipients detected: The chat history will be cleared by default if a recipient appears more than once. To retain the chat history, please set 'clear_history=False' in the configuration of the repeating agent.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "# Let's use the group chat with introduction messages created above.\n", + "group_chat_manager_with_intros = GroupChatManager(\n", + " groupchat=group_chat_with_introductions,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "# Start a sequence of two-agent chats between the number agent and\n", + "# the group chat manager.\n", + "chat_result = number_agent.initiate_chats(\n", + " [\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"message\": \"My number is 3, I want to turn it into 13.\",\n", + " },\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"message\": \"Turn this number to 32.\",\n", + " },\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above example, the Group Chat Manager runs the group chat two times.\n", + "In the first time the number 3 becomes 13, and the last message of this group chat\n", + "is being used as the carryover for the next group chat, which starts from 13.\n", + "\n", + "You can also see from the warning message that the Group Chat Manager's\n", + "history is being cleared after the first group chat, which is the default.\n", + "To keep the history of the Group Chat Manager, \n", + "you can set the `clear_history=False` for the first chat." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Constrained Speaker Selection\n", + "\n", + "Group chat is a powerful conversation pattern, but it can be hard to control\n", + "if the number of participating agents is large.\n", + "AutoGen provides a way to constrain the selection of the next speaker\n", + "by using the `allowed_or_disallowed_speaker_transitions` argument of the \n", + "`GroupChat` class.\n", + "\n", + "The `allowed_or_disallowed_speaker_transitions` argument is a dictionary\n", + "that maps a given agent to a list of agents that can (or cannot) \n", + "be selected to speak next. The `speaker_transitions_type` argument specifies\n", + "whether the transitions are allowed or disallowed.\n", + "\n", + "Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "allowed_transitions = {\n", + " number_agent: [adder_agent, number_agent],\n", + " adder_agent: [multiplier_agent, number_agent],\n", + " subtracter_agent: [divider_agent, number_agent],\n", + " multiplier_agent: [subtracter_agent, number_agent],\n", + " divider_agent: [adder_agent, number_agent],\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, the allowed transitions are specified for each agent.\n", + "The Number Agent can be followed by the Adder Agent and the Number Agent, \n", + "the Adder Agent can be followed by the Multiplier Agent and the Number Agent,\n", + "and so on.\n", + "Let's put this into the group chat and see how it works.\n", + "The `speaker_transitions_type` is set to `allowed` so the transitions are\n", + "positive constraints." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", + "\n", + "3.5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4.5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "9\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mDivider_Agent\u001b[0m (to chat_manager):\n", + "\n", + "4\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "5\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "10\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "10\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "constrained_graph_chat = GroupChat(\n", + " agents=[adder_agent, multiplier_agent, subtracter_agent, divider_agent, number_agent],\n", + " allowed_or_disallowed_speaker_transitions=allowed_transitions,\n", + " speaker_transitions_type=\"allowed\",\n", + " messages=[],\n", + " max_round=12,\n", + " send_introductions=True,\n", + ")\n", + "\n", + "constrained_group_chat_manager = GroupChatManager(\n", + " groupchat=constrained_graph_chat,\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + ")\n", + "\n", + "chat_result = number_agent.initiate_chat(\n", + " constrained_group_chat_manager,\n", + " message=\"My number is 3, I want to turn it into 10. Once I get to 10, keep it there.\",\n", + " summary_method=\"reflection_with_llm\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This time, the agents are selected following the constraints we have specified." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Changing the select speaker role name\n", + "\n", + "As part of the Group chat process, when the select_speaker_method is set to 'auto' (the default value),\n", + "a select speaker message is sent to the LLM to determine the next speaker.\n", + "\n", + "Each message in the chat sequence has a `role` attribute that is typically `user`,\n", + "`assistant`, or `system`. The select speaker message is the last in the chat\n", + "sequence when used and, by default, has a role of `system`.\n", + "\n", + "When using some models, such as Mistral through Mistral.AI's API, the role on\n", + "the last message in the chat sequence has to be `user`.\n", + "\n", + "To change the default behaviour, Autogen provides a way to set the value of the\n", + "select speaker message's role to any string value by setting the\n", + "`role_for_select_speaker_messages` parameter in the GroupChat's constructor. The\n", + "default value is `system` and by setting it to `user` you can accommodate the\n", + "last message role requirement of Mistral.AI's API." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Nested Chats\n", + "\n", + "The previous conversations patterns (two-agent chat, sequential chat, and group chat)\n", + "are useful for building complex workflows, however, they do not expose a\n", + "single conversational interface, which is often needed for scenarios like\n", + "question-answering bots and personal assistants.\n", + "In some other cases, it is also useful to package a workflow into a single\n", + "agent for reuse in a larger workflow. \n", + "AutoGen provides a way to achieve this by using nested chats.\n", + "\n", + "Nested chats is powered by the nested chats handler, which is a pluggable\n", + "component of `ConversableAgent`.\n", + "The figure below illustrates how the nested chats handler triggers\n", + "a sequence of nested chats when a message is received.\n", + "\n", + "```{=mdx}\n", + "![nested_chat](./assets/nested-chats.png)\n", + "```\n", + "\n", + "When a message comes in and passes the [human-in-the-loop component](./human-in-the-loop), \n", + "the nested chats handler checks if the message should trigger a nested chat\n", + "based on conditions specified by the user.\n", + "If the conditions are met, the nested chats handler starts a sequence of\n", + "nested chats specified using the sequential chats pattern.\n", + "In each of the nested chats, the sender agent is always the same agent\n", + "that triggered the nested chats.\n", + "In the end, the nested chat handler uses the results of the nested chats\n", + "to produce a response to the original message.\n", + "By default, the nested chat handler uses the summary of the last chat\n", + "as the response." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is an example of using nested chats to build an arithmetic agent that\n", + "packages arithmetic operations, code-based validation, and poetry into a single\n", + "agent. This arithmetic agent takes a number transformation request like \n", + "\"turn number 3 into 13\" and returns a poem that describes a transformation attempt.\n", + "\n", + "First we define the agents. We reuse the `group_chat_manager_with_intros`\n", + "from previous example to orchestrate the arithmetic operations." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "import tempfile\n", + "\n", + "temp_dir = tempfile.gettempdir()\n", + "\n", + "arithmetic_agent = ConversableAgent(\n", + " name=\"Arithmetic_Agent\",\n", + " llm_config=False,\n", + " human_input_mode=\"ALWAYS\",\n", + " # This agent will always require human input to make sure the code is\n", + " # safe to execute.\n", + " code_execution_config={\"use_docker\": False, \"work_dir\": temp_dir},\n", + ")\n", + "\n", + "code_writer_agent = ConversableAgent(\n", + " name=\"Code_Writer_Agent\",\n", + " system_message=\"You are a code writer. You write Python script in Markdown code blocks.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")\n", + "\n", + "poetry_agent = ConversableAgent(\n", + " name=\"Poetry_Agent\",\n", + " system_message=\"You are an AI poet.\",\n", + " llm_config={\"config_list\": [{\"model\": \"gpt-4\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]},\n", + " human_input_mode=\"NEVER\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we define the nested chats using the sequential chat pattern.\n", + "All the senders are always `artihmetic_agent`." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "nested_chats = [\n", + " {\n", + " \"recipient\": group_chat_manager_with_intros,\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " \"summary_prompt\": \"Summarize the sequence of operations used to turn \" \"the source number into target number.\",\n", + " },\n", + " {\n", + " \"recipient\": code_writer_agent,\n", + " \"message\": \"Write a Python script to verify the arithmetic operations is correct.\",\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " },\n", + " {\n", + " \"recipient\": poetry_agent,\n", + " \"message\": \"Write a poem about it.\",\n", + " \"max_turns\": 1,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we register the nested chats handler to the `arithmetic_agent` and\n", + "set the conditions for triggering the nested chats." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arithmetic_agent.register_nested_chats(\n", + " nested_chats,\n", + " # The trigger function is used to determine if the agent should start the nested chat\n", + " # given the sender agent.\n", + " # In this case, the arithmetic agent will not start the nested chats if the sender is\n", + " # from the nested chats' recipient to avoid recursive calls.\n", + " trigger=lambda sender: sender not in [group_chat_manager_with_intros, code_writer_agent, poetry_agent],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we call `generate_reply` to get a response from the `arithmetic_agent`\n", + "-- this will trigger a sequence of nested chats and return the summary of the\n", + "last nested chat as the response." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[31m\n", + ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "I have a number 3 and I want to turn it into 7.\n", + "\n", + "With the following carryover: \n", + "\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to chat_manager):\n", + "\n", + "I have a number 3 and I want to turn it into 7.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mAdder_Agent\u001b[0m (to chat_manager):\n", + "\n", + "To give you the result, I'll add 1 to the number you gave me. So your new number is 4.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mMultiplier_Agent\u001b[0m (to chat_manager):\n", + "\n", + "8\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mSubtracter_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mNumber_Agent\u001b[0m (to chat_manager):\n", + "\n", + "7\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Write a Python script to verify the arithmetic operations is correct.\n", + "\n", + "With the following carryover: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", + "\n", + "Write a Python script to verify the arithmetic operations is correct.\n", + "Context: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "Here is a Python script to verify the aforementioned arithmetic operations:\n", + "\n", + "```python\n", + "# defining the initial value\n", + "initial_number = 3\n", + "\n", + "# Adding 1 to initial number\n", + "initial_number += 1\n", + "assert initial_number == 4, \"The first operation failed!\"\n", + "\n", + "# Multiplying the result by 2\n", + "initial_number *= 2\n", + "assert initial_number == 8, \"The second operation failed!\"\n", + "\n", + "# Subtracting 1 from the result\n", + "initial_number -= 1\n", + "assert initial_number == 7, \"The final operation failed!\"\n", + "\n", + "print(\"All operations were carried out successfully!\")\n", + "```\n", + "In the script, the entire process is broken down into steps. The `assert` function is used to verify the result at every step. If any of the operations doesn't yield the expected result, an `AssertionError` exception will be raised. If all operations pass, the message \"All operations were carried out successfully!\" will be printed.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[31m\n", + ">>>>>>>> NO HUMAN INPUT RECEIVED.\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> USING AUTO REPLY...\u001b[0m\n", + "\u001b[31m\n", + ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Code_Writer_Agent):\n", + "\n", + "exitcode: 0 (execution succeeded)\n", + "Code output: \n", + "All operations were carried out successfully!\n", + "\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mCode_Writer_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "Certainly, that means the python script was successful and every arithmetic operation performed correctly given the initial input and the steps performed.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[34mStart a new chat with the following message: \n", + "Write a poem about it.\n", + "\n", + "With the following carryover: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\u001b[0m\n", + "\u001b[34m\n", + "********************************************************************************\u001b[0m\n", + "\u001b[33mArithmetic_Agent\u001b[0m (to Poetry_Agent):\n", + "\n", + "Write a poem about it.\n", + "Context: \n", + "First, 1 was added to the initial number 3 to make it 4. Then it was multiplied by 2 which resulted in 8. Finally, 1 was subtracted from 8 to reach the target number 7.\n", + "The Python script successfully performed and verified the arithmetic operations on the initial number provided. The steps included adding 1 to the initial number, multiplying the result by 2, and finally subtracting 1. The assert function was used to check the result at each step, and confirmed that all operations were carried out correctly.\n", + "\n", + "--------------------------------------------------------------------------------\n", + "\u001b[33mPoetry_Agent\u001b[0m (to Arithmetic_Agent):\n", + "\n", + "From numbers, logic, pure mathematical creation,\n", + "Ponder this tale of numeric manipulation.\n", + "In the universe of Python where operations exist,\n", + "A story of integers and functions persist.\n", + "\n", + "Three was the number from where we began,\n", + "Oblivious to the journey and its grandiosely plan.\n", + "Added with 1, the sum it adorned,\n", + "A sweet quadruple in the dawn was formed.\n", + "\n", + "The saga continued with a twist of the tale,\n", + "The four was multiplied, while the winds wail.\n", + "The duo of four unfolded its wings,\n", + "An octet presence in our midst it brings.\n", + "\n", + "Then enters subtraction, sly and clever,\n", + "Removing one to alter the endeavor.\n", + "From eight, subtracted one in delight,\n", + "To finally bask in the glow of seven's light.\n", + "\n", + "Each operation, together they conspired,\n", + "In this tale of integers, creatively inspired.\n", + "Through life's equation, the script ran so free,\n", + "Amidst the language of Python, a symphony, you see.\n", + "\n", + "Tested with assert, cross-checked the chain,\n", + "Confirming accuracy in program's domain.\n", + "Each move calculated, each step so right,\n", + "In the maze of coding, found was the light. \n", + "\n", + "Such is the tale, of numbers and operations, \n", + "A dance among digits, logical iterations,\n", + "Just another day, in this AI poet's life,\n", + "Cutting through ambiguity, like a razor-sharp knife.\n", + "\n", + "--------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "# Instead of using `initiate_chat` method to start another conversation,\n", + "# we can use the `generate_reply` method to get single reply to a message directly.\n", + "reply = arithmetic_agent.generate_reply(\n", + " messages=[{\"role\": \"user\", \"content\": \"I have a number 3 and I want to turn it into 7.\"}]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A poem is returned as the response, which describes the transformation attempt\n", + "from 3 to 7." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The implementation of the nested chats handler makes use of the\n", + "[`register_reply`](../reference/agentchat/conversable_agent/#register_reply)\n", + "method, which allows you to make extensive customization to\n", + " `ConversableAgent`. The GroupChatManager uses the same mechanism to implement the group chat.\n", + "\n", + "Nested chat is a powerful conversation pattern that allows you to package\n", + "complex workflows into a single agent.\n", + "You can hide [tool usages](/docs/tutorial/tool-use) within a single agent by having the tool-caller agent \n", + "starts a nested chat with a tool-executor agent and then use the result\n", + "of the nested chat to generate a response.\n", + "See the [nested chats for tool use notebook](/docs/notebooks/agentchat_nested_chats_chess) for an example." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "In this chapter, we covered two-agent chat, sequential chat, group chat,\n", + "and nested chat patterns. You can compose these patterns like LEGO blocks to \n", + "create complex workflows. You can also use [`register_reply`](../reference/agentchat/conversable_agent/#register_reply) to create new patterns.\n", + "\n", + "This is the last chapter on basic AutoGen concepts. \n", + "In the next chatper, we will give you some tips on what to do next." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "autogen", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From fb0594448da12fe612d6e606ed7df51cf9577c5c Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:59:08 -0400 Subject: [PATCH 09/10] update --- website/docs/topics/groupchat/_category_.json | 2 +- .../customized_speaker_selection.ipynb | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/website/docs/topics/groupchat/_category_.json b/website/docs/topics/groupchat/_category_.json index 3bf8fc4b8b37..da7c00366565 100644 --- a/website/docs/topics/groupchat/_category_.json +++ b/website/docs/topics/groupchat/_category_.json @@ -1,5 +1,5 @@ { "position": 5, - "label": "Using GroupChat", + "label": "GroupChat", "collapsible": true } diff --git a/website/docs/topics/groupchat/customized_speaker_selection.ipynb b/website/docs/topics/groupchat/customized_speaker_selection.ipynb index 4aa7adb28513..1ab26667e2d5 100644 --- a/website/docs/topics/groupchat/customized_speaker_selection.ipynb +++ b/website/docs/topics/groupchat/customized_speaker_selection.ipynb @@ -66,13 +66,23 @@ "outputs": [], "source": [ "import autogen\n", + "import os\n", "\n", - "config_list = autogen.config_list_from_json(\n", - " \"OAI_CONFIG_LIST\",\n", - " filter_dict={\n", - " \"model\": [\"gpt-4-1106-preview\"],\n", - " },\n", - ")" + "# Put your api key in the environment variable OPENAI_API_KEY\n", + "config_list = [\n", + " {\n", + " \"model\": \"gpt-4-0125-preview\",\n", + " \"api_key\": os.environ[\"OPENAI_API_KEY\"],\n", + " }\n", + "]\n", + "\n", + "# You can also create an file called \"OAI_CONFIG_LIST\" and store your config there\n", + "# config_list = autogen.config_list_from_json(\n", + "# \"OAI_CONFIG_LIST\",\n", + "# filter_dict={\n", + "# \"model\": [\"gpt-4-0125-preview\"],\n", + "# },\n", + "# )" ] }, { From 492636716c77a6a06794c0e69ebbc551a099efe7 Mon Sep 17 00:00:00 2001 From: Yiran Wu <32823396+kevin666aa@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:15:28 -0400 Subject: [PATCH 10/10] update --- .../docs/topics/groupchat/customized_speaker_selection.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/topics/groupchat/customized_speaker_selection.ipynb b/website/docs/topics/groupchat/customized_speaker_selection.ipynb index 1ab26667e2d5..830215a5e90b 100644 --- a/website/docs/topics/groupchat/customized_speaker_selection.ipynb +++ b/website/docs/topics/groupchat/customized_speaker_selection.ipynb @@ -65,9 +65,10 @@ "metadata": {}, "outputs": [], "source": [ - "import autogen\n", "import os\n", "\n", + "import autogen\n", + "\n", "# Put your api key in the environment variable OPENAI_API_KEY\n", "config_list = [\n", " {\n",