Skip to main content

2 posts tagged with "swarm"

View All Tags

· 6 min read
Mark Sze
Tvrtko Sternak
Davor Runje
AgentGenie
Qingyun Wu

FalkorDB Web

TL;DR:

  • We introduce a new ability for AG2 agents, Graph RAG with FalkorDB, providing the power of knowledge graphs
  • Structured outputs, using OpenAI models, provide strict adherence to data models to improve reliability and agentic flows
  • Nested chats are now available with a Swarm

FalkorDB Graph RAG

Typically, RAG uses vector databases, which store information as embeddings, mathematical representations of data points. When a query is received, it's also converted into an embedding, and the vector database retrieves the most similar embeddings based on distance metrics.

Graph-based RAG, on the other hand, leverages graph databases, which represent knowledge as a network of interconnected entities and relationships. When a query is received, Graph RAG traverses the graph to find relevant information based on the query's structure and semantics.

Advantages of Graph RAG:

  1. Enhanced Contextual Understanding Graph RAG captures the relationships between entities in the knowledge graph, providing richer context for LLMs. This enables more accurate and nuanced responses compared to traditional RAG, which often retrieves isolated facts.

  2. Improved Reasoning Abilities The interconnected nature of graph databases allows Graph RAG to perform reasoning and inference over the knowledge. This is crucial for tasks requiring complex understanding and logical deductions, such as question answering and knowledge discovery.

  3. Handling Complex Relationships Graph RAG excels at representing and leveraging intricate relationships between entities, allowing it to tackle complex queries that involve multiple entities and their connections. This makes it suitable for domains with rich interconnected data, like healthcare or finance.

  4. Explainable Retrieval The graph traversal process in Graph RAG provides a clear path for understanding why specific information was retrieved. This transparency is valuable for visualizing, debugging and building trust in the system's outputs.

FalkorDB Graph RAG capabilities

FalkorDB is a high performant graph database enabling queries with reduced hallucinations.

In release 0.5, AG2 has added the ability to add FalkorDB Graph RAG querying capabilities to an agent. These agents will behave like other agents in an orchestration but will query the FalkorDB and return the results as a response.

An LLM is incorporated into this capability, allowing data to be classified during ingestion, queries to be optimised, and results to be provided back in natural language.

See the FalkorDB docs for how to get a database setup.

Below is a simple example of creating a FalkorDB Graph RAG agent in AG2. A data file of web page on the movie The Matrix is ingested into the database and the knowledge graph is created automatically before being queried. Data file here.

For example:

import os
import autogen

config_list = autogen.config_list_from_json(env_or_file="OAI_CONFIG_LIST")
os.environ["OPENAI_API_KEY"] = config_list[0]["api_key"] # Utilised by the FalkorGraphQueryEngine

from autogen import ConversableAgent, UserProxyAgent
from autogen.agentchat.contrib.graph_rag.document import Document, DocumentType
from autogen.agentchat.contrib.graph_rag.falkor_graph_query_engine import FalkorGraphQueryEngine
from autogen.agentchat.contrib.graph_rag.falkor_graph_rag_capability import FalkorGraphRagCapability

# Auto generate graph schema from unstructured data
input_path = "../test/agentchat/contrib/graph_rag/the_matrix.txt"
input_documents = [Document(doctype=DocumentType.TEXT, path_or_url=input_path)]

# Create FalkorGraphQueryEngine
query_engine = FalkorGraphQueryEngine(
name="The_Matrix_Auto",
host="172.18.0.3", # Change
port=6379, # if needed
)

# Ingest data and initialize the database
query_engine.init_db(input_doc=input_documents)

# Create a ConversableAgent
graph_rag_agent = ConversableAgent(
name="matrix_agent",
human_input_mode="NEVER",
)

# Associate the capability with the agent
graph_rag_capability = FalkorGraphRagCapability(query_engine)
graph_rag_capability.add_to_agent(graph_rag_agent)

# Create a user proxy agent to converse with our RAG agent
user_proxy = UserProxyAgent(
name="user_proxy",
human_input_mode="ALWAYS",
)

user_proxy.initiate_chat(
graph_rag_agent,
message="Name a few actors who've played in 'The Matrix'")

Here's the output showing the FalkorDB Graph RAG agent, matrix_agent, finding relevant actors and then being able to confirm that there are no other actors in the movie, when queried.

user_proxy (to matrix_agent):

Name a few actors who've played in 'The Matrix'

--------------------------------------------------------------------------------
matrix_agent (to user_proxy):

Keanu Reeves, Laurence Fishburne, Carrie-Anne Moss, and Hugo Weaving are a few actors who've played in 'The Matrix'.

--------------------------------------------------------------------------------
user_proxy (to matrix_agent):

Who else acted in The Matrix?

--------------------------------------------------------------------------------
matrix_agent (to user_proxy):

Based on the provided information, there is no additional data about other actors who acted in 'The Matrix' outside of Keanu Reeves, Laurence Fishburne, Carrie-Anne Moss, and Hugo Weaving.

--------------------------------------------------------------------------------

For a more in-depth example, see this notebook where we create this Trip Planner workflow. Trip Planner

Structured Outputs

Also featured in the Trip Planner example above, AG2 now enables your agents to respond with a structured output, aligned with a Pydantic model.

This capability provides strict responses, where the LLM provides the data in a structure that you define. This enables you to interpret and validate information precisely, providing more robustness to an LLM-based workflow.

This is available when using OpenAI LLMs and is set in the LLM configuration (gpt-3.5-turbo-0613 or gpt-4-0613 and above):

from pydantic import BaseModel

# Here is our model
class Step(BaseModel):
explanation: str
output: str

class MathReasoning(BaseModel):
steps: list[Step]
final_answer: str

# response_format is added to our configuration
llm_config = {
"config_list":
[
{
"api_type": "openai",
"model": "gpt-4o-mini",
"api_key": os.getenv("OPENAI_API_KEY"),
"response_format": MathReasoning
}
]
}

# This agent's responses will now be based on the MathReasoning model
assistant = autogen.AssistantAgent(
name="Math_solver",
llm_config=llm_config,
)

A sample response to how can I solve 8x + 7 = -23 would be:

{
"steps": [
{
"explanation": "To isolate the term with x, we first subtract 7 from both sides of the equation.",
"output": "8x + 7 - 7 = -23 - 7 -> 8x = -30."
},
{
"explanation": "Now that we have 8x = -30, we divide both sides by 8 to solve for x.",
"output": "x = -30 / 8 -> x = -3.75."
}
],
"final_answer": "x = -3.75"
}

See the Trip Planner and Structured Output notebooks to start using Structured Outputs.

Nested Chats in Swarms

Building on the capability of Swarms, AG2 now allows you to utilise a nested chat within a swarm. By providing this capability, you can perform sub-tasks or solve more complex tasks, while maintaining a simple swarm setup.

Additionally, adding a carry over configurations allow you to control what information from the swarm messages is carried over to the nested chat. Options include bringing over context from all messages, the last message, an LLM summary of the messages, or based on a own custom function.

See the Swarm documentation for more information.

For Further Reading

Do you have interesting use cases for FalkorDB / RAG? Would you like to see more features or improvements? Please join our Discord server for discussion.

· 8 min read
Yiran Wu
Mark Sze

AG2 now provides an implementation of the swarm orchestration from OpenAI's Swarm framework, with some additional features!

Background: the swarm orchestration is a multi-agent collaboration where agents execute tasks and are responsible for handing them off to other agents.

Here are the key features of the swarm orchestration:

  • Hand-offs: Agents can transfer control to another agent, enabling smooth and direct transitions within workflows.
  • Context variables: Agents can dynamically update a shared memory through function calls, maintaining context and adaptability throughout the process.

Besides these core features, AG2 provides:

  • Simple Interface for Tool Call/Handoff Registration: When creating a swarm agent, you can pass in a list of functions to be registered directly. We also provide a simple method to register handoffs.
  • Transition Beyond Tool Calls: We enable the ability to automatically transfer to a nominated swarm agent when an agent has completed their task. We will extend this to allow other transitions in the future (e.g., use a function to determine the next agent ).
  • Built-in human-in-the-loop: Adding a user agent (UserProxyAgent) to your swarm will allow swarm agents to transition back to the user. Provides a means to clarify and confirm with the user without breaking out of the swarm.

This feature builds on GroupChat, offering a simpler interface to use swarm orchestration. For comparison, see two implementations of the same example: one using swarm orchestration and another naive implementation with GroupChat (Legacy).

Handoffs

Before we dive into a swarm example, an important concept in swarm orchestration is when and how an agent hands off to another agent.

Providing additional flexibility, we introduce the capability to define an after-work handoff. Think of it as the agent's next action after completing their task. It can be to hand off to another agent, revert to the user, stay with the agent for another iteration, or terminate the conversation.

The following are the prioritized handoffs for each iteration of the swarm.

  1. Agent-level: Calls a tool that returns a swarm agent: A swarm agent's tool call returns the next agent to hand off to.
  2. Agent-level: Calls a pre-defined conditional handoff: A swarm agent has an ON_CONDITION handoff that is chosen by the LLM (behaves like a tool call).
  3. Agent-level: After work hand off: When no tool calls are made it can use an, optional, AFTER_WORK handoff that is a preset option or a nominated swarm agent.
  4. Swarm-level: After work handoff: If the agent does not have an AFTER_WORK handoff, the swarm's AFTER_WORK handoff will be used.

In the following code sample a SwarmAgent named responder has:

  • Two conditional handoffs registered (ON_CONDITION), specifying the agent to hand off to and the condition to trigger the handoff.
  • An after-work handoff (AFTER_WORK) nominated using one of the preset options (TERMINATE, REVERT_TO_USER, STAY). This could also be a swarm agent.
responder.register_hand_off(
hand_to=[
ON_CONDITION(weather, "If you need weather data, hand off to the Weather_Agent"),
ON_CONDITION(travel_advisor, "If you have weather data but need formatted recommendations, hand off to the Travel_Advisor_Agent"),
AFTER_WORK(AfterWorkOption.REVERT_TO_USER),
]
)

You can specify the swarm-level after work handoff when initiating the swarm (here we nominate to terminate):

history, context, last_agent = initiate_swarm_chat(
initial_agent=responder,
agents=my_list_of_swarm_agents,
max_rounds=30,
messages=messages,
after_work=AFTER_WORK(AfterWorkOption.TERMINATE)
)

Creating a swarm

  1. Define the functions that can be used by your SwarmAgents.
  2. Create your SwarmAgents (which derives from ConversableAgent).
  3. For each swarm agent, specify the handoffs (transitions to another agent) and what to do when they have finished their work (termed After Work).
  4. Optionally, create your context dictionary.
  5. Call initiate_swarm_chat.

Example

This example of managing refunds demonstrates the context handling, swarm and agent-level conditional and after work hand offs, and the human-in-the-loop feature.

from autogen import initiate_swarm_chat, SwarmAgent, SwarmResult, ON_CONDITION, AFTER_WORK, AfterWorkOption
from autogen import UserProxyAgent
import os

# All our swarm agents will use GPT-4o-mini from OpenAI
llm_config = {...}

# We configure our starting context dictionary
context_variables = {
"passport_number": "",
"customer_verified": False,
"refund_approved": False,
"payment_processed": False
}

# Functions that our swarm agents will be assigned
# They can return a SwarmResult, a SwarmAgent, or a string
# SwarmResult allows you to update context_variables and/or hand off to another agent
def verify_customer_identity(passport_number: str, context_variables: dict) -> str:
context_variables["passport_number"] = passport_number
context_variables["customer_verified"] = True
return SwarmResult(values="Customer identity verified", context_variables=context_variables)

def approve_refund_and_transfer(context_variables: dict) -> str:
context_variables["refund_approved"] = True
return SwarmResult(values="Refund approved", context_variables=context_variables, agent=payment_processor)

def process_refund_payment(context_variables: dict) -> str:
context_variables["payment_processed"] = True
return SwarmResult(values="Payment processed successfully", context_variables=context_variables)

# Swarm Agents, similar to ConversableAgent, but with functions and hand offs (specified later)
customer_service = SwarmAgent(
name="CustomerServiceRep",
system_message="""You are a customer service representative.
First verify the customer's identity by asking for the customer's passport number,
then calling the verify_customer_identity function,
finally, transfer the case to the refund specialist.""",
llm_config=llm_config,
functions=[verify_customer_identity],
)

refund_specialist = SwarmAgent(
name="RefundSpecialist",
system_message="""You are a refund specialist.
Review the case and approve the refund, then transfer to the payment processor.""",
llm_config=llm_config,
functions=[approve_refund_and_transfer],
)

payment_processor = SwarmAgent(
name="PaymentProcessor",
system_message="""You are a payment processor.
Process the refund payment and provide a confirmation message to the customer.""",
llm_config=llm_config,
functions=[process_refund_payment],
)

satisfaction_surveyor = SwarmAgent(
name="SatisfactionSurveyor",
system_message="""You are a customer satisfaction specialist.
Ask the customer to rate their experience with the refund process.""",
llm_config=llm_config,
)

# Conditional and After work hand offs

customer_service.register_hand_off(
hand_to=[
ON_CONDITION(refund_specialist, "After customer verification, transfer to refund specialist"),
AFTER_WORK(AfterWorkOption.REVERT_TO_USER)
]
)

payment_processor.register_hand_off(
hand_to=[
AFTER_WORK(satisfaction_surveyor),
]
)

# Our human, you, allowing swarm agents to revert back for more information
user = UserProxyAgent(name="User", code_execution_config=False)

# Initiate the swarm
# Returns the ChatResult, final context, and last speaker

chat_result, context_variables, last_speaker = initiate_swarm_chat(
initial_agent=customer_service, # Starting agent
agents=[customer_service, refund_specialist, payment_processor, satisfaction_surveyor],
user_agent=user, # Human user
messages="Customer requesting refund for order #12345",
context_variables=context_variables, # Context
after_work=AFTER_WORK(AfterWorkOption.TERMINATE) # Swarm-level after work hand off
)


print(f"Context Variables:\n{json.dumps(context_variables, indent=2)}")

And here's the output, showing the flow of agents.

User (to chat_manager):

Customer requesting refund for order #12345

--------------------------------------------------------------------------------

Next speaker: CustomerServiceRep

CustomerServiceRep (to chat_manager):

To assist you with the refund for order #12345,
I need to verify your identity.
Could you please provide your passport number?

--------------------------------------------------------------------------------

Next speaker: User

Replying as User. Provide feedback to chat_manager.
Press enter to skip and use auto-reply,
or type 'exit' to end the conversation: AUS923828C

User (to chat_manager):

AUS923828C

--------------------------------------------------------------------------------

Next speaker: CustomerServiceRep

CustomerServiceRep (to chat_manager):

***** Suggested tool call (call_wfx2VoCmuCKDFKV5xcmB6kSc): verify_customer_identity *****
Arguments:
{"passport_number":"AUS923828C"}
*****************************************************************************************

--------------------------------------------------------------------------------

Next speaker: Tool_Execution


>>>>>>>> EXECUTING FUNCTION verify_customer_identity...
Tool_Execution (to chat_manager):

***** Response from calling tool (call_wfx2VoCmuCKDFKV5xcmB6kSc) *****
Customer identity verified
**********************************************************************

--------------------------------------------------------------------------------

Next speaker: CustomerServiceRep

CustomerServiceRep (to chat_manager):

***** Suggested tool call (call_Jz1viRLeJuOltPRcKfYZ8bgH): transfer_to_RefundSpecialist *****
Arguments:
{}
*********************************************************************************************

--------------------------------------------------------------------------------

Next speaker: Tool_Execution


>>>>>>>> EXECUTING FUNCTION transfer_to_RefundSpecialist...
Tool_Execution (to chat_manager):

***** Response from calling tool (call_Jz1viRLeJuOltPRcKfYZ8bgH) *****
SwarmAgent --> RefundSpecialist
**********************************************************************

--------------------------------------------------------------------------------

Next speaker: RefundSpecialist

RefundSpecialist (to chat_manager):

***** Suggested tool call (call_c4uhy8Mi3Ihe3tVRFVG9M8Uw): approve_refund_and_transfer *****
Arguments:
{}
********************************************************************************************

--------------------------------------------------------------------------------

Next speaker: Tool_Execution


>>>>>>>> EXECUTING FUNCTION approve_refund_and_transfer...
Tool_Execution (to chat_manager):

***** Response from calling tool (call_c4uhy8Mi3Ihe3tVRFVG9M8Uw) *****
Refund approved
**********************************************************************

--------------------------------------------------------------------------------

Next speaker: PaymentProcessor

PaymentProcessor (to chat_manager):

***** Suggested tool call (call_qrs5ysx89rQqMFtVuqMUb9O0): process_refund_payment *****
Arguments:
{}
***************************************************************************************

--------------------------------------------------------------------------------

Next speaker: Tool_Execution


>>>>>>>> EXECUTING FUNCTION process_refund_payment...
Tool_Execution (to chat_manager):

***** Response from calling tool (call_qrs5ysx89rQqMFtVuqMUb9O0) *****
Payment processed successfully
**********************************************************************

--------------------------------------------------------------------------------

Next speaker: PaymentProcessor

PaymentProcessor (to chat_manager):

Your refund for order #12345 has been processed successfully.
You should see the amount credited back to your account shortly.
If you have any further questions or need assistance, feel free to reach out.
Thank you for your patience!

--------------------------------------------------------------------------------

Next speaker: SatisfactionSurveyor

SatisfactionSurveyor (to chat_manager):

Thank you for your patience during the refund process!
We hope you are satisfied with your experience.
Could you please rate your satisfaction with the refund process from 1 to 5,
where 1 is very dissatisfied and 5 is very satisfied?
Your feedback is valuable to us!

--------------------------------------------------------------------------------
Context Variables:
{
"customer_verified": true,
"refund_approved": true,
"payment_processed": true,
"passport_number": "AUS923828C"
}

Notes

  • Behind-the-scenes, swarm agents are supported by a tool execution agent, that executes tools on their behalf. Hence, the appearance of Tool Execution in the output.
  • Currently only swarm agents can be added to a swarm. This is to maintain their ability to manage context variables, auto-execute functions, and support hand offs. Eventually, we may allow ConversableAgent to have the same capability and make "SwarmAgent" a simpler subclass with certain defaults changed (like AssistantAgent and UserProxyAgent).
  • Would you like to enhance the swarm feature or have found a bug? Please let us know by creating an issue on the AG2 GitHub.

For Further Reading