第20章:三层架构设计:Go、Rust 与 Python 的“三国演义”

34 阅读6分钟

第20章:三层架构设计:Go、Rust 与 Python 的“三国演义”

单体架构(Monolith)是初创期的甜蜜陷阱。三层架构不是为了炫技,而是为了让每种语言做它最擅长的事——Go 负责指挥,Rust 负责安保,Python 负责外交。

Snipaste_2026-01-29_12-20-06.png 你用 Python 写了一个 Agent Demo。 单进程,asyncio 并发,工具直接在本地跑。 你在笔记本上跑得飞起,觉得“架构不过如此”。

直到你把它部署到生产环境,噩梦开始了:

  1. 性能瓶颈:10 个用户同时发请求,Python 的 GIL(全局解释器锁)就把 CPU 卡死了,响应像蜗牛。
  2. 安全漏洞:有个用户让 Agent 写一段代码“遍历服务器文件”,Agent 照做了,直接把你服务器的 /etc/passwd 读了出来。
  3. 系统雪崩:一个工具调用吃光了 8GB 内存,导致主进程 OOM(内存溢出)被杀,其他正常的 99 个任务也跟着挂了。

这时候你才意识到:Python 是一个好的“胶水”,但不是一个好的“地基”。

image.png 我们要突破单体架构的天花板,就需要引入 多语言三层架构。这就像组建一支特种部队,不能全是拿枪的,还得有指挥官和拆弹专家。

01. 为什么要分层?(单体的极限)

在早期,我们通常使用 Python 单体架构

graph TD
    User -->|HTTP| PythonApp[Python 单体应用]
    PythonApp -->|逻辑| Orchestration[编排逻辑]
    PythonApp -->|执行| ToolExec[工具执行]
    PythonApp -->|调用| LLM_API[模型接口]

它的三大硬伤:

  1. 安全边界模糊:工具代码和主进程共享内存。恶意代码可以轻松“越狱”。
  2. 并发能力弱:Python 在高并发调度上天生腿短(受限于 GIL)。
  3. 容错性差:一处崩溃,全盘皆输。

生产级的三层架构:

02. 第一层:Orchestrator(Go 语言)—— 指挥官

角色:系统的大脑职责:它不干具体的脏活累活,它只负责 发号施令

  • 接收用户请求。
  • 决定调用哪个工作流(Planning)。
  • 管理 Token 预算(Finance)。
  • 记录审计日志。

为什么选 Go?

  • 高并发:Go 的协程(Goroutine)是处理高并发请求的神器。几万个用户同时在线,Go 能轻松扛住,Python 早趴下了。
  • 类型安全:编译型语言,能在代码运行前发现很多低级错误。
  • Temporal 亲和性:我们后面要讲的 Temporal(工作流引擎),它的原生 SDK 是 Go 写的,最稳定。

比喻:Orchestrator 是 塔台指挥员。他不需要会开飞机,但他必须头脑清醒,能同时监控几百架飞机的起降。

03. 第二层:Agent Core(Rust 语言)—— 拆弹专家

角色:系统的保镖职责:它负责在 受控环境 中执行那些可能危险的操作。

  • 运行用户生成的代码(Sandbox Execution)。
  • 调用外部工具。
  • 强制执行资源限制(CPU、内存、网络)。

为什么选 Rust?

  • 极致安全:Rust 的内存安全机制,让你很难写出导致内存泄漏或崩溃的代码。
  • 零成本抽象:性能接近 C++,但没有 C++ 的历史包袱。
  • WASM 支持:Rust 对 WebAssembly(WASM)的支持极好。我们可以用 WASM 构建一个 “数字监狱” ,把不信任的代码扔进去跑,就算炸了也伤不到宿主机。

比喻:Agent Core 是 防爆盾。当 Agent 要执行“删除文件”或“运行脚本”这种危险动作时,必须在 Rust 构建的沙箱里进行。

04. 第三层:LLM Service(Python 语言)—— 外交官

角色:系统的嘴巴职责:它负责和各种 AI 模型打交道。

  • 适配 OpenAI、Claude、Gemini 等各种 API。
  • 处理 Embedding(向量化)。
  • 管理 Prompt 模板。

为什么选 Python?

  • 生态垄断:AI 界的库(LangChain, NumPy, PyTorch)全是 Python 的。
  • 迭代极快:新的模型出来,Python SDK 永远是第一个更新的。
  • 胶水能力:处理文本、拼接 Prompt,Python 最顺手。

比喻:LLM Service 是 翻译官。它不需要身体强壮(性能),也不需要全副武装(安全),它只需要长袖善舞,能跟各种 AI 大佬谈笑风生。

image.png

05. 层间通信:如何避免“语言不通”?

三种语言,三个服务,怎么协作? 我们使用 gRPCHTTP

请求流转示例:

  1. 用户 发请求:“分析某 AI 公司”。
  2. Go (Orchestrator) 接收请求,创建工作流 ID,决定分三步走:搜概况、搜融资、写报告。
  3. Go 发指令给 Rust (Agent Core) :“去执行搜索工具,查一下这个公司。”
  4. Rust 在沙箱里安全地执行了搜索代码,拿到了网页内容。
  5. Rust 把网页内容扔给 Python (LLM Service) :“喂,帮我总结一下这段话。”
  6. Python 调大模型,生成总结,传回给 Rust,再传回给 Go
  7. Go 收到结果,继续下一步。

关键设计:Workflow ID 透传 无论请求流转到哪一层,HTTP Header 里必须带上 X-Workflow-ID。这样出了 Bug,我们能在日志系统(如 Jaeger)里看到完整的调用链路。

06. 架构师的劝退指南

虽然三层架构很美,但我必须泼一盆冷水。这套架构有昂贵的“税”:

  1. 部署复杂:原来只要 python app.py,现在你要编排 Docker、K8s,管理三个服务的版本兼容性。
  2. 调试困难:Go 报了个错,可能是 Rust 那边传回来的,Rust 的错又可能是 Python 那边超时的。查 Bug 像破案。
  3. 人才密度:你得招懂 Go 的后端,懂 Rust 的系统工程师,懂 Python 的 AI 工程师。这人不好招。

决策矩阵:

你的情况推荐架构
个人开发者 / 内部工具 / 原型验证Python 单体(别折腾,LangChain 一把梭)
中型 SaaS / 对外服务 / 追求并发Go + Python(Go 做网关和编排,Python 做业务)
平台级 PaaS / 代码解释器 / 极高安全Go + Rust + Python(三层完全体)

总结

架构设计的本质是 Trade-off(权衡)

  • 我们引入 Go,是为了解决 并发和编排 的问题。
  • 我们引入 Rust,是为了解决 安全和隔离 的问题。
  • 我们保留 Python,是为了连接 AI 生态

这就是 Agent 系统的“三国演义”。没有最好的语言,只有最适合的角色。

下一章预告

架构搭好了,服务也跑起来了。 但是,网络是不可靠的,服务器是会宕机的。如果 Agent 正在执行一个耗时 30 分钟的任务,跑到第 29 分钟时,机房断电了,怎么办? 难道让用户重来一遍?

下一章,我们将介绍 Temporal 工作流引擎:它是 Agent 系统的 “时光宝石” ,能让程序在崩溃后,像什么都没发生一样,从断点处 完美复活