数学的数学——用对象和箭头统一描述一切结构,在 AI Agent 工程中落地为”如何安全组合带副作用的计算”。
Definition / Explanation
范畴论由 Samuel Eilenberg 和 Saunders Mac Lane 于 1945 年创立,最初用于代数拓扑学。核心思想:不关心对象内部是什么,只关心对象之间的关系(箭头)。
三个层次的递进
普通函数 f: A → B 点 → 点
函子 F: C → D(范畴到范畴) 世界 → 世界(保结构翻译)
单子 M + return + bind 世界 → 世界 + 链式组合能力
1. 范畴(Category)
由两样东西组成:
- 对象(Objects):可以是任何东西(类型、集合、Agent、状态…)
- 态射(Morphisms):对象之间的”箭头”,代表变换/关系
必须满足两条规则:
- 结合律:
(f ∘ g) ∘ h = f ∘ (g ∘ h) - 恒等态射:每个对象 A 都有
id_A,使得f ∘ id = id ∘ f = f
% 态射 = 函数
double(X) -> X * 2.
inc(X) -> X + 1.
% 组合(结合律自动满足)
double_then_inc(X) -> inc(double(X)).
% 恒等态射
id(X) -> X.2. 函子(Functor):整个小世界的翻译
函子是两个范畴之间保持结构的映射,做两件事:
- 把 C 中的对象映射到 D 中的对象
- 把 C 中的态射映射到 D 中的态射
- 且保持组合关系:
F(f ∘ g) = F(f) ∘ F(g)
范畴 C (普通类型) 范畴 D (List类型)
Integer ---F---> [Integer]
| |
double map(double)
| |
Integer ---F---> [Integer]
% List 函子:map 把 f: A->B 提升为 [A]->[B]
lists:map(fun double/1, [1, 2, 3]). % [2, 4, 6]
% Maybe 函子
fmap(_F, nothing) -> nothing;
fmap(F, {just, X}) -> {just, F(X)}.判断口诀:只要你写了一个”对容器里每个元素做变换、不改变容器结构”的函数,你就在实现函子。
3. 单子(Monad):带上下文的链式计算
函子和单子的分界线只有一条:
| 函子 | 单子 | |
|---|---|---|
| 核心操作 | map(变形内部值) | bind(扁平化组合) |
| 操作后结构 | 仍是一层壳 | 不会出现两层壳 |
| 串联能力 | 无(不能依赖前面结果决定后面结构) | 有(前一个结果决定下一个世界) |
为什么函子不够?
safe_div(_, 0) -> nothing;
safe_div(X, Y) -> {just, X / Y}.
% map:函数本身返回 Maybe,结果双层壳
maybe_map(fun(X) -> safe_div(10, X) end, {just, 2}).
% => {just, {just, 5.0}} ← 坏了,没法继续链式调用
% bind:自动扁平化,一层壳
maybe_bind({just, 2}, fun(X) -> safe_div(10, X) end).
% => {just, 5.0} ← 干净铁路比喻:
成功轨道: [step1] ---> [step2] ---> [step3] ---> 结果
失败轨道: =========================> 错误(一旦失败,后续全跳过)
bind 就是铺设这两条轨道的连接器
单子 = 自函子 + return + bind,其中:
return:把普通值包装进 Monad 上下文bind:解决”函子嵌套”问题,让带效果的计算可以链式组合
4. 六种常用单子
每个 Monad 对应一种”计算效果”,bind 负责让这种效果自动传播:
Either:带原因的失败
either_bind({error, E}, _F) -> {error, E};
either_bind({ok, X}, F) -> F(X).
State:隐式传递状态(本质:S -> {A, S})
state_bind(M, F) -> fun(S0) ->
{A, S1} = M(S0),
(F(A))(S1)
end.
(a -> M b) -> (b -> M c) -> (a -> M c)
kleisli(F, G) -> fun(X) -> either_bind(F(X), G) end.
Pipeline = kleisli(
kleisli(fun call_llm/1, fun parse_response/1),
fun execute_tool/1
),
Result = Pipeline("What's the weather?").7. Monad Transformer Stack:效果叠加
真实系统同时需要多种效果,Transformer 把它们叠成一座塔:
┌─────────────────────────────────────┐
│ StateT AppState ← 记忆/上下文 │ 隐式传递状态
├─────────────────────────────────────┤
│ EitherT Error ← 可能失败 │ 自动短路错误
├─────────────────────────────────────┤
│ IO ← 副作用 │ 隔离不纯操作
└─────────────────────────────────────┘
类型签名:AppState → IO(Either(Error, (Result, AppState)))
读法:接受初始状态,执行 IO,返回"要么错误,要么(结果+新状态)"
8. 其他核心概念
自然变换(Natural Transformation):函子之间的态射,描述”容器类型之间的转换”,且转换方式与容器里的内容无关。
% 自然变换:List A -> Maybe A(取第一个元素)
head([]) -> nothing;
head([H|_]) -> {just, H}.
% 自然性:head(map(f, list)) = fmap(f, head(list))Yoneda 引理:对象可以通过它与所有其他对象的关系完全刻画。直觉:你不需要知道一个对象”内部是什么”,只需要知道它”能做什么”。Transformer 注意力机制的范畴论解释——Token 的语义由它与其他 Token 的关系决定。
伴随函子(Adjoint Functors):函子 F 和 G 互为伴随(F ⊣ G),是一对”最优的互逆操作”。编码/解码、压缩/解压、抽象/具体化都是伴随关系的体现。
Current State of Knowledge
范畴论在 AI/Agent 领域的应用正在快速发展:
- MCE(Monadic Context Engineering):Princeton 大学论文,用 Functor/Applicative/Monad 三层抽象解决 Agent 架构脆弱性,开源于
github.com/yifanzhang-pro/monadic-context-engineering - Token Space:2024 年论文(arXiv 2404.11624),用范畴论框架在 Token 级别建立范畴结构,分析 Transformer 注意力机制
- UMass COMPSCI 692CT:2026 年春季研究生课程,系统讲授范畴论在 AGI 中的应用,配套 FunctorFlow 框架
- ArchAgents 范畴:arXiv 2603.28906,用范畴论统一描述 AGI 架构模式
Open Questions or Debates
- 范畴论对 Agent 工程师的实际价值边界在哪?对只写 prompt 的用户暂无直接价值;对构建 Agent 框架/runtime 的工程师价值显著
- Monad Transformer Stack 的性能开销与工程复杂度是否值得?LangChain/AutoGen 等主流框架仍采用命令式方法
- Topos 理论(范畴论高级分支)是否真的对 AGI 意识建模有帮助?UMass 课程持肯定态度,但学界尚无定论
Related Concepts
- agent-client-protocol — ACP 协议的 EitherT 层与 MCP 规范中工具结果必须显式标明成功/失败的要求对齐
- openclaw-acp-protocol — Agent 工具调用链是 Kleisli 组合的直接工程实现
- llm-wiki-pattern — 知识库构建本身可用 State Monad 建模(状态 = 知识库快照)