Embabel Execution Modes: Open, Focused, and Closed Explained
Embabel agents run in either Open-Focused mode, which dynamically selects goals and composes multi-agent solutions with optional tool constraints via chooseAndAccomplishGoal, or Closed mode, which deterministically executes a specific agent via chooseAndRunAgent.
The embabel/embabel-agent repository provides distinct execution architectures that determine how user requests map to agent actions. Understanding these modes is essential for building applications that balance autonomous discovery against deterministic control.
Open-Focused Execution: Goal-Centric Intelligence
Open-Focused execution centers on goal resolution rather than direct agent invocation. When you call Autonomy.chooseAndAccomplishGoal, the platform analyzes the user input, identifies relevant goals from the provided AgentScope, and potentially constructs a composite agent that aggregates capabilities from multiple sources.
Dynamic Goal Selection and Multi-Agent Composition
In this mode, Embabel creates a GoalSeeker instance to rank available goals based on the user's intent. If the multiGoal parameter is enabled, the system may compose a temporary "goal-agent" that combines actions, conditions, and knowledge from several registered agents to satisfy complex, cross-domain requests. This composite agent is then optionally pruned to remove irrelevant actions before execution.
According to the source code in [Autonomy.kt](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/common/autonomy/Autonomy.kt), this process allows the system to discover the best goal(s) and bring in the most useful actions from any agent in the scope, rather than being restricted to a single agent's capabilities.
Focused Tool-Call Control
A specialized variation of Open-Focused execution incorporates Focused Tool-Call Control, which constrains the LLM to specific tools while maintaining the open, goal-driven flow. When you include a FocusedToolCallControl element in your prompt, you restrict which tool the model may invoke and how many times.
The [ToolCallControl.kt](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/src/main/kotlin/com/embabel/agent/prompt/element/ToolCallControl.kt) file defines this control mechanism, allowing you to specify parameters like toolName="search" and toolCalls=2 to limit the LLM to exactly two search invocations. This is particularly useful when you want the flexibility of goal-driven execution but need to constrain costs or prevent excessive API calls. The [ToolCallControlTest.kt](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/src/test/kotlin/com/embel/agent/prompt/element/ToolCallControlTest.kt) file demonstrates the expected behavior for these constraints.
Closed Execution: Direct Agent Determinism
Closed execution takes an agent-centric approach via Autonomy.chooseAndRunAgent. Instead of evaluating goals, the system ranks registered agents based on the provided intent string and selects the top-scoring candidate.
Once selected, Embabel creates an AgentProcess for that specific agent and runs it as-is. Actions and conditions are never combined with another agent's capabilities, and no dynamic composition occurs. The LLM may invoke any tool the chosen agent exposes, without the focused restrictions available in Open-Focused mode.
Use Closed execution when you know exactly which specialized agent should handle the request—such as a dedicated translation bot or a specific data processing pipeline—and require deterministic, predictable behavior without cross-agent side effects.
Comparing Execution Architectures
| Aspect | Open-Focused Execution | Closed Execution |
|---|---|---|
| Core entry point | Autonomy.chooseAndAccomplishGoal |
Autonomy.chooseAndRunAgent |
| Selection logic | Selects a goal from the AgentScope |
Selects an agent from registered agents |
| Agent composition | May combine actions from multiple agents | Uses a single agent as-is |
| Dynamic pruning | Prunes composite agents to relevant actions only | No composition or pruning performed |
| Tool constraints | Supports FocusedToolCallControl for limited tool access |
No tool-call restrictions injected |
| Ideal use case | Vague user intent spanning multiple domains | Deterministic, specialized agent invocation |
Implementation Examples
The following Kotlin examples demonstrate how to invoke each execution mode using the Embabel API.
Open-Focused Execution with Goal Selection
import com.embabel.agent.api.common.autonomy.Autonomy
import com.embabel.agent.api.common.scope.AgentScope
val autonomy: Autonomy = // ... initialize autonomy
val scope: AgentScope = // ... define agent scope
val result = autonomy.chooseAndAccomplishGoal(
goalChoiceApprover = MyGoalApprover(),
agentScope = scope,
bindings = mapOf("it" to UserInput("Find recent research on AI safety")),
multiGoal = true // Enable composition across multiple goals
)
Adding Focused Tool-Call Control
import com.embabel.agent.prompt.element.FocusedToolCallControl
import com.embabel.agent.prompt.Prompt
// Constrain the LLM to exactly 3 search tool calls
val control = FocusedToolCallControl(toolName = "search", toolCalls = 3)
val prompt = Prompt.builder()
.add(control) // Injected into the prompt context
.add(userMessage)
.build()
Closed Execution with Direct Agent Selection
import com.embabel.agent.api.common.autonomy.Autonomy
import com.embabel.agent.api.common.process.ProcessOptions
val autonomy: Autonomy = // ... initialize autonomy
val result = autonomy.chooseAndRunAgent(
intent = "Translate this paragraph to French",
processOptions = ProcessOptions()
)
Summary
- Open-Focused execution uses
chooseAndAccomplishGoalto dynamically select goals and potentially compose solutions from multiple agents, with optionalFocusedToolCallControlfor tool constraints. - Closed execution uses
chooseAndRunAgentto run a single, specific agent deterministically without cross-agent composition. - Open-Focused is ideal for exploratory, multi-domain tasks where the best agent combination isn't known in advance.
- Closed execution provides predictable, isolated behavior for well-defined, specialized agents.
- Tool-call restrictions are only available in Open-Focused mode via the
FocusedToolCallControlprompt element.
Frequently Asked Questions
What is the difference between Open and Focused execution modes?
Open-Focused execution is a unified mode where Embabel selects goals and may compose multi-agent solutions. "Focused" specifically refers to the optional addition of FocusedToolCallControl constraints within an Open-Focused run, limiting which tools the LLM may invoke and how frequently. Without this control, the execution remains "Open," allowing the LLM access to all available tools from the composed agents.
When should I use Closed execution instead of Open-Focused?
Use Closed execution when you require deterministic behavior from a known, specialized agent—such as a dedicated customer service bot or a specific translation engine. Use Open-Focused execution when the user's intent is ambiguous, spans multiple domains, or when you want Embabel to automatically discover and combine the best capabilities from across your agent ecosystem.
Can FocusedToolCallControl be used with Closed execution?
No. The FocusedToolCallControl element is designed for the goal-centric flow of Open-Focused execution. Closed execution runs agents exactly as defined in their source configuration, without injecting additional prompt controls that would modify tool access. If you need tool restrictions with Closed execution, you must implement them within the agent's own prompt construction logic.
How does Embabel handle multiple agents in Open-Focused mode?
When multiGoal is enabled in chooseAndAccomplishGoal, Embabel creates a composite agent that aggregates actions, conditions, and knowledge from all relevant agents in the provided AgentScope. This temporary agent is then pruned to remove actions that don't contribute to the selected goal(s), resulting in a tailored execution context that draws from multiple sources while maintaining focus on the specific objective.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →