May 11, 2026 2 min read Hyr1sky

设计模式与 AI 时代下的范式转移

从工厂方法、策略模式与观察者模式出发,重新理解网关路由、上下文压缩、自我进化技能等 AI 原生架构模式。


引言

随着大模型及 Coding Agent 能力的日益增长,开发者最核心的能力正逐渐从底层的“功能实现”向高层次的“架构设计”转移,在这一趋势下,设计模式依然是一门必修课。纵观目前市场上的主流 Agent 框架(如 Claude Code, Hermes Agent, OpenClaw 等),无不在架构上进行了深度的创新:Gateway 路由分发、安全沙箱机制、多层记忆管理等,都是极其优秀的系统设计。

本文希望从传统的设计模式领域出发,重点回顾几个经典模式,探讨它们的核心思想,然后再迈步向 AI 时代的新架构方案。正如 Matt 所说:当下,软件工程基础比以往任何时候都更加重要。


经典设计模式

设计模式与其说是一种规范,不如说是思想层面的共识。

1. 工厂方法模式

对外仅暴露接口,调用方不需要了解类内的具体实现,直接使用即可。其余类通过继承的形式去重写父类的方法,从而达到创建不同对象的目的。

应用场景

  • 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
  • 如果你希望用户能扩展你软件库或框架的内部组件,可使用工厂方法。
  • 如果你希望复用现有对象来节省系统资源,而不是每次都重新创建对象,可使用工厂方法。

优缺点

  • 优点:避免创建者和具体产品之间的紧密耦合;符合单一职责原则,可以将产品创建代码集中在程序的单一位置;符合开闭原则,无需更改现有的客户端代码即可在程序中引入新的产品类型。
  • 缺点应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂。最好的情况是将该模式引入创建者类的现有层次结构中。

2. 策略模式

策略模式建议找出负责用许多不同方式完成特定任务的类,然后将其中的算法抽取到一组被称为策略的独立类中。名为上下文的原始类必须包含一个成员变量来存储对于每种策略的引用。上下文并不执行任务,而是将工作委派给已连接的策略对象。

class Man:
    height: float
    weight: float
 
# 策略1:按身高排序
men_sorted_by_height = sorted(men, key=lambda m: m.height)
# 策略2:按体重排序  
men_sorted_by_weight = sorted(men, key=lambda m: m.weight)

应用场景

  • 当你想使用对象中各种不同的算法变体,并希望能在运行时切换算法时,可使用策略模式。
  • 当你有许多仅在执行某些行为时略有不同的相似类时,可使用策略模式。
  • 如果算法在上下文的逻辑中不是特别重要,使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
  • 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时,可使用该模式。

优缺点

  • 优点:可以在运行时动态切换对象内的算法;将算法的实现和使用算法的代码隔离开;可以使用组合代替继承;符合开闭原则,无需对上下文修改就可以引入新的策略。
  • 缺点如果你的算法极少发生改变,那么没有任何理由引入新的类和接口,这只会让程序过于复杂。客户端必须知晓策略间的不同,以便选择合适的策略。此外,许多现代编程语言支持函数式特性,允许通过匿名函数实现不同版本的算法,无需借助额外的类来保持代码简洁。

3. 观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(Subject)。当主题对象的状态发生变化时,它会主动通知所有注册的观察者,使它们能够自动执行更新。这种模式在解耦系统组件、构建事件驱动架构时极为核心,通常也被称为“发布-订阅(Publish-Subscribe)”模式。

将核心数据/状态(发布者)与对该数据做出响应的周边逻辑(订阅者)彻底解耦。发布者不需要关心观察者是谁、具体做什么,只需维护一个订阅列表并按约定广播事件即可。

应用场景

  • 当一个对象状态的改变需要联动改变其他对象,或实际对象是事先未知的、动态变化的时,可使用观察者模式。
  • 当应用中的某些对象必须持续观察另一对象的状态,但仅在有限时间内或特定情况下需要维持这种联系时。

优缺点

  • 优点:符合开闭原则,无需修改发布者代码就能引入新的订阅者类;可以在运行时动态建立或取消对象之间的联系,极大提升了系统的灵活性。
  • 缺点如果依赖关系过于复杂,可能会导致级联更新甚至循环调用;订阅者的通知顺序通常是随机的,不能依赖特定的执行顺序。

核心 AI 应用架构模式

在 AI Native 应用开发中,系统状态、上下文流转和 Agent 协作成为了一等公民。当我们深入研读当今主流框架(如 Claude Code, Hermes Agent, OpenClaw 等)的源码时,会发现它们在底层架构上有着极强的共性与极高的工程审美。

1. 意图路由与多分支流转 (Gateway & Routing)

单一的 Prompt 无法应对复杂的工程任务。现代 Agent 框架(如 OpenClaw)通常在最前端设置一个轻量级的网关控制器。它利用一个小参数量但速度极快的分类模型分析用户意图,随后将任务分发给专精不同领域的底层子 Agent。这种设计彻底解耦了任务流,降低了系统延迟。

class IntentGateway:
    def route_request(self, user_query: str) -> BaseAgent:
        # 使用轻量级分类器进行意图识别
        intent = self.classifier.predict(f"Classify intent: {user_query}")
        
        if intent == 'system_control':
            # 分发给具备 Docker 沙箱和 Shell 权限的底层 Agent
            return OpenClawAgent(sandbox_backend='docker', permissions=['shell'])
        elif intent == 'coding':
            # 分发给专注代码上下文处理的 Agent
            return ClaudeCodingAgent(memory=WorkingMemory())
        
        return GenericChatAgent()

2. 异步生成器与上下文压缩管道 (Async Loop & Context Compaction)

在处理长时间、多步骤的任务时,上下文窗口极易爆炸。以 Claude Code 为代表的系统,其核心架构采用了优雅的异步生成器(AsyncGenerator)来维持 Agent 循环,并在每次模型调用前强制插入一条“压缩管道(Compaction Pipeline)”,对历史消息进行裁剪和折叠。

// Claude Code 风格的底层 Agent 循环架构
export async function* queryLoop(params: QueryParams): AsyncGenerator<StreamEvent | Message> {
  let context = await buildState(params);
  
  while (!isTerminal(context)) {
    // 每次调用前进行上下文压力管理(如微压缩、自动摘要折叠)
    context = await compactionPipeline.run(context);
    
    // 调用 LLM 决策
    const response = await llm.call(context);
    
    // 安全拦截与工具执行分离
    const toolResults = await sandbox.executeWithHooks(response.tools);
    yield { type: 'tool_result', data: toolResults };
  }
}

3. 自我进化与技能沉淀 (Self-Evolving Skills)

Hermes AgentGeneric Agent 引入了“闭环学习”的架构。Agent 不仅执行任务,还会将成功的任务轨迹(Task Trace)提取出来,沉淀为可持久化的 Markdown 技能文件或 Python 脚本,供未来调用。这种设计让 Agent 从“无状态调用”变成了“伴随项目共同成长的数字协作者”。

def crystallize_skill(task_trace: list, success: bool) -> None:
    if not success: 
        return
    # 将成功的完整执行路径通过大模型提取为规范化的技能文件
    skill_content = prompt_extractor.extract(task_trace)
    
    # 持久化存储,供 Agent 的 MCP 接口下次动态加载
    with open(f".skills/{task_trace.intent}.md", "w") as f:
        f.write(f"---\nname: {task_trace.intent}\ndescription: Auto-generated skill\n---\n")
        f.write(skill_content)

传统设计模式在 AI 架构中的映射

经典设计模式并没有在 AI 时代消亡,而是以一种“降维”或“变体”的形式,深深嵌入到了 Agent 的底层工程结构中。

1. 工厂方法模式 (Factory Method)

理论分析

在多智能体(Multi-Agent)系统中,硬编码每一个 Agent 实例会导致系统极度臃肿。工厂方法模式的核心思想在于“延迟实例化与解耦”。在 AI 架构中,工厂不再仅仅是生成普通的类对象,而是根据动态的上下文环境,组装具备特定系统 Prompt、可用工具集和安全权限的“数字员工”。

实例说明

假设你正在开发一个类似 OpenClaw 的本地任务系统。当系统接收到“帮我分析这份 CSV 财务数据”的指令时,AgentFactory 会在运行时动态读取配置,实例化一个 DataAnalystAgent。这个 Agent 在被工厂创建的瞬间,已经被自动挂载了 Python 代码解释器工具、开启了本地只读文件权限,并注入了数据分析视角的系统提示词。调用方(网关)无需关心这个 Agent 是如何组装的,只需下发任务即可。

2. 策略模式 (Strategy Pattern)

理论分析

策略模式主张将不同的算法变体抽取为独立类,并在运行时动态切换。这在当前大热的 RAG(检索增强生成)管道中是不可或缺的基石架构。由于用户问题的复杂性不可预测,单一的检索手段无法满足需求,将底层检索逻辑抽象为不同的策略,能极大提升系统的鲁棒性。

实例说明

在构建企业级知识库 Agent 时,我们可以定义一个统一的 RetrievalStrategy 接口。其下实现三种策略:VectorSearchStrategy(纯向量匹配)、GraphSearchStrategy(图谱逻辑推理检索)、HybridSearchStrategy(混合检索)。当 Agent 判断当前用户只是在查询一个具体术语(如“什么是路由模式”),上下文管理器会切换至向量策略以求极速响应;当用户抛出一个需要多跳推理的宏观问题时,系统则无缝切换至图谱检索策略。

3. 观察者模式 (Observer Pattern)

理论分析

观察者模式定义了一对多的依赖关系(发布-订阅机制)。在 AI 应用中,“流式响应(Streaming)”和“不可预测的工具调用”是常态。核心调度循环(发布者)只需要不断向外抛出事件(如 Token 生成、思考链产生、工具调用请求),而不用关心谁在处理这些事件。这为系统的可观测性和安全性打下了基础。

实例说明

以 Claude Code 的沙箱架构为例,底层的 Agent 在决定执行一段 Bash 脚本时,会抛出一个 ToolRequestEvent。此时,前端的 UI 组件(观察者 A)接收到事件,开始在终端渲染加载动画;同时,系统的 SafetyMiddleware(观察者 B)也订阅了该事件,它会立即拦截该脚本,进行黑名单正则匹配或交由另一个审核 LLM 评估危险系数。如果发现高危命令,安全组件可直接中断该事件流,从而保证系统的绝对安全。