LLM + 数据集构成的计算系统(LDS),与概率 Lambda 演算在计算能力上等价。
这不只是理论推导。我们发现:现有的 Agent 配置文件(如 YAML)已经在不自觉地使用 Lambda 演算的结构。本研究做的是揭示这一隐藏的数学等价,并将其显式化为可执行的 DSL。
理论: LDS ≡ 概率 Lambda 演算
实证: 60/60 Church 原语实验全部通过
实例: agent-config.yml 每一行都对应一个 Lambda 构造
工具: lambdagent DSL — ~11,300 行 Python,81 个导出符号
11 核心构造 + 5 多智能体构造 + 4 Skill 构造
+ MCP Client + A2A Protocol + RAG + Checkpoint + Sandbox
LLM 正在改变软件工程的实践,但缺乏理论基础:
业界已经在用 YAML/JSON 配置文件来"编程" Agent,但没有人意识到这些配置文件本质上是 Lambda 表达式的序列化。Prompt 工程师在写函数体,Agent 架构师在组合高阶函数——只是缺少了形式化的语言来表达这一点。
本研究的目标:揭示这一等价性,并提供可执行的工具。
以下是一个真实的 Agent 配置文件(agent-cofig.yml):
agentId: seeCoderManus
type: react
model:
provider: dashscope
name: qwen3-max-2026-01-23
temperature: 0.7
maxTokens: 4096
systemPrompt: |
你是 SeeCoderManus,一个智能编程助手...
react:
maxSteps: 20
mcp:
onlineTool:
example-mcp-server:
- everything_get_sum
- chat_improve_prompt
localTools:
- terminate
memory:
strategy: redis
size: 20
ttl: 7200
这个 YAML 就是一个 Lambda 表达式:
SeeCoderManus = Memory( ← memory: {redis, size=20}
Loop( ← type: react
think >> act >> observe, ← ReAct 三步循环
max_steps = 20 ← react.maxSteps
),
store = redis(size=20, ttl=7200)
)
where:
think = Lam("SeeCoderManus", ← agentId
prompt = "你是 SeeCoderManus...", ← systemPrompt
model = qwen3-max, ← model.name
temperature = 0.7) ← model.temperature
act = Route(think_output, { ← mcp 配置
"everything_get_sum": Tool(MCP), ← onlineTool
"chat_improve_prompt": Tool(MCP),
"terminate": Tool(λx.x) ← localTools: 恒等函数 = 递归终止
})
逐字段对应:
| YAML 字段 | Lambda 演算概念 | 说明 |
|---|---|---|
model + systemPrompt |
λ 抽象 λx.body |
模型参数 = 求值引擎,prompt = 函数体 |
agent(input) |
函数应用 (f x) |
将输入送入 Agent = β-规约 |
type: react |
Y 组合子 | ReAct = 反复 think-act-observe 直到终止 |
react.maxSteps: 20 |
Y 展开次数上界 | 最多 β-规约 20 步 |
temperature: 0.7 |
概率选择 ⊕_p |
0 = 确定性 Lambda,>0 = 概率 Lambda |
mcp.onlineTool |
Tool(外部 Oracle) | 外部函数提升为 Lambda 项 |
localTools: [terminate] |
恒等函数 λx.x |
Y 组合子的 base case — 停止递归 |
memory: redis |
环境扩展 Γ' = Γ ∪ store |
持久化的变量绑定 |
memory.ttl: 7200 |
变量生命周期 | 绑定存活 2 小时后过期 |
rag |
外部存储(无界纸带) | 突破上下文窗口限制 |
关键发现:terminate 工具就是恒等函数 λx.x——它不做任何变换,只是返回输入本身。这正是 Y 组合子的 base case:没有 base case,ReAct 循环将无限展开。这不是巧合,这是递归终止条件的数学本质。
意义:行业已经在不自觉地使用 Lambda 演算结构来设计 Agent。YAML 配置就是 Lambda 项的声明式序列化。我们的理论不是在创造新的东西,而是在命名和形式化已经存在的实践。
第一环:Church 编码——数据即计算
c_n = λf.λx. f^n(x)
数据被表示为函数的行为。LLM 也是如此:它不存储"3"这个符号,而是通过训练数据学习"3"的行为模式。
第二环:LLM 作为函数学习器
LLM 在数据集 D 上训练/提示后,学习到映射 F_{M,D} : Input → Output。
两种绑定方式:
第三环:构造 Lambda 原语
用 LDS 实现所有 Church 编码原语:
| 原语 | Lambda 定义 | LDS 实现 | 实验结果 |
|---|---|---|---|
| SUCC | λn.λf.λx. f(n f x) |
7 个示例 → 泛化到 255 | ✓ 8/8 |
| TRUE/FALSE | λa.λb. a / λa.λb. b |
各 5 个示例 | ✓ 8/8 |
| AND/OR/NOT | 逻辑运算 | 2-4 个示例 | ✓ 10/10 |
| IF | λc.λt.λe. c t e |
6 个示例 | ✓ 6/6 |
| PAIR/FST/SND | Church 对 | 3-4 个示例 | ✓ 8/8 |
| 函数组合 | λx.g(f(x)) |
DOUBLE ∘ SUCC | ✓ 6/6 |
| 递归 | Y 组合子 | CoT 展开 FACTORIAL | ✓ 6/6 |
| Church 数 | λf.λx. f^n(x) |
add1/double 重复应用 | ✓ 8/8 |
| 总计 | 60/60 |
第四环:组合封闭性
f >> g:DOUBLE ∘ SUCC 6/6 通过Pair(SUCC, DOUBLE) >> Fst() 通过第五环:等价性定理
| 难题 | 解法 | 对应到 agent-config.yml |
|---|---|---|
| 近似 vs 精确 | 概率 Lambda 演算(Dal Lago 2012),仍 Turing 完备 | temperature: 0.7 = 概率参数 |
| 有限上下文 | 自回归 = 无界带(Schuurmans 2024) | memory: redis = 外部存储增强 |
| 训练 vs 编程 | 指称语义(说明做什么)vs 操作语义(说明怎么做) | systemPrompt = 声明式规约 |
既然 YAML 配置已经是 Lambda 项的序列化形式,那么我们可以设计一个 DSL,让这种对应显式化、可执行、可验证。
# agent-config.yml 用 lambdagent DSL 表达:
from lambdagent import Lam, Tool, Loop, Memory, Route
think = Lam("SeeCoderManus",
prompt="你是 SeeCoderManus...",
model="qwen3-max",
temperature=0.7)
tools = Route(think, {
"everything_get_sum": Tool("sum", mcp_call),
"chat_improve_prompt": Tool("improve", mcp_call),
"terminate": Tool("terminate", lambda x: x), # λx.x = base case
})
react = Loop(think >> tools, max_steps=20) # Y 组合子,最多展开 20 次
agent = Memory(react, store={"redis": True}) # 环境扩展 Γ ∪ store
11 个核心构造(Lambda 演算):
| # | DSL 构造 | Lambda 演算 | 语法 |
|---|---|---|---|
| 1 | Lam(name, prompt) |
λ 抽象 λx.body |
创建 Agent |
| 2 | agent(input) |
函数应用 (f x) |
β-规约 |
| 3 | f >> g |
组合 λx.g(f(x)) |
管道 |
| 4 | If(cond, a, b) |
Church 条件 | 分支 |
| 5 | Loop(body, cond) |
Y 组合子 | 递归/CoT |
| 6 | Pair(f, g) |
PAIR λa.λb.λf. f a b |
并行+打包 |
| 7 | Fst() / Snd() |
投影 | 解构 |
| 8 | Tool(name, fn) |
原语/Oracle | 外部工具 |
| 9 | Route(cls, routes) |
广义 Church 布尔 CASE | N 路分发 |
| 10 | Guard(agent, P) |
依赖类型 {x:T\|P(x)} |
输出约束 |
| 11 | Memory(agent, store) |
环境扩展 Γ'=Γ∪s |
持久状态 |
5 个多智能体构造(扩展至 π-演算):
| # | DSL 构造 | 进程演算对应 | 语法 |
|---|---|---|---|
| 12 | Channel + Send + Receive |
π-calculus 通道 c!(v) / c?(x) |
Agent 间通信 |
| 13 | SharedMemory |
共享环境 Γ_shared |
多 Agent 共享状态 |
| 14 | GroupChat |
Y_n(Loop + Route) |
多 Agent 群组对话 |
| 15 | Handoff |
动态 CASE(运行时路由) | 动态委派 |
| 16 | AsyncPar |
并发 β-规约 | 线程池真并行 |
4 个 Skill 系统构造:
| 构造 | Lambda 语义 | 说明 |
|---|---|---|
Skill(name, term) |
let name = term in ... |
命名的可复用 Lambda 项 |
SkillPack |
{name_i: skill_i} |
技能集合(类似 package) |
SkillRegistry |
Gamma_skills: Name -> Skill |
全局注册表(可发现、可搜索) |
SkillAgent |
lambda x. discover(x) >> execute |
自动发现技能的 Agent |
协议集成层:
| 模块 | 说明 | Lambda 语义 |
|---|---|---|
MCPServer / MCPTool |
MCP 协议客户端 (HTTP + stdio) | Tool(name, lambda x. mcp_call(x)) |
AgentCard / A2AServer / A2AClient |
Google A2A 协议 | Skill 发布/发现/远程调用 |
RAGTool / AgenticRAG |
检索增强生成 | Tool("rag", lambda x. retrieve(store, x, k)) |
Checkpoint / CheckpointManager |
状态序列化与恢复 | save(Gamma, trace) / load(path) |
agent-config.yml lambdagent DSL Lambda 演算
════════════════ ══════════════ ══════════════
model + systemPrompt → Lam("name", prompt) → λx. body
type: react → Loop(body, cond) → Y(λself.λx. ...)
react.maxSteps: 20 → Loop(max_steps=20) → Y 展开上界
mcp.onlineTool → Tool("name", fn) → 原语 / Oracle
localTools: terminate → Tool("t", λx.x) → λx.x (base case)
memory: redis → Memory(agent, store) → Γ' = Γ ∪ store
temperature: 0.7 → Lam(temperature=0.7) → 概率选择 ⊕₀.₇
rag → (外部存储扩展) → 无界纸带
这三层对应说明:YAML 配置是 Lambda 表达式的声明式语法,DSL 是过程式语法,Lambda 演算是语义。
实验 A:Church 原语验证(真实 API 调用)
SUCC, TRUE/FALSE, AND/OR/NOT, IF, PAIR, 组合, Tool, Church 数
总计: 29/29 通过,43 步 β-规约
实验 B:多步研究 Agent
decompose >> map_research >> synthesize >> Loop(critique/refine)
总计: 15 步 β-规约,输出 5 段高质量研究报告
实验 C:从 YAML 构建 Agent
agent-cofig.yml → from_config() → 可执行 Lambda 项
ReAct 循环 = Loop(think >> act >> observe)
3 步 β-规约完成模拟执行
from lambdagent import from_config, describe_config
# 将 YAML 编译为 Lambda 项
agent = from_config("agent-cofig.yml")
# 打印 Lambda 结构
print(describe_config("agent-cofig.yml"))
# 输出:
# SeeCoderManus = Memory(Loop(think >> act >> observe, max_steps=20), redis)
# where: think = Lam(...), tools = [Tool(MCP), Tool(λx.x)]
# 执行 = β-规约链
ctx = Context()
result = agent("帮我写一个快速排序", ctx)
ctx.print_trace() # 打印每步 β-规约
from_config() 本质上是一个编译器:从 YAML 声明式语法到 Lambda 项的语义表示。
选择数据集 D ⟺ 编写 Lambda 项
训练/提示 LLM ⟺ 编译程序
推理 ⟺ 执行程序
System Prompt = 全局环境 Γ ← agent-config.yml 的 systemPrompt
Few-shot 示例 = 运行时 Lambda 绑定 ← Dataset 的 examples
CoT 提示 = Y 组合子展开策略 ← type: react
Temperature = 概率参数 ⊕_p ← model.temperature
这是本研究最具实践意义的推论。
现有的 Agent 配置格式(YAML/JSON/TOML)已经是 Lambda 项的序列化——只是没有人用这个视角看待它。一旦认识到这一点:
| 现有概念 | Lambda 本质 | 为什么有效 |
|---|---|---|
| ReAct | Loop(think >> act >> observe) |
Y 组合子提供无界计算 |
| Chain-of-Thought | Y 组合子的逐步展开 | 每步 β-规约降低问题复杂度 |
| Tool Use | Tool(name, fn) — 外部 Oracle |
将不可计算/效率低的部分外包 |
| terminate | λx.x — 恒等函数 |
Y 组合子的 base case |
| Memory / RAG | Γ' = Γ ∪ store — 环境扩展 |
突破有限上下文 = 无界纸带 |
| Multi-Agent | 高阶函数组合 | Agent 作为参数传递给其他 Agent |
| Routing | 广义 Church 布尔 | 分类器选择下游函数 |
| Output Validation | 依赖类型 {x : T \| P(x)} |
约束输出满足谓词 |
如果 LDS 是编程模型,则:
Phase 1: 形式化 [THEORY.md — ✅ 已完成]
├── 定义 LDS 计算模型(定义 1-5)
├── 建立与 Lambda 项的对应关系
└── 陈述等价性定理
Phase 2: 实验验证 — ✅ 已完成
├── Church 原语实验 60/60 通过(CLI),51/51 通过(API)
└── 分析正确率、泛化能力、组合稳定性
Phase 3: Agent DSL [lambdagent/] — ✅ 已完成
├── 11 个核心构造,严格对应 Lambda 演算
├── 5 个多智能体构造(π-演算: Channel, SharedMemory, GroupChat, Handoff, AsyncPar)
├── Skill 系统(Skill, SkillPack, SkillRegistry, SkillAgent, @skill 装饰器)
├── MCP Client(MCPServer, MCPTool, HTTP + stdio 传输)
├── A2A Protocol(AgentCard, A2AServer, A2AClient — Google A2A v0.3)
├── RAG(RAGTool, AgenticRAG, SimpleVectorStore, ChromaDB 后端)
├── Checkpoint(Checkpoint, CheckpointManager, save/load_context)
├── Church 原语 29/29 通过(DSL + 真实 API)
├── 多步研究 Agent 成功运行(15 步 β-规约)
├── from_config():YAML → Lambda 编译器 (v1 + v2 with lint)
├── Sandbox(SandboxedTool, SandboxPolicy, SecureExecutor, ResourceLimiter, @sandboxed)
└── ~11,300 行 Python,81 个导出符号,4 项专利
Phase 4: 真实案例验证 [agent-cofig.yml] — ✅ 已完成
├── 逐字段建立 YAML ↔ Lambda 对应
├── 发现 terminate = λx.x(Y 组合子 base case)
├── 证明现有 Agent 配置已是 Lambda 项的序列化
└── YAML → DSL → Lambda 三层对应
Phase 5: 严格证明 [进行中]
├── 方向一(LDS → Lambda):LLM 是可计算的
├── 方向二(Lambda → LDS):利用 Schuurmans 2024
└── 处理近似性:概率 Lambda 演算 + PAC 框架
Phase 6: 论文撰写
├── 标题:"Agent Configuration as Lambda Calculus:
│ Theory, DSL, and Industrial Evidence"
└── 投稿方向:ICML / NeurIPS / AAAI
Phase 7: 应用扩展
├── 类型系统(Agent 输入/输出类型推导)
├── 形式化验证工具
├── 异步并行(Par + asyncio)
├── Sandbox 进程隔离 — ✅ 已完成
│ ├── SandboxedTool(pickle IPC + 子进程隔离)
│ ├── SandboxPolicy 预设(strict / default / permissive)
│ ├── SecureExecutor(递归包裹 Term 树中所有 Tool)
│ ├── ResourceLimiter(RLIMIT_CPU / AS / NOFILE / NPROC)
│ └── @sandboxed 装饰器 + 异常体系
└── 与 LangChain/DSPy 的基准对比
Church-Turing-LDS 论题:是否所有"自然可计算"函数都是 LDS-可计算的?
LDS 复杂性理论:模型参数量、数据集大小、上下文长度对应什么计算复杂性类?
最小 LDS:实现给定函数的最小数据集规模是多少?(类比 Kolmogorov 复杂性)
LDS 等价性判定:两个 LDS 是否计算同一函数?(类比 Lambda 项等价性不可判定)
YAML 配置的形式化验证:能否自动检查一个 agent-config.yml 是否满足给定规约?
Agent 配置的等价变换:两个不同的 YAML 配置是否定义了语义等价的 Agent?这对应 Lambda 项的 α-等价和 β-等价。
Paper08/
├── IDEA.md ← 本文件:完整研究框架
├── PLAN.md ← 实验计划与结果记录
├── THEORY.md ← 形式化理论(定义、定理、证明)
├── RUNTIME_SPEC.md ← 运行时规格文档
├── FROM_CONFIG_SPEC.md ← YAML → Lambda 编译器规格
├── EXPERIMENT_REPORT.md ← 详细实验报告
├── agent-cofig.yml ← 真实 Agent 配置(Lambda 项实例)
│
├── experiment_church_primitives.py ← 原始实验代码(API 版,51/51)
├── run_experiment.py ← 原始实验代码(CLI 版,60/60)
├── experiment_results.json ← 实验原始数据
│
├── lambdagent/ ← Agent DSL 包(~11,300 行,46 个 .py 文件,62 个导出符号)
│ ├── core.py Term, Context, TraceEntry
│ ├── primitives.py Lam, Compose, If, Loop, Pair, Fst, Snd, Tool
│ ├── extensions.py Par, Route, Memory, Guard
│ ├── dataset.py Dataset 类
│ ├── from_config.py YAML → Lambda 编译器 (v1)
│ ├── fromconfig/ YAML → Lambda 编译器 (v2, 带 lint)
│ ├── agentruntime/ 运行时:β-规约引擎、ReAct、LLM 适配器
│ ├── cli/ 命令行界面
│ ├── multiagent.py Channel, Send, Receive, SharedMemory,
│ │ GroupChat, Handoff, AsyncPar
│ ├── skills.py Skill, SkillPack, SkillRegistry, SkillAgent, @skill
│ ├── mcp_client.py MCPServer, MCPTool, mcp_tools (MCP 协议)
│ ├── checkpoint.py Checkpoint, CheckpointManager, save/load_context
│ ├── a2a.py AgentCard, A2AServer, A2AClient (Google A2A)
│ ├── rag.py RAGTool, AgenticRAG, SimpleVectorStore, create_rag
│ └── sandbox.py SandboxedTool, SandboxPolicy, SecureExecutor,
│ ResourceLimiter, @sandboxed, SandboxViolation
│
├── examples/ ← 8 个示例文件 + 1 个 YAML 配置
│ ├── ex01_church_primitives.py ← Church 原语验证(29/29)
│ ├── ex02_research_agent.py ← 多步研究 Agent(15 步 β-规约)
│ ├── ex03_from_yaml.py ← YAML → Lambda 解读与执行
│ ├── ex04_generalization.py ← 泛化能力测试
│ ├── ex05_failure_boundary.py ← 失败边界探索
│ ├── demo_advanced.py ← 高级功能演示
│ ├── nl2agent_demo.py ← 自然语言→Agent 演示
│ └── quick_start.py ← 快速入门
│
└── patents/ ← 4 项专利
├── patent-01-lint/ ← YAML → Lambda 静态分析
├── patent-02-trace/ ← β-规约追踪
├── patent-03-compiler/ ← YAML → Lambda 编译器
└── patent-04-cli/ ← 命令行界面
现有的 Agent 配置文件已经是 Lambda 表达式——只是没有人用这个视角看待它。
systemPrompt 是 λ 抽象的 body。type: react 是 Y 组合子。terminate 是恒等函数 λx.x。memory 是环境扩展 Γ'。temperature 是概率参数 ⊕_p。
我们的工作不是创造新的东西,而是命名和形式化已经存在的实践。
编程范式的三次转变:
1930s Lambda 演算 / Turing 机 → 理论计算
1950s 高级编程语言 → 代码即程序
2020s LLM + Dataset + YAML 配置 → 配置即程序(= Lambda 项的声明式序列化)
lambdagent DSL 和 from_config() 编译器是这一认知的可执行证明:
# YAML 配置 → Lambda 项 → 可执行 Agent → β-规约追踪
agent = from_config("agent-cofig.yml")
result = agent("帮我写一个快速排序", ctx)
ctx.print_trace() # 每步 β-规约可见、可调试、可验证
from_config("agent-config.yml")编译器接受的 YAML 配置格式完整说明。 每个字段标注:类型、是否必填、默认值、约束、对应的 Lambda 构造、相关 lint 规则。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 | 说明 |
|---|---|---|---|---|---|
agentId |
string | 否 | "agent" |
Term 标识符 | Agent 唯一标识 |
name |
string | 否 | 同 agentId | Term.name | 显示名称 |
description |
string | 否 | "" |
— | 描述性文本 |
type |
enum | 是 | — | 决定顶层 Lambda 构造 | simple | react | chain | router | parallel |
Schema 规则: S001 (type 缺失 → ERROR), S002 (type 非法值 → ERROR)
Lint 规则: L000 (框架检测, 自动识别 crewai/autogen/langchain/dify/lambdagent)
| type | Lambda 构造 | 公式 | 说明 |
|---|---|---|---|
simple |
Lam | λx. LLM(prompt, x) |
单次 LLM 调用 |
react |
Loop (Y combinator) | Y_n(λself.λstate. think >> route >> observe) |
ReAct 循环,n = maxSteps |
chain |
Compose | λx. step_N(... step_2(step_1(x))) |
顺序管道 |
router |
Route (CASE) | λx. CASE(classifier(x)) [(l₁,a₁), (l₂,a₂), ...] |
条件分派 |
parallel |
Par (PAIR) | λx. PAIR(a₁(x))(a₂(x)) |
并行执行 |
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
systemPrompt |
string (多行) | type=simple/react 时是 | "You are a helpful assistant." |
λx. body 中的 body |
Schema 规则: S003 (simple/react 缺失 → ERROR) Lint 规则: L001 (空 prompt → ERROR, CrewAI 允许用 role+goal+backstory 替代)
systemPrompt: |
你是一个编程助手。
你能使用工具解决问题。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 | 约束 |
|---|---|---|---|---|---|
model.provider |
string | 否 | "anthropic" |
LLM 后端选择 | anthropic | openai | dashscope | ollama |
model.name |
string | 否 | 按 provider 默认 | 模型 ID | Anthropic 默认 claude-sonnet-4-20250514,OpenAI 默认 gpt-4o,DashScope 默认 qwen-max |
model.temperature |
float | 否 | 0.0 |
⊕_p 概率参数 |
[0.0, 2.0] |
model.maxTokens |
int | 否 | 1024 |
输出长度上限 | > 0 |
model.topP |
float | 否 | — | 核采样参数 | (0.0, 1.0] |
model.stopSequences |
list[string] | 否 | [] |
停止序列 | — |
model.baseUrl |
string | 否 | "" |
自定义 API 端点 | 完整 URL |
Schema 规则: S009 (temperature 超范围 → WARN) Lint 规则: L002 (无 model → ERROR), L007 (temperature > 1.5 → WARN), L014 (temperature=0 → INFO)
Provider 默认模型解析 (_resolve_model()):
provider=anthropic, name="" → "claude-sonnet-4-20250514"
provider=openai, name="" → "gpt-4o"
provider=dashscope, name="" → "qwen-max"
provider≠anthropic, name有值 → "{provider}/{name}"
子 Agent 继承: chain.steps / router.routes / parallel.agents 中的子 Agent 若未指定 model,继承父级 model 配置。
model:
provider: dashscope
name: qwen3-max-2026-01-23
temperature: 0.7
maxTokens: 4096
仅当 type: react 时生效。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 | 约束 |
|---|---|---|---|---|---|
react.maxSteps |
int | 否 | 10 |
Y 组合子展开上限 Y_n |
> 0,建议 <= 1000 |
react.observationEnabled |
bool | 否 | true |
是否将工具输出注入状态 | — |
react.toolTimeout |
int | 否 | 30 |
单个工具调用超时 (秒) | > 0 |
react.verbose |
bool | 否 | false |
打印每步 β-规约详情 | — |
Schema 规则: S004 (maxSteps <= 0 → ERROR) Lint 规则:
Y_0(g) = ⊥)编译行为 (_compile_react()):
Lam("agent.think", prompt, model)Dict[str, Tool] (经 ToolGateway 包装)react_step 闭包 (包含 state 压缩、隐式终止检测、工具缓存)Loop(body=react_step, condition=stop_condition, max_steps=N)内置优化:
react:
maxSteps: 20
observationEnabled: true
toolTimeout: 30
verbose: true
仅当 type: chain 时生效。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
chain.steps |
list[object] | 是 | — | Compose(step1, step2, ...) |
chain.steps[].name |
string | 否 | "step_{i}" |
步骤名称 |
chain.steps[].prompt |
string | 是 | "" |
λx. body |
chain.steps[].model |
object | 否 | 继承父级 | 可覆盖模型 |
chain.steps[].guard |
object | 否 | — | 步骤级 Guard |
Schema 规则: S005 (steps 为空 → ERROR) Lint 规则: L006 (空 steps → ERROR), L024 (重复 agent name → WARN)
type: chain
chain:
steps:
- name: researcher
prompt: "研究以下主题..."
- name: writer
prompt: "基于研究结果撰写报告..."
model:
temperature: 0.8
仅当 type: router 时生效。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
router.classifier |
object | 是 | — | 分类器 Lam |
router.classifier.prompt |
string | 是 | "Classify the input." |
分类 prompt |
router.classifier.model |
object | 否 | 继承父级 | 可覆盖模型 |
router.routes |
Dict[string, object] | 是 | — | {label: sub_agent} |
router.default |
object | 否 | None |
默认路由 (未匹配时) |
Schema 规则: S006 (routes 为空 → ERROR), S007 (classifier 缺失 → ERROR) Lint 规则: L005 (空 routes → ERROR), L013 (无 default → WARN), L023 (空 target → ERROR)
type: router
router:
classifier:
prompt: "将输入分类为 'code' 或 'writing'"
routes:
code:
type: react
systemPrompt: "你是代码专家..."
writing:
type: simple
systemPrompt: "你是写作专家..."
default:
type: simple
systemPrompt: "通用助手..."
仅当 type: parallel 时生效。
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
parallel.agents |
list[object] | 是 (>=2) | — | Par(a1, a2, ...) |
parallel.merge |
enum | 否 | "tuple" |
结果合并策略 |
parallel.mergePrompt |
string | 否 | "Synthesize..." |
merge=custom 时的合并 prompt |
merge 取值:
tuple: 返回原始元组 (result1, result2, ...)concat: 拼接所有结果 "\n\n".join(results)custom: 用 mergePrompt 的 Lam 合并 Par >> format >> Lam(mergePrompt)Schema 规则: S008 (agents < 2 → ERROR)
type: parallel
parallel:
agents:
- type: simple
name: analyst
systemPrompt: "分析市场趋势..."
- type: simple
name: researcher
systemPrompt: "调研竞品..."
merge: custom
mergePrompt: "综合以上分析,给出结论..."
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
mcp.onlineTool |
Dict[server, list[tool_name]] | 否 | {} |
Tool(name, mcp_caller) |
mcp.localTools |
list[string] | 否 | [] |
本地工具列表 |
mcp.policy.mode |
enum | 否 | "auto" |
工具策略 |
mcp.policy.retryOnFail |
int | 否 | 0 |
MCP 调用重试次数 |
mcp.policy.mode 取值: auto | force | intelligence | disable
mcp.localTools 特殊值: terminate 编译为 Tool("terminate", λx.x) (恒等函数 = Y 组合子基 case)
Lint 规则: L004 系列 (react 无 terminate), L011 (无工具仅 terminate), L026 (远程依赖检测)
mcp:
onlineTool:
example-mcp-server:
- search_tool
- calculate_tool
localTools:
- terminate
policy:
mode: auto
retryOnFail: 1
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
app.mcp.custom.nodes.{server_name}.url |
string | 是 | "" |
MCP 服务器 URL |
app.mcp.custom.nodes.{server_name}.endpoint |
string | 否 | "" |
API 路径 (拼接在 url 后) |
app.mcp.custom.nodes.{server_name}.headers |
Dict[string, string] | 否 | {} |
请求头 (支持 ${ENV_VAR} 引用) |
app.mcp.custom.nodes.{server_name}.timeout |
int | 否 | 30 |
超时秒数 |
app.mcp.custom.nodes.{server_name}.retry |
int | 否 | 0 |
重试次数 |
app:
mcp:
custom:
nodes:
my-server:
url: https://mcp.example.com
endpoint: /mcp/v1
headers:
Authorization: "${MCP_AUTH_TOKEN}"
timeout: 30
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
memory.enabled |
bool | 否 | false |
是否启用 Memory(agent, store) |
memory.strategy |
enum | 否 | "local" |
存储后端 |
memory.size |
int | 否 | 20 |
最大条目数 (LRU) |
memory.ttl |
int | 否 | 3600 |
条目过期秒数 |
memory.strategy 取值: local (内存 dict) | redis (分布式) | sqlite (持久化)
Lint 规则:
编译行为: 编译为 Memory(agent, store) 包装在最外层(Guard 之后)
memory:
enabled: true
strategy: redis
size: 20
ttl: 7200
{x:T | P(x)})| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 | 说明 |
|---|---|---|---|---|---|
guard.validator |
string (Python expr) | 否 | "True" |
谓词 P(x) |
eval 执行,可用变量: x, len, str, int, float |
guard.retry |
int | 否 | 0 |
验证失败重试次数 | — |
guard.fallback |
enum | 否 | "error" |
最终失败策略 | error | empty | last |
guard.maxOutputLength |
int | 否 | 0 (不限) |
输出长度上限 | 超限 → 触发 retry 或 truncate |
guard.dangerousCommandBlock |
bool | 否 | false |
启用 ToolGateway | CRITICAL/HIGH 命令自动阻止 |
guard.highRiskConfirmation |
bool | 否 | false |
HIGH 需确认 | 触发 confirm_callback |
Lint 规则: L012 (retry > 5 → WARN), L025 (有 guard 但无 retry → WARN)
编译行为:
dangerousCommandBlock / highRiskConfirmation / maxOutputLength → 构建 ToolGateway(GatewayPolicy) → 所有 Tool 包装为 GatedToolvalidator / retry / fallback → 构建 Guard(agent, validator_fn, retry, on_fail) 包装在 Memory 之前ToolGateway 风险分级 (50+ regex 规则):
| 级别 | 示例命令 | 默认行为 |
|---|---|---|
| CRITICAL (22 规则) | rm -rf /, curl\|sh, cat ~/.ssh/*, fork bomb |
始终 BLOCK |
| HIGH (18 规则) | sudo, rm -r, pip install, kill -9, git push --force |
dangerousCommandBlock → BLOCK;highRiskConfirmation → CONFIRM |
| MEDIUM (10 规则) | mv, sed -i, git rebase, cp -r |
LOG_ONLY |
| LOW | 文件写入, MCP 远程调用 | ALLOW + log |
| SAFE | ls, cat, git status, terminate |
ALLOW |
guard:
validator: "len(x) > 10 and 'error' not in x.lower()"
retry: 2
fallback: last
maxOutputLength: 3000
dangerousCommandBlock: true
highRiskConfirmation: true
| 字段 | 类型 | 必填 | 默认值 | Lambda 语义 |
|---|---|---|---|---|
rag.enabled |
bool | 否 | false |
是否启用 RAG |
rag.source |
string | 否 | "" |
数据源路径 |
rag.topK |
int | 否 | 5 |
检索返回条数 |
rag.chunkSize |
int | 否 | 500 |
分块大小 |
rag.backend |
enum | 否 | "simple" |
向量存储后端 |
rag.minScore |
float | 否 | 0.0 |
最低相关度阈值 |
rag.backend 取值: simple (TF-IDF, 零依赖) | chroma (ChromaDB)
Lint 规则: L016 (启用 → INFO)
rag:
enabled: true
source: ./docs/
topK: 5
backend: simple
# === 完整 Agent 配置示例 ===
agentId: seeCoderManus
name: SeeCoderManus
description: 智能编程助手
type: react
model:
provider: dashscope
name: qwen3-max-2026-01-23
temperature: 0.7
maxTokens: 4096
systemPrompt: |
你是 SeeCoderManus,一个智能编程助手。
你能够帮助用户解决编程问题。
react:
maxSteps: 20
observationEnabled: true
toolTimeout: 30
verbose: true
mcp:
onlineTool:
example-mcp-server:
- search_tool
localTools:
- terminate
policy:
mode: auto
app:
mcp:
custom:
nodes:
example-mcp-server:
url: https://mcp.example.com
endpoint: /mcp/v1
headers:
Authorization: "${MCP_AUTH_TOKEN}"
memory:
enabled: true
strategy: redis
size: 20
ttl: 7200
guard:
dangerousCommandBlock: true
highRiskConfirmation: true
maxOutputLength: 3000
validator: "len(x) > 0"
retry: 1
fallback: last
rag:
enabled: false
YAML 文件
│
▼
[yaml.safe_load()] ← 安全加载,禁止 yaml.load()
│
▼
[validate_schema(cfg)] ← S001-S009 规则
│ 有 ERROR → 抛出 SchemaError
▼
[build_agent(cfg, overrides)]
│
├─ [_build_gateway(guard_cfg)] → ToolGateway (如有安全字段)
│
├─ 按 type 分派:
│ ├─ simple → _compile_simple() → Lam
│ ├─ react → _compile_react() → Loop(react_step, condition, maxSteps)
│ ├─ chain → _compile_chain() → Compose(*steps)
│ ├─ router → _compile_router() → Route(classifier, routes, default)
│ └─ parallel→ _compile_parallel()→ Par(*agents) [>> merge]
│
├─ [_compile_guard(agent, guard_cfg)] → Guard(agent, validator, retry, on_fail)
│
└─ [_compile_memory(agent, memory_cfg)] → Memory(agent, store)
│
▼
Term (可执行 Lambda 项)
| ID | 级别 | 触发条件 |
|---|---|---|
| S001 | ERROR | 缺失 type 字段 |
| S002 | ERROR | type 值不在 simple/react/chain/router/parallel 中 |
| S003 | ERROR | simple/react 缺失 systemPrompt |
| S004 | ERROR | react.maxSteps <= 0 |
| S005 | ERROR | chain.steps 为空 |
| S006 | ERROR | router.routes 为空 |
| S007 | ERROR | router.classifier 缺失 |
| S008 | ERROR | parallel.agents 少于 2 个 |
| S009 | WARN | temperature 不在 [0, 2.0] 范围 |
| ID | 级别 | 触发条件 | Lambda 含义 |
|---|---|---|---|
| L000 | INFO | 始终 | 框架检测结果 |
| L001 | ERROR | 空 systemPrompt | λx. ⊥ 函数体未定义 |
| L002 | ERROR | 无 model 配置 | 无法执行 β-规约 |
| L003 | ERROR | maxSteps=0 | Y_0(g) = ⊥ |
| L004a | ERROR | react 无 terminate 且无替代终止 | Y 组合子无基 case,潜在无限循环 |
| L004b | WARN | 无 terminate 但有有界回退 | 有回退但无优雅终止 |
| L004c/d | INFO | 框架内置终止 | 框架运行时提供基 case |
| L005 | ERROR | router 空 routes | CASE 无分支 |
| L006 | ERROR | chain 空 steps | 空组合链 |
| L007 | WARN | temperature > 1.5 | 高熵,输出不稳定 |
| L008 | WARN | memory.ttl=0 | Γ' 绑定永不回收 |
| L009 | WARN | memory.size=0 | Γ' = Γ ∪ ∅ = Γ |
| L010 | WARN | maxSteps > 50 | Y_{n>50} 高成本 |
| L011 | WARN | react 无工具仅 terminate | 纯推理循环 |
| L012 | WARN | guard.retry > 5 | 过多重试 |
| L013 | WARN | router 无 default | CASE 不完备 |
| L014 | INFO | temperature=0 | 确定性 Lambda |
| L015 | INFO | memory 启用 | 显示策略参数 |
| L016 | INFO | rag 启用 | 外部知识 Oracle |
| L017 | WARN | 未显式设置 maxSteps | Y_n 的 n 由框架隐式决定 |
| L018 | WARN | maxSteps > 100 | Y_{>100} ≈ Y 近似无界 |
| L019 | INFO | is_termination_msg 检测到 | AutoGen 字符串匹配终止 |
| L020 | WARN | allow_delegation 但无 peer | 委派目标未定义 |
| L021 | ERROR | 多 Agent 无终止条件 | GroupChat Y 无基 case 且无界 |
| L022 | WARN | 有 terminate 但无 maxSteps | LLM 不调 terminate 则无限循环 |
| L023 | ERROR | router 路由目标为空 | CASE 分支 → ⊥ |
| L024 | WARN | chain 中重复 agent | f >> g >> f 冗余组合 |
| L025 | WARN | guard 无 retry | 验证失败无恢复 |
| L026 | INFO | 远程依赖检测 | Oracle 依赖外部服务 |
from_config(path, **overrides) 支持以下运行时覆盖:
| Override | 覆盖字段 | 说明 |
|---|---|---|
model="gpt-4o" |
model.name |
替换模型 |
temperature=0.5 |
model.temperature |
替换温度 |
max_steps=30 |
react.maxSteps |
替换最大步数 |
tools={"search": fn} |
MCP 工具实现 | 注入自定义工具函数 |
memory_store={"key": "val"} |
Memory 初始值 | 注入初始记忆 |
_confirm_callback=fn |
ToolGateway 确认回调 | HIGH-risk 时调用 |
_audit_log_path="audit.jsonl" |
审计日志路径 | 持久化审计记录 |
agent = from_config("config.yml",
model="gpt-4o",
temperature=0.5,
max_steps=30,
tools={"search": my_search_fn},
memory_store={"user_name": "Alice"}
)