04 Python常见的编程模式和架构方法
洋葱模型和面向切面(AOP)
在 LangChain 的 Agent 系统和 FastAPI 的 Web 系统中,洋葱模型 (Onion Model) 和 面向切面编程 (AOP) 是实现功能解耦的核心架构模式。
1. 核心概念:洋葱模型与 AOP
洋葱模型:将请求看作一颗洋葱,每一层中间件包裹着核心逻辑。请求进入时由外向内层层穿透,响应返回时由内向外层层回调。这种结构决定了执行顺序。
面向切面编程 (AOP):将非业务逻辑(如权限检查、监控、重试)从业务代码中分离,作为“切面”横向植入系统。它解决了代码复用问题。
2. FastAPI 中间件:请求/响应层面的“环”
FastAPI 基于 Starlette,其中间件工作在 HTTP 协议层:
场景:处理整个 HTTP 事务,如 CORS、全局异常捕获、请求计时。
实现技巧:在
dispatch方法中使用await call_next(request),这行代码就是“剥开下一层洋葱”的动作。
# FastAPI 中的洋葱环
async def dispatch(request: Request, call_next):
# 1. 业务逻辑前(外层)
start_time = time.time()
response = await call_next(request) # 2. 剥开洋葱,执行下一层
# 3. 业务逻辑后(返回路径)
process_time = time.time() - start_time
return response
3. LangChain 中间件:Agent 执行层面的“环”
LangChain 的 AgentMiddleware 工作在 Agent 的推理循环层,主要处理模型调用和工具调用。
场景:处理 Agent 决策逻辑,如模型切换、工具调用重试、上下文注入。
实现技巧:
wrap_model_call中的handler(request)是剥开下一层洋葱的关键,类似于call_next。
# LangChain 中的洋葱环
@wrap_model_call
def retry_middleware(request: ModelRequest, handler: Callable):
# 1. 进入切面(可以在此修改 request)
for attempt in range(3):
try:
return handler(request) # 2. 剥开洋葱
except Exception:
# 3. 拦截并处理异常
continue
4. 架构对比表
特性 |
FastAPI Middleware |
LangChain AgentMiddleware |
|---|---|---|
层级 |
HTTP 协议/路由层 |
Agent 推理/决策层 |
核心媒介 |
|
|
触发器 |
|
|
主要用途 |
全局横切逻辑 (CORS, 监控) |
业务行为横切 (模型切换, 提示词优化) |
5. 最佳实践技巧
分层思维 (Layering):
最外层:执行全局任务(如日志记录、性能指标、异常处理)。
中间层:处理业务切面(如权限鉴权、动态上下文注入)。
最内层:执行核心逻辑(真正的 LLM 调用或工具运行)。
单一职责原则:不要在一个中间件里既处理模型切换又处理日志,应分别编写
DynamicModelMiddleware和LoggingMiddleware,然后在 Agent 工厂中按序组合。状态传递:在 LangChain 中,利用中间件修改
request.state或返回Command,实现跨层的状态同步,这是 AOP 编程中传递元数据的关键手段。
结论: FastAPI 保护的是你的 Web 接口安全与性能;LangChain 的中间件保护的是你的 Agent 推理质量与决策逻辑。两者虽层级不同,但都通过“执行拦截 -> 调用下层 -> 响应拦截”的洋葱路径,实现了业务逻辑的纯净。
Relevant docs: