mini007

CRAN status R badge metacran downloads metacran downloads

mini007 provides a lightweight and extensible framework for multi-agents orchestration processes capable of decomposing complex tasks and assigning them to specialized agents.

Each agent is an extension of an ellmer object. mini007 relies heavily on the excellent ellmer package but aims to make it easy to create a process where multiple specialized agents help each other sequentially in order to execute a task.

mini007 provides two types of agents:

Highlights

🧠 Memory and identity for each agent via uuid and message history.

βš™οΈ Built-in task decomposition and delegation via LLM.

πŸ”„ Agent-to-agent orchestration with result chaining.

🌐 Compatible with any chat model supported by ellmer.

πŸ§‘ Possibility to set a Human In The Loop (HITL) at various execution steps

You can install mini007 from CRAN with:

install.packages("mini007")
library(mini007)

Creating an Agent

An Agent is built upon an LLM object created by the ellmer package, in the following examples, we’ll work with the OpenAI models, however you can use any model/combination of models you want:

# no need to provide the system prompt, it will be set when creating the
# agent (see the 'instruction' parameter)

openai_4_1_mini <- ellmer::chat(
  name = "openai/gpt-4.1-mini",
  api_key = Sys.getenv("OPENAI_API_KEY"), 
  echo = "none"
)

After initializing the ellmer LLM object, creating the Agent is straightforward:

polar_bear_researcher <- Agent$new(
  name = "POLAR BEAR RESEARCHER",
  instruction = "You are an expert in polar bears, you task is to collect information about polar bears. Answer in 1 sentence max.",
  llm_object = openai_4_1_mini
)

Each created Agent has an agent_id (among other meta information):

polar_bear_researcher$agent_id
#> [1] "41c46a04-9ae3-4b37-b633-3aebc1dd0dbc"

At any time, you can tweak the llm_object:

polar_bear_researcher$llm_object
#> <Chat OpenAI/gpt-4.1-mini turns=1 tokens=0/0 $0.00>
#> ── system [0] ──────────────────────────────────────────────────────────────────
#> You are an expert in polar bears, you task is to collect information about polar bears. Answer in 1 sentence max.

An agent can provide the answer to a prompt using the invoke method:

polar_bear_researcher$invoke("Are polar bears dangerous for humans?")
#> [1] "Yes, polar bears are dangerous to humans as they are powerful predators and may attack if threatened or hungry."

You can also retrieve a list that displays the history of the agent:

polar_bear_researcher$messages
#> [[1]]
#> [[1]]$role
#> [1] "system"
#> 
#> [[1]]$content
#> [1] "You are an expert in polar bears, you task is to collect information about polar bears. Answer in 1 sentence max."
#> 
#> 
#> [[2]]
#> [[2]]$role
#> [1] "user"
#> 
#> [[2]]$content
#> [1] "Are polar bears dangerous for humans?"
#> 
#> 
#> [[3]]
#> [[3]]$role
#> [1] "assistant"
#> 
#> [[3]]$content
#> [1] "Yes, polar bears are dangerous to humans as they are powerful predators and may attack if threatened or hungry."

Or the ellmer way:

polar_bear_researcher$llm_object
#> <Chat OpenAI/gpt-4.1-mini turns=3 tokens=43/21 $0.00>
#> ── system [0] ──────────────────────────────────────────────────────────────────
#> You are an expert in polar bears, you task is to collect information about polar bears. Answer in 1 sentence max.
#> ── user [43] ───────────────────────────────────────────────────────────────────
#> Are polar bears dangerous for humans?
#> ── assistant [21] ──────────────────────────────────────────────────────────────
#> Yes, polar bears are dangerous to humans as they are powerful predators and may attack if threatened or hungry.

Managing Agent Conversation History

Only in the development version at the moment

The clear_and_summarise_messages method allows you to compress an agent’s conversation history into a concise summary and clear the message history while preserving context. This is useful for maintaining memory efficiency while keeping important conversation context.

# After several interactions, summarise and clear the conversation history
polar_bear_researcher$clear_and_summarise_messages()
#> βœ” Conversation history summarised and appended to system prompt.
#> β„Ή Summary: The user asked if polar bears are dangerous to humans, and the expert confirmed that polar bears are...
polar_bear_researcher$messages
#> [[1]]
#> [[1]]$role
#> [1] "system"
#> 
#> [[1]]$content
#> [1] "You are an expert in polar bears, you task is to collect information about polar bears. Answer in 1 sentence max. \n\n--- Conversation Summary ---\n The user asked if polar bears are dangerous to humans, and the expert confirmed that polar bears are indeed dangerous as powerful predators who may attack when threatened or hungry."

This method summarises all previous conversations into a paragraph and appends it to the system prompt, then clears the conversation history. The agent retains the context but with reduced memory usage.

Budget and cost control

Only in the development version at the moment

You can limit how much an Agent is allowed to spend and decide what should happen as the budget is approached or exceeded. Use set_budget() to define the maximum spend (in USD), and set_budget_policy() to control warnings and over-budget behavior.

# An API KEY is required to invoke the Agent
openai_4_1_mini <- ellmer::chat(
  name = "openai/gpt-4.1-mini",
  api_key = Sys.getenv("OPENAI_API_KEY"),
  echo = "none"
)

agent <- Agent$new(
  name = "cost_conscious_assistant",
  instruction = "Answer succinctly.",
  llm_object = openai_4_1_mini
)

# Set a 5 USD budget
agent$set_budget(5)

# Warn at 90% of the budget and ask what to do if exceeded
agent$set_budget_policy(on_exceed = "ask", warn_at = 0.9)

# Normal usage
agent$invoke("Give me a one-sentence fun fact about Algeria.")

The current policy is echoed when setting the budget. You can update the policy at any time before or during an interaction lifecycle to adapt to your workflow’s tolerance for cost overruns.

Generate and execute R code from natural language

Only in the development version at the moment

generate_execute_r_code() lets an Agent translate a natural-language task description into R code, optionally validate its syntax, and (optionally) execute it.

Safety notes: - Set validate = TRUE and review the printed code before execution. - Keep interactive = TRUE to require an explicit confirmation before running code.

openai_4_1_mini <- ellmer::chat(
  name = "openai/gpt-4.1-mini",
  api_key = Sys.getenv("OPENAI_API_KEY"),
  echo = "none"
)

r_assistant <- Agent$new(
  name = "R Code Assistant",
  instruction = "You are an expert R programmer.",
  llm_object = openai_4_1_mini
)

# Generate code to summarise the built-in mtcars data frame,
# validate it, then execute after interactive confirmation.
r_assistant$generate_execute_r_code(
  code_description = "Calculate the summary of the mtcars dataframe",
  validate = TRUE,
  execute = TRUE,
  interactive = TRUE, 
  env = globalenv()
)

Creating a multi-agents orchestraction

We can create as many Agents as we want, the LeadAgent will dispatch the instructions to the agents and provide with the final answer back. Let’s create three Agents, a researcher, a summarizer and a translator:


researcher <- Agent$new(
  name = "researcher",
  instruction = "You are a research assistant. Your job is to answer factual questions with detailed and accurate information. Do not answer with more than 2 lines",
  llm_object = openai_4_1_mini
)

summarizer <- Agent$new(
  name = "summarizer",
  instruction = "You are agent designed to summarise a give text into 3 distinct bullet points.",
  llm_object = openai_4_1_mini
)

translator <- Agent$new(
  name = "translator",
  instruction = "Your role is to translate a text from English to German",
  llm_object = openai_4_1_mini
)

Now, the most important part is to create a LeadAgent:

lead_agent <- LeadAgent$new(
  name = "Leader", 
  llm_object = openai_4_1_mini
)

Note that the LeadAgent cannot receive an instruction as it has already the necessary instructions.

Next, we need to assign the Agents to LeadAgent, we do it as follows:

lead_agent$register_agents(c(researcher, summarizer, translator))
#> βœ” Agent(s) successfully registered.
lead_agent$agents
#> [[1]]
#> <Agent>
#>   Public:
#>     add_message: function (role, content) 
#>     agent_id: 0c525d0a-370a-46cf-ac58-503920a2249f
#>     broadcast_history: list
#>     budget: NA
#>     clear_and_summarise_messages: function () 
#>     clone: function (deep = FALSE) 
#>     export_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     generate_r_code: function (code_description, validate = FALSE, execute = FALSE, 
#>     get_usage_stats: function () 
#>     initialize: function (name, instruction, llm_object, budget = NA) 
#>     instruction: You are a research assistant. Your job is to answer fact ...
#>     invoke: function (prompt) 
#>     keep_last_n_messages: function (n = 2) 
#>     llm_object: Chat, R6
#>     load_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     messages: active binding
#>     model_name: gpt-4.1-mini
#>     model_provider: OpenAI
#>     name: researcher
#>     reset_conversation_history: function () 
#>     set_budget: function (amount_in_usd) 
#>     update_instruction: function (new_instruction) 
#>   Private:
#>     ._messages: list
#>     .add_assistant_message: function (message, type = "assistant") 
#>     .add_message: function (message, type) 
#>     .add_user_message: function (message, type = "user") 
#>     .set_turns_from_messages: function () 
#> 
#> [[2]]
#> <Agent>
#>   Public:
#>     add_message: function (role, content) 
#>     agent_id: ded4342b-a4a5-46e4-9bc2-cea87455da5c
#>     broadcast_history: list
#>     budget: NA
#>     clear_and_summarise_messages: function () 
#>     clone: function (deep = FALSE) 
#>     export_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     generate_r_code: function (code_description, validate = FALSE, execute = FALSE, 
#>     get_usage_stats: function () 
#>     initialize: function (name, instruction, llm_object, budget = NA) 
#>     instruction: You are agent designed to summarise a give text into 3 d ...
#>     invoke: function (prompt) 
#>     keep_last_n_messages: function (n = 2) 
#>     llm_object: Chat, R6
#>     load_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     messages: active binding
#>     model_name: gpt-4.1-mini
#>     model_provider: OpenAI
#>     name: summarizer
#>     reset_conversation_history: function () 
#>     set_budget: function (amount_in_usd) 
#>     update_instruction: function (new_instruction) 
#>   Private:
#>     ._messages: list
#>     .add_assistant_message: function (message, type = "assistant") 
#>     .add_message: function (message, type) 
#>     .add_user_message: function (message, type = "user") 
#>     .set_turns_from_messages: function () 
#> 
#> [[3]]
#> <Agent>
#>   Public:
#>     add_message: function (role, content) 
#>     agent_id: 5fb56804-d728-49f8-9cc5-3901f99e5a87
#>     broadcast_history: list
#>     budget: NA
#>     clear_and_summarise_messages: function () 
#>     clone: function (deep = FALSE) 
#>     export_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     generate_r_code: function (code_description, validate = FALSE, execute = FALSE, 
#>     get_usage_stats: function () 
#>     initialize: function (name, instruction, llm_object, budget = NA) 
#>     instruction: Your role is to translate a text from English to German
#>     invoke: function (prompt) 
#>     keep_last_n_messages: function (n = 2) 
#>     llm_object: Chat, R6
#>     load_messages_history: function (file_path = paste0(getwd(), "/", paste0(self$name, 
#>     messages: active binding
#>     model_name: gpt-4.1-mini
#>     model_provider: OpenAI
#>     name: translator
#>     reset_conversation_history: function () 
#>     set_budget: function (amount_in_usd) 
#>     update_instruction: function (new_instruction) 
#>   Private:
#>     ._messages: list
#>     .add_assistant_message: function (message, type = "assistant") 
#>     .add_message: function (message, type) 
#>     .add_user_message: function (message, type = "user") 
#>     .set_turns_from_messages: function ()

Before executing your prompt, you can ask the LeadAgent to generate a plan so that you can see which Agent will be used for which prompt, you can do it as follows:

prompt_to_execute <- "Tell me about the economic situation in Algeria, summarize it in 3 bullet points, then translate it into German."

plan <- lead_agent$generate_plan(prompt_to_execute)
#> βœ” Plan successfully generated.
plan
#> [[1]]
#> [[1]]$agent_id
#> 0c525d0a-370a-46cf-ac58-503920a2249f
#> 
#> [[1]]$agent_name
#> [1] "researcher"
#> 
#> [[1]]$model_provider
#> [1] "OpenAI"
#> 
#> [[1]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[1]]$prompt
#> [1] "Research the current economic situation in Algeria, including key indicators such as GDP growth, unemployment rate, and main industries."
#> 
#> 
#> [[2]]
#> [[2]]$agent_id
#> ded4342b-a4a5-46e4-9bc2-cea87455da5c
#> 
#> [[2]]$agent_name
#> [1] "summarizer"
#> 
#> [[2]]$model_provider
#> [1] "OpenAI"
#> 
#> [[2]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[2]]$prompt
#> [1] "Summarize the researched information into 3 clear and concise bullet points."
#> 
#> 
#> [[3]]
#> [[3]]$agent_id
#> 5fb56804-d728-49f8-9cc5-3901f99e5a87
#> 
#> [[3]]$agent_name
#> [1] "translator"
#> 
#> [[3]]$model_provider
#> [1] "OpenAI"
#> 
#> [[3]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[3]]$prompt
#> [1] "Translate the 3 bullet points from English into German accurately."

Now, in order now to execute the workflow, we just need to call the invoke method which will behind the scene delegate the prompts to suitable Agents and retrieve back the final information:

response <- lead_agent$invoke("Tell me about the economic situation in Algeria, summarize it in 3 bullet points, then translate it into German.")
#> 
#> ── Using existing plan ──
#> 
response
#> [1] "- Das BIP-Wachstum Algeriens ist mit etwa 2-3 % Anfang 2024 moderat und wird hauptsΓ€chlich durch Kohlenwasserstoffe angetrieben.  \n- Die Wirtschaft ist stark abhΓ€ngig von Γ–l und Gas, die ΓΌber 90 % der ExporterlΓΆse ausmachen.  \n- Die Arbeitslosigkeit bleibt hoch, insbesondere bei Jugendlichen, mit Raten von etwa 12-14 %, in SchlΓΌsselbranchen wie Energie, Landwirtschaft, Bergbau und verarbeitendem Gewerbe."

If you want to inspect the multi-agents orchestration, you have access to the agents_interaction object:

lead_agent$agents_interaction
#> [[1]]
#> [[1]]$agent_id
#> 0c525d0a-370a-46cf-ac58-503920a2249f
#> 
#> [[1]]$agent_name
#> [1] "researcher"
#> 
#> [[1]]$model_provider
#> [1] "OpenAI"
#> 
#> [[1]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[1]]$prompt
#> [1] "Research the current economic situation in Algeria, including key indicators such as GDP growth, unemployment rate, and main industries."
#> 
#> [[1]]$response
#> [1] "As of early 2024, Algeria's GDP growth is modest, around 2-3%, with the economy reliant on hydrocarbons (oil and gas) contributing over 90% of export revenues; unemployment remains high at approximately 12-14%, especially among youth. Key industries include energy, agriculture, mining, and manufacturing sectors."
#> 
#> [[1]]$edited_by_hitl
#> [1] FALSE
#> 
#> 
#> [[2]]
#> [[2]]$agent_id
#> ded4342b-a4a5-46e4-9bc2-cea87455da5c
#> 
#> [[2]]$agent_name
#> [1] "summarizer"
#> 
#> [[2]]$model_provider
#> [1] "OpenAI"
#> 
#> [[2]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[2]]$prompt
#> [1] "Summarize the researched information into 3 clear and concise bullet points."
#> 
#> [[2]]$response
#> [1] "- Algeria's GDP growth is modest at around 2-3% as of early 2024, driven largely by hydrocarbons.\n- The economy is heavily dependent on oil and gas, which account for over 90% of export revenues.\n- Unemployment remains high, particularly among youth, with rates around 12-14%, amid key industries such as energy, agriculture, mining, and manufacturing."
#> 
#> [[2]]$edited_by_hitl
#> [1] FALSE
#> 
#> 
#> [[3]]
#> [[3]]$agent_id
#> 5fb56804-d728-49f8-9cc5-3901f99e5a87
#> 
#> [[3]]$agent_name
#> [1] "translator"
#> 
#> [[3]]$model_provider
#> [1] "OpenAI"
#> 
#> [[3]]$model_name
#> [1] "gpt-4.1-mini"
#> 
#> [[3]]$prompt
#> [1] "Translate the 3 bullet points from English into German accurately."
#> 
#> [[3]]$response
#> [1] "- Das BIP-Wachstum Algeriens ist mit etwa 2-3 % Anfang 2024 moderat und wird hauptsΓ€chlich durch Kohlenwasserstoffe angetrieben.  \n- Die Wirtschaft ist stark abhΓ€ngig von Γ–l und Gas, die ΓΌber 90 % der ExporterlΓΆse ausmachen.  \n- Die Arbeitslosigkeit bleibt hoch, insbesondere bei Jugendlichen, mit Raten von etwa 12-14 %, in SchlΓΌsselbranchen wie Energie, Landwirtschaft, Bergbau und verarbeitendem Gewerbe."
#> 
#> [[3]]$edited_by_hitl
#> [1] FALSE

The above example is extremely simple, the usefulness of mini007 would shine in more complex processes where a multi-agent sequential orchestration has a higher value added.

Broadcasting

If you want to compare several LLM models, the LeadAgent provides a broadcast method that allows you to send a prompt to several different agents and get the result for each agent back in order to make a comparison and potentially choose the best agent/model for the defined prompt:

Let’s go through an example:

openai_4_1 <- ellmer::chat(
  name = "openai/gpt-4.1",
  api_key = Sys.getenv("OPENAI_API_KEY"), 
  echo = "none"
)

openai_4_1_agent <- Agent$new(
  name = "openai_4_1_agent", 
  instruction = "You are an AI assistant. Answer in 1 sentence max.", 
  llm_object = openai_4_1
)

openai_4_1_nano <- ellmer::chat(
  name = "openai/gpt-4.1-nano",
  api_key = Sys.getenv("OPENAI_API_KEY"), 
  echo = "none"
)

openai_4_1_nano_agent <- Agent$new(
  name = "openai_4_1_nano_agent", 
  instruction = "You are an AI assistant. Answer in 1 sentence max.", 
  llm_object = openai_4_1_nano
)

lead_agent$clear_agents() # removing previous agents
lead_agent$register_agents(c(openai_4_1_agent, openai_4_1_nano_agent))
#> βœ” Agent(s) successfully registered.
lead_agent$broadcast(prompt = "If I were Algerian, which song would I like to sing when running under the rain? how about a flower?")
#> [[1]]
#> [[1]]$agent_id
#> [1] "189675a6-4302-4235-880e-12d02d73dd74"
#> 
#> [[1]]$agent_name
#> [1] "openai_4_1_agent"
#> 
#> [[1]]$model_provider
#> [1] "OpenAI"
#> 
#> [[1]]$model_name
#> [1] "gpt-4.1"
#> 
#> [[1]]$response
#> [1] "If you were Algerian, you might enjoy singing \"Ya Rayah\" while running in the rain, and if you were a flower, perhaps \"Fleur de Lys\" would suit your blooming spirit."
#> 
#> 
#> [[2]]
#> [[2]]$agent_id
#> [1] "41fd5742-255e-4050-a3e5-87c7e8570edf"
#> 
#> [[2]]$agent_name
#> [1] "openai_4_1_nano_agent"
#> 
#> [[2]]$model_provider
#> [1] "OpenAI"
#> 
#> [[2]]$model_name
#> [1] "gpt-4.1-nano"
#> 
#> [[2]]$response
#> [1] "You might enjoy singing \"Ya Rayah\" by Rachid Taha when running under the rain, and \"Ya Rayah\" metaphorically as a flower when appreciating its beauty."

You can also access the history of the broadcasting using the broadcast_history attribute:

lead_agent$broadcast_history
#> [[1]]
#> [[1]]$prompt
#> [1] "If I were Algerian, which song would I like to sing when running under the rain? how about a flower?"
#> 
#> [[1]]$responses
#> [[1]]$responses[[1]]
#> [[1]]$responses[[1]]$agent_id
#> [1] "189675a6-4302-4235-880e-12d02d73dd74"
#> 
#> [[1]]$responses[[1]]$agent_name
#> [1] "openai_4_1_agent"
#> 
#> [[1]]$responses[[1]]$model_provider
#> [1] "OpenAI"
#> 
#> [[1]]$responses[[1]]$model_name
#> [1] "gpt-4.1"
#> 
#> [[1]]$responses[[1]]$response
#> [1] "If you were Algerian, you might enjoy singing \"Ya Rayah\" while running in the rain, and if you were a flower, perhaps \"Fleur de Lys\" would suit your blooming spirit."
#> 
#> 
#> [[1]]$responses[[2]]
#> [[1]]$responses[[2]]$agent_id
#> [1] "41fd5742-255e-4050-a3e5-87c7e8570edf"
#> 
#> [[1]]$responses[[2]]$agent_name
#> [1] "openai_4_1_nano_agent"
#> 
#> [[1]]$responses[[2]]$model_provider
#> [1] "OpenAI"
#> 
#> [[1]]$responses[[2]]$model_name
#> [1] "gpt-4.1-nano"
#> 
#> [[1]]$responses[[2]]$response
#> [1] "You might enjoy singing \"Ya Rayah\" by Rachid Taha when running under the rain, and \"Ya Rayah\" metaphorically as a flower when appreciating its beauty."

Tool specification

As mentioned previously, an Agent is an extension of an ellmer object. As such, you can define a tool that will be used, the exact same way as in ellmer. Suppose, we want to get the weather in Algiers through a function (Tool). Let’s first create the Agents:

openai_llm_object <- ellmer::chat(
  name = "openai/gpt-4.1-mini",
  api_key = Sys.getenv("OPENAI_API_KEY"), 
  echo = "none"
)

assistant <- Agent$new(
  name = "assistant",
  instruction = "You are an AI assistant that answers question. Do not answer with more than 1 sentence.",
  llm_object = openai_llm_object
)

weather_assistant <- Agent$new(
  name = "weather_assistant",
  instruction = "You role is to provide weather assistance.",
  llm_object = openai_llm_object
)

Now, let’s define the tool that we’ll be using, using ellmer it’s quite straightforward:

get_weather_in_algiers <- ellmer::tool(
  function() {
    "35 degrees Celcius, it's sunny and there's no precipitation."
  },
  name = "get_weather_in_algiers",
  description = "Provide the current weather in Algiers, Algeria."
)

Our tool defined, the next step is to register it within the suitable Agent, in our case, the weather_assistant Agent:

weather_assistant$llm_object$register_tool(get_weather_in_algiers)

That’s it, now the last step is to create the LeadAgent, register the Agents that we need and call the invoke method:

lead_agent <- LeadAgent$new(
  name = "Leader", 
  llm_object = openai_llm_object
)

lead_agent$register_agents(c(assistant, weather_assistant))
#> βœ” Agent(s) successfully registered.

lead_agent$invoke(
  "Tell me about the economic situation in Algeria, then tell me how's the weather in Algiers?"
)
#> 
#> ── Generating new plan ──
#> 
#> βœ” Plan successfully generated.
#> [1] "The weather in Algiers is currently warm and sunny with a temperature of 35 degrees Celsius. There is no precipitation, making for clear and dry conditions."

Human In The Loop (HITL)

When executing an LLM workflow that relies on many steps, you can set Human In The Loop (HITL) trigger that will check the model’s response at a specific step. You can define a HITL trigger after defining a LeadAgent as follows:

lead_agent <- LeadAgent$new(
  name = "Leader", 
  llm_object = openai_llm_object
)

lead_agent$set_hitl(steps = 1)
#> βœ” HITL successfully set at step(s) 1.

lead_agent$hitl_steps
#> [1] 1

After setting the HITL to step 1, the workflow execution will pose and give the user 3 choices:

  1. Continue the execution of the workflow as it is;
  2. Change manually the answer of the specified step and continue the execution of the workflow;
  3. Stop the execution of the workflow (hard error);

Note that you can set a HITL at several steps, for example lead_agent$set_hitl(steps = c(1, 2)) will set the HITL at step 1 and step 2.

Judge as a decision process

Only in the development version at the moment

Sometimes you want to send a prompt to several agents and pick the best answer. In order to choose the best prompt, you can also rely on the Lead Agent which will act a dudge and pick for you the best answer. You can use the judge_and_choose_best_response method as follows:

openai_4_1 <- ellmer::chat(
  name = "openai/gpt-4.1",
  api_key = Sys.getenv("OPENAI_API_KEY"),
  echo = "none"
)

stylist_1 <- Agent$new(
  name = "stylist",
  instruction = "You are an AI assistant. Answer in 1 sentence max.",
  llm_object = openai_4_1
)

openai_4_1_nano <- ellmer::chat(
  name = "openai/gpt-4.1-nano",
  api_key = Sys.getenv("OPENAI_API_KEY"),
  echo = "none"
)

stylist_2 <- Agent$new(
  name = "stylist2",
  instruction = "You are an AI assistant. Answer in 1 sentence max.",
  llm_object = openai_4_1_nano
)

openai_4_1_mini <- ellmer::chat(
  name = "openai/gpt-4.1-mini",
  api_key = Sys.getenv("OPENAI_API_KEY"),
  echo = "none"
)

stylist_lead_agent <- LeadAgent$new(
  name = "Stylist Leader",
  llm_object = openai_4_1_mini
)

stylist_lead_agent$register_agents(c(stylist_1, stylist_2))
#> βœ” Agent(s) successfully registered.

best_answer <- stylist_lead_agent$judge_and_choose_best_response(
  "what's the best way to wear a blue kalvin klein shirt in winter with a pink pair of trousers?"
)

best_answer
#> $proposals
#> $proposals[[1]]
#> $proposals[[1]]$agent_id
#> [1] "7234ef30-7060-4b89-884c-5d123ca8e3ef"
#> 
#> $proposals[[1]]$agent_name
#> [1] "stylist"
#> 
#> $proposals[[1]]$response
#> [1] "Pair the blue Calvin Klein shirt and pink trousers with a neutral-colored (like grey, navy, or camel) wool coat, dark shoes, and a coordinating scarf for a stylish winter look."
#> 
#> 
#> $proposals[[2]]
#> $proposals[[2]]$agent_id
#> [1] "03e0dde5-43f3-451a-988e-c0b2d350519d"
#> 
#> $proposals[[2]]$agent_name
#> [1] "stylist2"
#> 
#> $proposals[[2]]$response
#> [1] "Pair the blue Calvin Klein shirt and pink trousers with a neutral-colored sweater or blazer and stylish footwear for a chic winter look."
#> 
#> 
#> 
#> $chosen_response
#> Pair the blue Calvin Klein shirt and pink trousers with a neutral-colored (like
#> grey, navy, or camel) wool coat, dark shoes, and a coordinating scarf for a 
#> stylish winter look.

Code of Conduct

Please note that the mini007 project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.