引言

Agent的状态管理是系统设计中最容易被忽视却又最关键的环节。一个Agent在执行任务时,可能经历"理解意图→检索记忆→调用工具→评估结果→生成回复"等多个阶段,每个阶段都有不同的状态和转移条件。状态管理不当会导致上下文丢失、重复执行、死循环等严重问题。

2026年,随着Agent系统复杂度的指数级增长,系统化的状态管理架构已成为生产部署的必备条件。

Agent状态的三个层次

第一层:会话状态(Session State)

会话状态是最基础的状态层,管理单次用户交互的上下文:

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum

class SessionStatus(Enum):
    ACTIVE = "active"
    PAUSED = "paused"
    COMPLETED = "completed"
    FAILED = "failed"
    TIMEOUT = "timeout"

@dataclass
class SessionState:
    """会话状态——管理单次交互的完整生命周期"""
    session_id: str
    user_id: str
    status: SessionStatus
    created_at: datetime
    updated_at: datetime
    message_history: list = field(default_factory=list)
    active_tools: list = field(default_factory=list)
    pending_actions: list = field(default_factory=list)
    context_window: dict = field(default_factory=dict)
    metadata: dict = field(default_factory=dict)
    
    def add_message(self, role: str, content: str):
        self.message_history.append({
            "role": role,
            "content": content,
            "timestamp": datetime.now().isoformat()
        })
        self.updated_at = datetime.now()
    
    def is_expired(self, ttl_seconds: int = 3600) -> bool:
        elapsed = (datetime.now() - self.updated_at).total_seconds()
        return elapsed > ttl_seconds

第二层:工作流状态(Workflow State)

工作流状态管理Agent执行复杂多步骤任务时的进度:

from enum import Enum

class WorkflowStepStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    SUCCESS = "success"
    FAILED = "failed"
    SKIPPED = "skipped"
    RETRYING = "retrying"

@dataclass
class WorkflowStep:
    step_id: str
    step_name: str
    status: WorkflowStepStatus
    dependencies: list  # 前置步骤ID
    inputs: dict
    outputs: dict
    retry_count: int = 0
    max_retries: int = 3
    started_at: datetime = None
    completed_at: datetime = None

@dataclass
class WorkflowState:
    """工作流状态——管理多步骤任务的执行进度"""
    workflow_id: str
    session_id: str
    steps: dict  # step_id -> WorkflowStep
    current_step: str
    context: dict  # 跨步骤共享的上下文
    
    def get_ready_steps(self) -> list:
        """获取可执行的步骤(依赖已完成)"""
        ready = []
        for step_id, step in self.steps.items():
            if step.status != WorkflowStepStatus.PENDING:
                continue
            deps_satisfied = all(
                self.steps[dep].status == WorkflowStepStatus.SUCCESS
                for dep in step.dependencies
            )
            if deps_satisfied:
                ready.append(step)
        return ready
    
    def is_complete(self) -> bool:
        return all(
            s.status in [WorkflowStepStatus.SUCCESS, WorkflowStepStatus.SKIPPED]
            for s in self.steps.values()
        )

第三层:持久状态(Persistent State)

持久状态跨越会话边界,包括用户偏好、长期记忆和已学习的模式:

class PersistentStateManager:
    """持久状态管理器"""
    
    def __init__(self, redis_client, postgres_client):
        self.redis = redis_client  # 热数据缓存
        self.postgres = postgres_client  # 冷数据持久化
    
    async def save_user_state(self, user_id: str, state: dict):
        """保存用户持久状态"""
        # 写入PostgreSQL
        await self.postgres.execute(
            """INSERT INTO user_state (user_id, state, updated_at)
               VALUES ($1, $2, NOW())
               ON CONFLICT (user_id) 
               DO UPDATE SET state = $2, updated_at = NOW()""",
            user_id, json.dumps(state)
        )
        # 更新Redis缓存
        await self.redis.setex(
            f"user_state:{user_id}",
            3600,  # 1小时TTL
            json.dumps(state)
        )
    
    async def load_user_state(self, user_id: str) -> dict:
        """加载用户状态,优先从缓存读取"""
        # 先查缓存
        cached = await self.redis.get(f"user_state:{user_id}")
        if cached:
            return json.loads(cached)
        
        # 缓存未命中,查数据库
        row = await self.postgres.fetchrow(
            "SELECT state FROM user_state WHERE user_id = $1",
            user_id
        )
        if row:
            state = json.loads(row["state"])
            # 回填缓存
            await self.redis.setex(
                f"user_state:{user_id}", 3600, json.dumps(state)
            )
            return state
        return {}

有限状态机(FSM)设计

对于复杂的Agent行为,有限状态机是最有效的建模工具:

from transitions import Machine

class AgentStateMachine:
    """Agent行为状态机"""
    
    states = [
        'idle',           # 空闲,等待用户输入
        'understanding',  # 理解用户意图
        'planning',       # 制定执行计划
        'retrieving',     # 检索记忆和知识
        'executing',      # 执行工具调用
        'evaluating',     # 评估执行结果
        'generating',     # 生成响应
        'clarifying',     # 向用户澄清问题
        'error',          # 错误状态
        'timeout'         # 超时状态
    ]
    
    transitions = [
        # 触发事件          源状态            目标状态
        {'trigger': 'receive_input', 'source': 'idle', 'dest': 'understanding'},
        {'trigger': 'intent_clear', 'source': 'understanding', 'dest': 'planning'},
        {'trigger': 'need_clarification', 'source': 'understanding', 'dest': 'clarifying'},
        {'trigger': 'plan_ready', 'source': 'planning', 'dest': 'retrieving'},
        {'trigger': 'context_ready', 'source': 'retrieving', 'dest': 'executing'},
        {'trigger': 'tools_complete', 'source': 'executing', 'dest': 'evaluating'},
        {'trigger': 'retry_needed', 'source': 'evaluating', 'dest': 'executing'},
        {'trigger': 'result_good', 'source': 'evaluating', 'dest': 'generating'},
        {'trigger': 'response_sent', 'source': 'generating', 'dest': 'idle'},
        {'trigger': 'user_responded', 'source': 'clarifying', 'dest': 'understanding'},
        {'trigger': 'error_occurred', 'source': '*', 'dest': 'error'},
        {'trigger': 'timeout', 'source': '*', 'dest': 'timeout'},
        {'trigger': 'reset', 'source': ['error', 'timeout'], 'dest': 'idle'},
    ]
    
    def __init__(self, session_id: str):
        self.session_id = session_id
        self.machine = Machine(
            model=self,
            states=self.states,
            transitions=self.transitions,
            initial='idle'
        )
    
    def on_enter_understanding(self):
        """进入理解状态时的回调"""
        logger.info(f"[{self.session_id}] Entering understanding phase")
    
    def on_enter_executing(self):
        """进入执行状态时的回调"""
        logger.info(f"[{self.session_id}] Starting tool execution")
        # 启动超时计时器
        asyncio.create_task(self._execution_timeout())
    
    async def _execution_timeout(self):
        await asyncio.sleep(30)  # 30秒超时
        if self.state == 'executing':
            self.timeout()

状态转移图

                    ┌───────┐
          ┌────────▶│  idle  │◀──────────┐
                   └────┬───┘            
                         receive_input   reset
                                        
                   ┌────────────┐   ┌────┴─────┐
            user   understanding     error   
          responded└───┬─────┬──┘   └──────────┘
                            need    
                 intent     clarif.   error_occurred
                 clear                (from any state)
                         ┌──────┐    
                         clarif.   
                         └──────┘    
                                     
                  ┌─────────┐         
                  planning          
                  └────┬────┘         
                        plan_ready   
                                     
                  ┌──────────┐        
                  retrieving        
                  └────┬─────┘        
                        context_ready
                                     
             ┌──────────────────┐     
                 executing     │─────┘
             └────────┬─────────┘
                       tools_complete
                      
             ┌──────────────────┐
                evaluating     
             └──┬───────────┬───┘
           retry           result_good
          needed           
          └──────┤    ┌──────────┐
                     generating
                     └────┬─────┘
                          response_sent
                 └─────────┘

分布式状态同步

当Agent部署在多节点上时,状态同步成为关键挑战:

class DistributedStateSync:
    """基于Redis的分布式状态同步"""
    
    def __init__(self, redis_client):
        self.redis = redis_client
        self.lock_timeout = 30  # 锁超时秒数
    
    async def acquire_state_lock(
        self, 
        session_id: str, 
        node_id: str
    ) -> bool:
        """获取状态锁,防止并发修改"""
        lock_key = f"state_lock:{session_id}"
        
        # 使用SET NX实现原子性锁获取
        acquired = await self.redis.set(
            lock_key, 
            node_id, 
            nx=True,  # 只在key不存在时设置
            ex=self.lock_timeout
        )
        
        if acquired:
            logger.info(f"State lock acquired for {session_id} by {node_id}")
            return True
        
        # 检查是否是自己已持有的锁(可重入)
        current_holder = await self.redis.get(lock_key)
        if current_holder == node_id:
            await self.redis.expire(lock_key, self.lock_timeout)
            return True
        
        return False
    
    async def release_state_lock(self, session_id: str, node_id: str):
        """释放状态锁"""
        lock_key = f"state_lock:{session_id}"
        
        # 使用Lua脚本确保原子性释放
        lua_script = """
        if redis.call("get", KEYS[1]) == ARGV[1] then
            return redis.call("del", KEYS[1])
        else
            return 0
        end
        """
        await self.redis.eval(lua_script, 1, lock_key, node_id)
    
    async def update_state_atomic(
        self,
        session_id: str,
        update_fn: callable,
        node_id: str
    ):
        """原子性状态更新"""
        max_retries = 3
        for attempt in range(max_retries):
            if await self.acquire_state_lock(session_id, node_id):
                try:
                    # 读取当前状态
                    state = await self._load_state(session_id)
                    # 应用更新
                    new_state = update_fn(state)
                    # 持久化
                    await self._save_state(session_id, new_state)
                    return new_state
                finally:
                    await self.release_state_lock(session_id, node_id)
            else:
                await asyncio.sleep(0.1 * (attempt + 1))
        
        raise StateLockAcquisitionError(
            f"Failed to acquire lock for {session_id} after {max_retries} attempts"
        )

状态序列化与迁移

随着系统演进,状态结构可能需要变更。设计良好的状态管理系统应支持版本化迁移:

class StateMigrator:
    """状态版本迁移器"""
    
    MIGRATIONS = {
        (1, 2): "_migrate_v1_to_v2",
        (2, 3): "_migrate_v2_to_v3",
    }
    CURRENT_VERSION = 3
    
    async def migrate(self, state: dict) -> dict:
        """迁移状态到最新版本"""
        version = state.get("_version", 1)
        
        while version < self.CURRENT_VERSION:
            migration_fn = self.MIGRATIONS.get((version, version + 1))
            if not migration_fn:
                raise ValueError(f"No migration from v{version}")
            
            state = getattr(self, migration_fn)(state)
            version += 1
        
        state["_version"] = self.CURRENT_VERSION
        return state
    
    def _migrate_v1_to_v2(self, state: dict) -> dict:
        """v1 -> v2: 添加tool_results字段"""
        if "tool_results" not in state:
            state["tool_results"] = []
        return state
    
    def _migrate_v2_to_v3(self, state: dict) -> dict:
        """v2 -> v3: 重构消息历史格式"""
        old_history = state.get("message_history", [])
        new_history = [
            {
                "role": msg.get("role", "user"),
                "content": msg.get("content", ""),
                "timestamp": msg.get("ts", datetime.now().isoformat()),
                "metadata": msg.get("metadata", {})
            }
            for msg in old_history
        ]
        state["message_history"] = new_history
        return state

总结

Agent状态管理是系统稳定性的基石。三层状态架构(会话状态、工作流状态、持久状态)覆盖了从瞬时到持久的完整状态生命周期。有限状态机为Agent行为建模提供了清晰的框架,分布式锁确保了多节点环境下的状态一致性,而版本化迁移机制则为系统的长期演进提供了保障。

在生产实践中,状态管理的核心原则是:始终假设状态可能在任何时候丢失,设计快速恢复机制比防止丢失更重要

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。