Mix.install(
[
{:lux, "~> 0.4.0"}
{:kino, "~> 0.14.2"}
],
config: [
lux: [
open_ai_models: [
default: "gpt-4o-mini"
],
api_keys: [
openai: System.fetch_env!("LB_OPENAI_API_KEY")
]
]
]
)
This guide demonstrates how to create and coordinate multiple agents working together in Lux.
Multi-agent collaboration in Lux is built on several key components:
- Agent Hub: Central system for discovering and tracking agents
- Capabilities: Tags that describe what an agent can do
- Status Tracking: Monitoring agent availability and workload
- Message Passing: Communication between agents
Here's an example of creating two agents that work together:
defmodule MyApp.Agents.Researcher do
use Lux.Agent,
name: "Research Assistant",
description: "Specialized in research and analysis",
goal: "Find and analyze information accurately",
capabilities: [:research, :analysis],
llm_config: %{
model: "gpt-4o-mini",
max_tokens: 500,
messages: [
%{
role: "system",
content: """
You are a Research Assistant specialized in finding and analyzing information.
Work with other agents to provide comprehensive research results.
"""
}
]
}
end
defmodule MyApp.Agents.Writer do
use Lux.Agent,
name: "Content Writer",
description: "Specialized in content creation",
goal: "Create engaging content from research",
capabilities: [:writing, :editing],
llm_config: %{
model: "gpt-4o-mini",
max_tokens: 500,
messages: [
%{
role: "system",
content: """
You are a Content Writer specialized in creating engaging content.
Work with researchers to transform their findings into compelling articles.
"""
}
]
}
end
Let's start the agents.
alias MyApp.Agents.Researcher
alias MyApp.Agents.Writer
{:ok, researcher_pid} = Kino.start_child({Researcher, []})
{:ok, writer_pid} = Kino.start_child({Writer, []})
You can check agent's state with get_state/1
function.
researcher = Researcher.get_state(researcher_pid)
writer = Writer.get_state(writer_pid)
Start your own agent hub.
If you want to use default agent hub, you can get it with
Lux.AgentHub.get_default/0
function.
{:ok, hub} = Kino.start_child({Lux.AgentHub, [name: :my_hub]})
Register agents with their capabilities
:ok =
Lux.AgentHub.register(
hub,
researcher,
researcher_pid,
[:research, :analysis]
)
:ok =
Lux.AgentHub.register(
hub,
writer,
writer_pid,
[:writing, :editing]
)
You can find agents by their capabilities.
research_agents = Lux.AgentHub.find_by_capability(hub, :research)
writing_agents = Lux.AgentHub.find_by_capability(hub, :writing)
Or you can get specific agent info with id
{:ok, researcher_info} = Lux.AgentHub.get_agent_info(hub, researcher.id)
Here's an example of how to coordinate work between a researcher and writer:
frame = Kino.Frame.new() |> Kino.render()
# 1. Update researcher status to busy
:ok = Lux.AgentHub.update_status(hub, researcher.id, :busy)
# 2. Start with a research task
{:ok, research_response} =
Researcher.send_message(
researcher_pid,
"Research the impact of AI on healthcare"
)
# 3. Mark researcher as available again
:ok = Lux.AgentHub.update_status(hub, researcher.id, :available)
Kino.Frame.append(frame, research_response)
# 4. Update writer status to busy
:ok = Lux.AgentHub.update_status(hub, writer.id, :busy)
# 5. Send research to writer for content creation
{:ok, article} =
Writer.send_message(
writer_pid,
"""
Create an engaging blog post based on this research:
#{research_response}
"""
)
# 6. Mark writer as avaiable again
:ok = Lux.AgentHub.update_status(hub, writer.id, :available)
Kino.Frame.append(frame, article)
Kino.nothing()
-
Status Management
- Always update agent status when starting/finishing work
- Check agent availability before sending tasks
- Handle offline agents gracefully
-
Capability Design
- Use specific, descriptive capability names
- Avoid overlapping capabilities
- Document expected inputs/outputs for each capability
-
Error Handling
- Handle agent unavailability
- Implement retry mechanisms for failed communications
- Monitor agent health
Lux.AgentHub.find_by_capability(hub, :research)
Here's a complete example of a research and writing pipeline:
defmodule MyApp.Workflows.ContentCreation do
alias Lux.AgentHub
def create_article(topic) do
# Get Agent Hub's pid
hub = Process.whereis(:my_hub)
# Find available researcher
case AgentHub.find_by_capability(hub, :research) do
[%{agent: researcher, pid: researcher_pid, status: :available} | _] ->
# Update researcher status
:ok = AgentHub.update_status(hub, researcher.id, :busy)
# Get research
{:ok, research} = Researcher.send_message(
researcher_pid,
"Research #{topic} comprehensively"
)
# Mark researcher as available
:ok = AgentHub.update_status(hub, researcher.id, :available)
# Find available writer
case AgentHub.find_by_capability(hub, :writing) do
[%{pid: writer_pid} | _] ->
# Create content
{:ok, article} = Writer.send_message(
writer_pid,
"""
Create an engaging article based on this research:
#{research}
"""
)
{:ok, article}
[] ->
{:error, :no_writers_available}
end
[] ->
{:error, :no_researchers_available}
end
end
end
MyApp.Workflows.ContentCreation.create_article("""
AI & Blockchain
""")
As your system grows, consider:
- Implementing load balancing between similar agents
- Adding specialized agents for specific tasks
- Using agent pools for high-demand capabilities
Track agent collaboration using:
- Agent status history
- Task completion metrics
- Communication logs
- Implement authentication between agents
- Validate message contents
- Rate limit agent interactions
- Monitor resource usage
- Implement more sophisticated collaboration patterns
- Add error recovery mechanisms
- Create specialized agent teams
- Implement performance monitoring