# Embabel Execution Modes: Open, Focused, and Closed Explained

> Understand Embabel execution modes: Open, Focused, and Closed. Learn how agents dynamically select goals or deterministically run specific agents for efficient task completion.

- Repository: [Embabel/embabel-agent](https://github.com/embabel/embabel-agent)
- Tags: deep-dive
- Published: 2026-08-10

---

**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/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/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/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

```kotlin
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

```kotlin
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

```kotlin
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 `chooseAndAccomplishGoal` to dynamically select goals and potentially compose solutions from multiple agents, with optional `FocusedToolCallControl` for tool constraints.
- **Closed execution** uses `chooseAndRunAgent` to 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 `FocusedToolCallControl` prompt 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.