Cog (Cognitive Architecture) Guide
June 13, 2025 · View on GitHub
Cogs in AgentForge are declarative YAML-driven orchestrators that define multi-agent workflows, memory nodes, and branching logic—enabling complex, loopable, and branching AI pipelines without writing custom Python code.
1. What Is a Cog?
A Cog is:
- A YAML file under
.agentforge/cogs/that declares agents, memory nodes, and flow logic. - A fully declarative automation: no custom Python is required to configure agent interactions.
- An engine for chaining agents, injecting persona/memory context, and handling routing based on agent outputs.
When you run a Cog, AgentForge:
- Loads and validates the YAML config.
- Initializes shared memory and persona context.
- Executes agents in the order defined by
flow.startandtransitions. - Merges each agent's output into the internal state.
- Routes to next agents via direct or decision-based transitions.
- Terminates when an
end: truenode is reached.
2. YAML Schema & Configuration
cog:
name: "ExampleFlow" # Identifier for this Cog
description: "A sample decision workflow."
agents: # Declare agent nodes
- id: analyze
template_file: analyze_agent # Required: at least one of template_file or type
- id: decide
template_file: decide_agent
- id: respond
template_file: response_agent
memory: # (Optional) shared memory nodes
- id: general_memory
type: agentforge.storage.memory.Memory # Optional: defaults to base Memory
collection_id: history
query_before: [analyze]
update_after: [respond]
query_keys: [user_input]
update_keys: [respond]
flow: # Define execution order
start: "analyze"
transitions:
analyze: decide
decide:
choice:
"approve": respond
"reject": analyze
fallback: respond
max_visits: 5
respond:
end: true
Top-Level Keys
cog.name,cog.description: Metadata.agents: List of agent definitions:id: Unique node key (required).template_file: Prompt YAML name (required iftypenot set).type: Full Python path to Agent subclass (required iftemplate_filenot set).
memory: List of memory nodes (optional):id: Key for memory instance (required).type: Memory class to instantiate (optional; defaults to base Memory).collection_id: Optional override for storage partition (defaults to node'sidfor base Memory; subclasses may override).query_before/update_after: List or string of agent IDs (always treated as lists internally).query_keys/update_keys: Keys to extract from context/state for querying/updating memory.
flow:start:agents.idto run first.transitions: Mapping from eachidto next steps:- Simple:
agentA: agentB - Decision: Use an output field (e.g.,
choice) to branch:agentA: choice: "approve": agentX "reject": agentY fallback: agentZ - Loop Guard:
max_visitsprevents infinite cycling. - Terminate:
agent_id: end: truemarks a terminal node.
- Simple:
3. Decision-Based Transitions
Decision-based transitions route flow based on values in the agent's output.
- Decision Key: The field name in the agent's output that determines the next branch.
- Value Normalization: Matching is case-insensitive and normalizes booleans/strings. Always quote branch labels in YAML to avoid type conversion issues.
- Fallback: If a decision value doesn't match, or the key is missing, or
max_visitsis exceeded, thefallbackbranch is used. If no fallback is defined, the flow terminates with an exception.
4. Memory Nodes & Chat History
Memory nodes declared under memory are shared across all agents in a Cog. Each node can:
- Specify when to query or update (before/after specific agents)
- Use
query_keysandupdate_keysto control what data is used - Use a custom
typefor specialized memory behavior
Collection Naming:
- For base Memory,
collection_iddefaults to the node'sidif not specified. - Some subclasses (e.g., PersonaMemory) may override this logic and append suffixes or use different naming.
Automatic Chat History Memory:
- Unless
chat_memory_enabled: falseis set at the top level, achat_historymemory node is automatically added for you. - Configure the recency slice with
chat_history_max_results(default: 20,0= no limit) and the semantic slice withchat_history_max_retrieval(default: 20,0= disable semantic retrieval). - Access chat history in prompts with
{_mem.chat_history.history}(recent turns) and{_mem.chat_history.relevant}(semantically relevant turns).
Note: You do not need to define a
chat_historymemory node yourself—this is handled automatically when chat memory is enabled.
5. Agent Execution & Context
- Initialization: Cog builds a
contextdict (external input) and astatedict (internal agent outputs). - Agent Run: For each node, the agent is called with the current context and state.
- Collect Output: Agent result is stored in
state[node_id]. - Memory Query/Update: Memory is queried before and updated after agents as configured.
- Routing: Next node is selected via
flow.transitions[node_id]. - Loop Control: If a node's
max_visitsis exceeded, thefallbackbranch is used. - Completion: When
end: trueis reached,cog.run()returns the final state or specified output.
How Agents Access Context, State, and Memory
When an agent runs, the Cog engine provides three key variables in the prompt template context:
_ctx: The current external context, such as user input and any runtime values passed tocog.run()._state: The internal state dictionary, containing outputs from all previously executed agents in the workflow._mem: The memory manager, where each memory node is accessible as an attribute. For example, if you have a memory node withid: persona_memory, you can access its properties in your prompt as{_mem.persona_memory.<property>}.
This allows agents to reference both the latest user input/context and the outputs of other agents. For example, in a prompt template:
prompts:
user:
context: |
## User Input
{_ctx.user_input}
analysis: |
## Previous Analysis
{_state.analysis}
persona_info: |
## Persona Info
{_mem.persona_memory._narrative}
{_ctx.user_input}: Accesses the current user input or context value.{_state.analysis}: Accesses the output of theanalysisagent node.{_mem.persona_memory._narrative}: Accesses the contents of the persona narrative built by thePersonaMemorymemory node.
6. Return Values
The Cog's run() method returns values based on the end keyword configuration:
- Default: Returns the internal state dictionary with all agent outputs.
end: true: Returns only the output of the last agent executed.end: "dot.notation.key": Returns a specific value from the state using dot notation.
Example:
transitions:
final_agent:
end: true # Returns only final_agent's output
Or using a specific key:
transitions:
final_agent:
end: "final_agent.summary" # Returns only the summary key from final_agent's output
7. Error Handling
The Cog engine handles errors as follows:
- Invalid Transitions: If a transition points to a non-existent agent, an exception is raised.
- Missing Decision Keys/No Matching Branch: If the decision key is missing or the value doesn't match, the
fallbackbranch is used. If no fallback is defined, the flow terminates with an exception. - Loop Prevention: When
max_visitsis exceeded, thefallbackbranch is used. If no fallback, the flow terminates with an exception.
8. Minimal Example
cog:
name: "SimpleAnalysis"
description: "Basic analysis flow"
agents:
- id: analyze
template_file: analyze_agent
flow:
start: analyze
transitions:
analyze:
end: true
9. Advanced Example with Branching
cog:
name: "AnalysisDecisionFlow"
description: "A multi-step workflow with decision branching"
agents:
- id: analyze
template_file: analyze_agent
- id: decide
template_file: decide_agent
- id: respond
template_file: response_agent
memory:
- id: general_memory
query_before: [analyze, respond]
update_after: [respond]
query_keys: [user_input]
update_keys: [user_input, respond]
flow:
start: analyze
transitions:
analyze: decide
decide:
choice:
"approve": respond
"reject": analyze
fallback: respond
max_visits: 3
respond:
end: true
10. Best Practices
- Prompt Engineering: Structure prompts with clear sections and use memory in context sections.
- Decision Branches: Always quote branch names in YAML, set reasonable
max_visits, and definefallbackpaths. - Memory Management: Use
query_beforeandupdate_afterto control memory usage, and be explicit aboutquery_keysandupdate_keys. Use{_mem.<node_id>.readable}in prompts for human-friendly formatting. - Chat History: Leverage the automatic
chat_historymemory node for conversation context unless explicitly disabled. - Testing: Use
cog.get_track_flow_trail()to inspect execution order and outputs.