diff --git a/website/docs/topics/swarm.ipynb b/website/docs/topics/swarm.ipynb index 05a8454346..7e8263f0db 100644 --- a/website/docs/topics/swarm.ipynb +++ b/website/docs/topics/swarm.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Swarm Ochestration\n", + "# Swarm Orchestration\n", "\n", "With AG2, you can initiate a Swarm Chat similar to OpenAI's [Swarm](https://github.com/openai/swarm). This orchestration offers two main features:\n", "\n", @@ -31,7 +31,7 @@ "- The docstring of the function will be used as the prompt. So make sure to write a clear description. \n", "- The function name will be used as the tool name.\n", "\n", - "### Registering Handoffs\n", + "### Registering Handoffs to agents\n", "While you can create a function to decide what next agent to call, we provide a quick way to register the handoff using `ON_CONDITION`. We will craft this transition function and add it to the LLM config directly.\n", "\n", "```python\n", @@ -55,6 +55,89 @@ "# You can also use agent_1.add_functions to add more functions after initialization\n", "```\n", "\n", + "### Registering Handoffs to a nested chat\n", + "In addition to transferring to an agent, you can also trigger a nested chat by doing a handoff and using `ON_CONDITION`. This is a useful way to perform sub-tasks without that work becoming part of the broader swarm's messages.\n", + "\n", + "Configuring the nested chat is similar to [establishing a nested chat for an agent](https://ag2ai.github.io/ag2/docs/tutorial/conversation-patterns#nested-chats).\n", + "\n", + "Nested chats are a set of sequential chats and these are defined like so:\n", + "```python\n", + "nested_chats = [\n", + " {\n", + " \"recipient\": my_first_agent,\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " \"summary_prompt\": \"Summarize the conversation into bullet points.\",\n", + " },\n", + " {\n", + " \"recipient\": poetry_agent,\n", + " \"message\": \"Write a poem about the context.\",\n", + " \"max_turns\": 1,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + "]\n", + "```\n", + "\n", + "New to nested chats within swarms is the ability to **carryover some context from the swarm chat into the nested chat**. This is done by adding a carryover configuration. If you're not using carryover, then no messages from the swarm chat will be brought into the nested chat.\n", + "\n", + "The carryover is applicable only to the first chat in the nested chats and works together with that nested chat's \"message\" value, if any.\n", + "\n", + "```python\n", + "my_carryover_config = {\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " \"summary_args\": {\"summary_prompt\": \"Summarise the conversation into bullet points.\"}\n", + " }\n", + "```\n", + "\n", + "The `summary_method` can be (with messages referring to the swarm chat's messages): \n", + "\n", + "- `\"all\"` - messages will be converted to a new-line concatenated string, e.g. `[first nested chat message]\\nContext: \\n[swarm message 1]\\n[swarm message 2]\\n...`\n", + "- `\"last_msg\"` - the latest message will be added, e.g. `[first nested chat message]\\nContext: \\n[swarm's latest message]`\n", + "- `\"reflection_with_llm\"` - utilises an LLM to interpret the messages and its resulting response will be added, e.g. `[first nested chat message]\\nContext: \\n[llm response]`\n", + "- `Callable` - a function that returns the full message (this will not concatenate with the first nested chat's message, it will replace it entirely).\n", + "\n", + "The signature of the `summary_method` callable is: \n", + "`def my_method(agent: ConversableAgent, messages: List[Dict[str, Any]], summary_args: Dict) -> str:`\n", + "\n", + "Both the \"reflection_with_llm\" and Callable will be able to utilise the `summary_args` if they are included.\n", + "\n", + "With your configuration available, you can add it to the first chat in the nested chat:\n", + "```python\n", + "nested_chats = [\n", + " {\n", + " \"recipient\": my_first_agent,\n", + " \"summary_method\": \"reflection_with_llm\",\n", + " \"summary_prompt\": \"Summarize the conversation into bullet points.\",\n", + " \"carryover_config\": my_carryover_config,\n", + " },\n", + " {\n", + " \"recipient\": poetry_agent,\n", + " \"message\": \"Write a poem about the context.\",\n", + " \"max_turns\": 1,\n", + " \"summary_method\": \"last_msg\",\n", + " },\n", + "]\n", + "```\n", + "\n", + "Finally, we add the nested chat as a handoff in the same way as we do to an agent:\n", + "\n", + "```python\n", + "agent_1.handoff(\n", + " hand_to=[ON_CONDITION(\n", + " target={\n", + " \"chat_queue\":[nested_chats],\n", + " \"config\": Any,\n", + " \"reply_func_from_nested_chats\": None,\n", + " \"use_async\": False\n", + " },\n", + " condition=\"condition_1\")\n", + " ]\n", + " )\n", + "```\n", + "\n", + "See the documentation on [registering a nested chat](https://ag2ai.github.io/ag2/docs/reference/agentchat/conversable_agent#register_nested_chats) for further information on the parameters `reply_func_from_nested_chats`, `use_async`, and `config`.\n", + "\n", + "Once a nested chat is complete, the resulting output from the last chat in the nested chats will be returned as the agent that triggered the nested chat's response.\n", + "\n", "### AFTER_WORK\n", "\n", "When the last active agent's response doesn't suggest a tool call or handoff, the chat will terminate by default. However, you can register an `AFTER_WORK` handoff to define a fallback agent if you don't want the chat to end at this agent. At the swarm chat level, you also pass in an `AFTER_WORK` handoff to define the fallback mechanism for the entire chat.\n",