Menu

Agent System

Relevant source files

Purpose and Scope

The Agent System provides the core abstraction for building intelligent LLM-powered applications within AStack. Agents orchestrate interactions between language models (via ModelProvider), external tools, and conversation memory to enable autonomous task execution with reasoning capabilities.

This document provides an architectural overview of the Agent system. For detailed implementation information, refer to:

For the model provider abstraction that agents depend on, see Model Provider Interface.


Overview

What is an Agent?

An Agent is an AStack Component that wraps a language model with additional capabilities:

  1. Tool Execution - Ability to call external functions and APIs
  2. Multi-Turn Reasoning - Iterative problem-solving with multiple model calls
  3. Context Management - Maintains conversation history across interactions
  4. Autonomous Decision Making - Determines when to use tools vs. respond directly

Agents implement the ReAct (Reasoning + Acting) pattern, where the model alternates between reasoning about the task and taking actions through tools until it reaches a conclusion.

Key Components

ComponentPurposePackage
AgentBase agent implementation with synchronous execution@astack-tech/components
StreamingAgentAgent variant with real-time progress updates@astack-tech/components
ModelProviderInterface for LLM integration@astack-tech/integrations
MemoryInterface for conversation context storage@astack-tech/components
ToolInterface for external capabilities@astack-tech/tools

Architecture

Agent System Component Hierarchy

The following diagram shows how the Agent system integrates with AStack's core architecture and relates to other framework components.

Sources:

Core Interfaces

The Agent system is built around several key TypeScript interfaces that define contracts between components:

Message Interface

Defines the format for all communication within the agent system. Supports multiple roles (system, user, assistant, tool) and includes fields for tool interactions.

Sources: packages/components/src/agents/index.ts6-38

ModelProvider Interface

Abstracts language model interactions. Agents call chatCompletion() to get responses from the LLM.

The temporaryTools option allows passing tool definitions on a per-request basis. See Model Provider Interface for details.

Sources: packages/components/src/agents/index.ts162-184

Tool Interface

Minimal interface for external capabilities. Tools must provide identification, description, and parameter schema.

Tools must implement either execute(args) or invoke(args) methods. See Tool Integration for details.

Sources: packages/components/src/agents/index.ts43-58

Memory Interface

Manages conversation history and context. The default implementation (DefaultMemory) stores all messages in memory.

See Memory Management for implementation details and custom memory patterns.

Sources: packages/components/src/agents/index.ts63-127

AgentConfig Interface

Configuration object passed to Agent constructor:

FieldTypeDefaultDescription
modelModelProviderrequiredLLM provider instance
toolsTool[][]Available tools for agent
systemPromptstring"你是一个智能助手"System message
memoryMemoryDefaultMemoryMemory implementation
maxIterationsnumber10Maximum tool execution rounds
verbosebooleanfalseEnable debug logging
supportsToolCallsbooleantrueEnable tool calling

Sources: packages/components/src/agents/index.ts233-268

AgentInput and AgentOutput

AgentInput - Passed to agent.run():

AgentOutput - Returned from agent.run():

Sources: packages/components/src/agents/index.ts189-228


Agent Execution Model

High-Level Execution Flow

Agents implement a multi-turn execution loop that allows the language model to iteratively use tools and refine its response. The flow is managed by the Agent.run() method and delegated to the internal executeWithTools() method.

High-Level Flow Diagram:

Sources:

ReAct Pattern Implementation

The Agent implements the ReAct (Reasoning + Acting) pattern through an iterative loop. In each iteration:

  1. Reasoning - Model receives conversation history and decides to call tools or respond
  2. Acting - If tools are called, they are executed and results added to history
  3. Repeat - Process continues until model produces final response or max iterations reached

This enables complex multi-step task execution where the agent can gather information incrementally.

Example Multi-Turn Execution:

For detailed implementation of the execution loop, including error handling and tool invocation logic, see Base Agent.

Sources:


Agent Implementations

AStack provides two agent implementations: the standard Agent class for synchronous execution, and StreamingAgent for real-time progress updates.

Agent Class

The base Agent class in packages/components/src/agents/index.ts273-638 provides synchronous execution with complete results returned after all iterations complete.

Core Methods:

MethodSignatureDescription
constructor()(config: AgentConfig)Initialize agent with model, tools, memory
run()(input: string | AgentInput): Promise<AgentOutput>Execute agent and return final result
reset()(): voidClear memory and reset state
_transform()($i, $o): voidComponent integration for pipelines

Usage Example:

See Base Agent for detailed implementation information.

Sources:

StreamingAgent Class

The StreamingAgent class in packages/components/src/agents/StreamingAgent.ts88-468 wraps the base Agent to provide real-time execution updates through chunk emission.

Chunk Types:

The runStream() method yields StreamingChunk objects with different types:

Chunk TypeDescriptionFields
iteration_startNew iteration beginsiteration
model_thinkingModel is processing-
assistant_messageModel response receivedcontent, toolCalls
tool_startTool execution beginstoolName
tool_resultTool execution completetoolName, result
completedAgent finishedfinalMessage, history, allToolCalls
errorError occurrederror

Usage Example:

This enables building responsive UIs that show progress in real-time. See Streaming Agent for details.

Sources:


Agent Configuration

Constructor Configuration

Agents are configured via the AgentConfig object passed to the constructor. The configuration determines the agent's capabilities and behavior.

Configuration Flow:

Sources:

System Prompt Construction

The buildSystemPrompt() method at packages/components/src/agents/index.ts357-390 generates a comprehensive system prompt by combining the base prompt with tool descriptions:

  1. Start with config.systemPrompt
  2. If tools are provided, append "\n\n可用工具:\n"
  3. For each tool, add "${index + 1}. ${tool.name} - ${tool.description}\n"
  4. For each parameter in tool.parameters.properties, add " - ${name}: ${description}\n"

This creates a system message that informs the model about available tools and their usage. The resulting system message is added to memory during initialization.

Sources:

Initialization Lifecycle

Initialization Sequence:

Sources:

Reset Behavior

The reset() method at packages/components/src/agents/index.ts634-637 clears agent state:

  1. Resets currentIteration to 0
  2. Calls initializeMemory() which clears memory and rebuilds system prompt

This allows reusing an agent instance for new conversations.

Sources:



Usage Patterns

Standalone Execution

Agents can be executed independently without a pipeline by calling the run() method directly:

This is the most common usage pattern for agents. See examples/agent-with-tools/index.ts116-156 for a complete example.

Sources:

Pipeline Integration

Agents extend the Component base class and can be integrated into pipelines like any other component. The agent's _transform() method at packages/components/src/agents/index.ts593-627 handles port-based communication:

Port Behavior:

  • Input Port 'in' - Accepts string | AgentInput
  • Output Port 'out' - Emits AgentOutput after execution completes

Sources:

Streaming in Production

The StreamingAgent is commonly used in web applications to provide real-time feedback. Example from the serve-astack backend:

See Serve-AStack Chat Application for the complete full-stack implementation.

Sources:


Error Handling and Resilience

Tool Execution Error Handling

The Agent's executeWithTools() method at packages/components/src/agents/index.ts438-514 implements robust error handling for tool execution:

Error Types and Responses:

Error ScenarioDetection PointHandling Behavior
Tool not foundtools.find() returns undefinedAdd error message to toolResultsText, continue processing other tools
Argument parsing failedJSON.parse() throws exceptionAdd parse error to toolResultsText, continue loop
No executable methodNo execute or invoke propertyAdd method error to toolResultsText, continue loop
Tool execution throwstool.execute() or tool.invoke() throwsCatch error, add to toolResultsText, record in toolCalls[] with error result

Error Flow:

All errors are:

  1. Logged to console when verbose: true
  2. Sent to the model in the next iteration via toolResultsText
  3. Recorded in the toolCalls array in AgentOutput
  4. Do not halt execution - processing continues with remaining tools

Sources:

Maximum Iteration Protection

The maxIterations configuration parameter prevents infinite loops. At packages/components/src/agents/index.ts411-534 the execution loop:

  1. Increments iteration counter at the start of each loop
  2. Checks iteration < this.maxIterations before continuing
  3. If limit is reached while hasMoreToolsToCall is true:
    • Logs warning: "达到最大迭代次数 ${this.maxIterations},强制终止迭代"
    • Breaks the loop
    • Returns the last available result

This prevents runaway execution when the model repeatedly requests tools without providing a final answer.

Sources:

Pipeline Error Handling

When used in a pipeline, the agent's _transform() method at packages/components/src/agents/index.ts593-627 wraps execution in a try-catch block:

This ensures that pipeline execution continues even if the agent encounters an unrecoverable error.

Sources:


Integration with Model Providers

Model Selection and Configuration

Agents work with any class that implements the ModelProvider interface. The most common pattern:

Sources:

Tool Passing to Models

Agents pass tools to models using the temporaryTools option:

The model provider converts these to its API format. For Deepseek:

Sources:


Debugging and Observability

Verbose Logging

When verbose: true, the Agent logs detailed execution information:

[Agent Debug] === 迭代 1/10 === [Agent Debug] 发送消息给模型: [...] [Agent Debug] 收到模型回复: {...} [Agent Debug] 工具调用数量: 2 [Agent Debug] 工具 readFile 的参数: {...} [Agent Debug] 使用 execute 方法执行工具 readFile [Agent Debug] 工具 readFile 执行结果: "..." 

This provides insight into:

  • Current iteration number
  • Messages sent to model
  • Model responses
  • Tool execution details
  • Results at each step

Sources:

Output Structure

The AgentOutput provides complete execution history:

This enables:

  • Replaying conversations
  • Analyzing tool usage
  • Debugging multi-turn interactions
  • Building conversation UIs

Sources: