Files
cleveragents-core/docs/adr/ADR-010-actor-and-agent-architecture.md
T
freemo c2db74ba81
CI / lint (push) Successful in 15s
CI / build (push) Successful in 16s
CI / quality (push) Successful in 20s
CI / security (push) Successful in 35s
CI / typecheck (push) Successful in 42s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m38s
CI / integration_tests (push) Successful in 3m11s
CI / docker (push) Successful in 39s
CI / coverage (push) Successful in 4m58s
CI / benchmark-publish (push) Successful in 17m32s
Docs: Restyled ADR pages
2026-03-10 12:38:35 -04:00

9.9 KiB

adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
adr_number title status_history tier authors superseded_by related_adrs acceptance
10 Actor and Agent Architecture
2026-02-16
Proposed
Jeffrey Phillips Freeman
2026-02-16
Accepted
Jeffrey Phillips Freeman
2
Jeffrey Phillips Freeman
null
number title relationship
2 Namespace System Actors and agents are identified via namespaced names
number title relationship
6 Plan Lifecycle Actors drive plan phase transitions and execute plan steps
number title relationship
11 Tool System Tools serve as atomic execution nodes within actor graphs
number title relationship
12 Skill System Skills provide the tool collections that actors are equipped with
number title relationship
22 LangChain/LangGraph Integration Actors are implemented as LangGraph StateGraph instances
number title relationship
30 Skill Abstraction Definition Skills are the unit of capability assignment to actors
number title relationship
31 Actor Abstraction Definition Formalizes the canonical definition of what an actor is
number title relationship
32 Jinja2 YAML Template Preprocessing Defines the two-phase Jinja2 + env var preprocessing pipeline for actor YAML files
number title relationship
33 Decision Recording Protocol Actors call `record_decision` tool during Strategize and Execute to record decisions in the tree
number title relationship
27 Language Server Protocol (LSP) Integration Actors acquire language intelligence through LSP servers bound via the `lsp` configuration field
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> Actor-as-graph with hierarchical composition gives us flexible orchestration without tight coupling

Context

CleverAgents must orchestrate multiple AI-driven roles — strategy planning, code execution, cost estimation, invariant reconciliation, code review, and more. Some of these roles are single LLM agents; others are complex multi-step workflows involving multiple LLMs, deterministic tool nodes, and sub-graphs. The system needs an abstraction that unifies all of these behind a common interface, supports hierarchical composition, and is defined declaratively via configuration rather than code.

Decision Drivers

  • Must orchestrate multiple AI-driven roles (strategy planning, code execution, cost estimation, invariant reconciliation, code review) under a single abstraction
  • Some roles are single LLM agents; others are complex multi-step workflows with multiple LLMs, deterministic tool nodes, and sub-graphs
  • Actors must be defined declaratively via YAML configuration, not code, to enable non-developer customization
  • Need hierarchical composition so complex behaviors are built from simple, reusable named components
  • Must support namespaced identification and resolution of actors across deployment boundaries
  • The "agent" concept (LLM with tools and reasoning) must be preserved as a specialization, not the only orchestration primitive

Decision

CleverAgents uses the actor as its fundamental orchestration abstraction. An actor generalizes "agent" into "anything conversational." Every custom actor is a LangGraph graph defined via YAML configuration — even a simple single-LLM actor is a graph with one node. Actors are namespaced, composable, and referenceable by name. An agent is a specialized actor with a conversational interface, tool-calling capability, and optionally memory and planning heuristics.

Design

Actor Definition

Actors are defined in YAML configuration files and managed via agents actor CLI commands. Key definition fields:

  • name: Namespaced identifier (e.g., local/code-reviewer).
  • provider and model: LLM provider and model for the actor's primary node.
  • system_prompt: Jinja2 template for the actor's system instructions. Supports {{ context.* }} variable expansion.
  • skill_access_policy: Controls which skills (and their tools) the actor can use.
  • graph_descriptor: Defines the actor's internal graph — nodes, edges, conditional routing.
  • memory_policy: Controls context retention between invocations.
  • context_view_policy: ACMS settings — preferred strategies, default breadth/depth, depth gradient, skeleton budget ratio, temporal scope, auto-refresh.
  • limits: Token limits, tool call limits per step, retry policies.
  • cost_policy: Budget constraints and cost tracking.
  • lsp: LSP server binding — explicit server names, language-based resolution, or auto-discovery from project resources. Provides language intelligence (diagnostics, type info, completions, references) to actor nodes.

Actor as Graph

Every actor is a LangGraph StateGraph. The graph contains:

  • Actor nodes: References to other actors by name, enabling hierarchical composition.
  • Tool nodes: Deterministic, non-LLM steps that either reference a named registered tool or define an anonymous inline tool.
  • Edges: Connections between nodes, including conditional edges for routing based on state.

Even a minimal single-LLM actor is expressed as a graph with one LLM node and tool edges. This uniformity means the system has exactly one execution model for all actors.

Actor Arguments

All actors can receive arguments when invoked. Arguments are injected into the actor's context and are usable in Jinja2 templates within system prompts and node configurations.

Actor Composition

Actors reference other actors by name. An actor graph node can point to another registered actor, enabling hierarchical composition:

  • A strategy actor might delegate to a specialized resource-analysis actor.
  • An execution actor might route to different implementation actors based on the programming language.
  • A review actor might compose multiple specialized checkers (security, style, correctness).

Load order matters — referenced actors must be registered before the referencing actor.

Actor vs. Agent

  • Agent: An actor that is specifically an LLM with tools and reasoning behaviors. Has a conversational interface and tool-calling capability. May have memory, planning heuristics, and a role identity.
  • Actor: May be an agent, or a composite workflow, a multi-step graph, a wrapper around a third-party system, or any combination.

Every agent is an actor. Not every actor is an agent.

Actor Roles in Plan Lifecycle

Role Phase Description
Strategy actor Strategize Planner/architect. Analyzes context, produces decision tree. Required.
Execution actor Execute Builder/implementer. Executes strategy, invokes tools. Required.
Estimation actor Pre-execute Cost/risk estimator. Optional.
Invariant actor Strategize entry Reconciles invariant conflicts across scopes. Optional (fallback chain: plan → action → project → global config).

Agent Behavior Configuration

Agent behavior is configurable without code changes: prompt templates, tool sets, safety constraints, style constraints (verbosity, code style), and reliability controls (self-checks, validations).

Constraints

  • Every custom actor must be defined as a LangGraph graph in YAML. There is no imperative actor definition API.
  • Actor names follow the namespace system ([[server:]namespace/]name).
  • Actor references in graph nodes must point to registered actors. Forward references are not resolved — load order matters.
  • Built-in provider namespaces (openai/, anthropic/, etc.) are reserved for built-in LLM actors and cannot be used for custom actor names.
  • An action must specify at least two actors: strategy_actor and execution_actor. Estimation and invariant actors are optional.

Consequences

Positive

  • A single abstraction (actor-as-graph) handles everything from simple single-LLM agents to complex multi-step workflows.
  • YAML-based definition enables non-developers to create and modify actors without writing code.
  • Hierarchical composition enables building complex behaviors from simple, reusable components.
  • The actor/agent distinction preserves the familiar "agent" concept while enabling non-agent automation.

Negative

  • Expressing all actors as graphs adds complexity for simple single-LLM use cases.
  • YAML graph definitions can become difficult to read and maintain for complex multi-node actors with many conditional edges.
  • Load-order dependency for actor references complicates registration and updates.

Risks

  • Circular actor references (A references B which references A) must be detected and rejected.
  • Deep actor composition hierarchies may have unpredictable latency and cost characteristics.
  • The YAML graph DSL may prove insufficient for complex orchestration patterns, requiring escape hatches to code.

Alternatives Considered

Separate abstractions for agents and workflows — Would require two execution engines, two configuration formats, and two sets of management commands. The actor-as-graph approach provides a single unified model.

Code-defined actors (Python classes) — More flexible but prevents non-developer customization. YAML definitions are chosen to align with the declarative configuration philosophy of the rest of the system.

Compliance

  • Graph validation: Actor registration validates that the graph is well-formed — no dangling references, no circular dependencies, all required nodes present.
  • Schema validation: Pydantic models validate actor YAML configuration against the expected schema.
  • Composition tests: Integration tests verify that hierarchically composed actors correctly delegate to sub-actors and aggregate results.
  • Role tests: BDD scenarios verify that strategy, execution, estimation, and invariant actors fulfill their roles correctly within the plan lifecycle.
  • Code review: New actor definitions are reviewed for correct graph structure, appropriate skill access policies, and reasonable limit configurations.