|
|
3 mesi fa | |
|---|---|---|
| .github | 3 mesi fa | |
| agent-lint-action | 3 mesi fa | |
| agentexample | 3 mesi fa | |
| agentpaas | 3 mesi fa | |
| demo | 3 mesi fa | |
| deploy | 3 mesi fa | |
| docs | 3 mesi fa | |
| experiments | 3 mesi fa | |
| lambdagent | 3 mesi fa | |
| lambdagent_guard | 3 mesi fa | |
| link | 3 mesi fa | |
| tests | 3 mesi fa | |
| webui | 3 mesi fa | |
| .dockerignore | 5 mesi fa | |
| .env.template | 3 mesi fa | |
| .gitignore | 3 mesi fa | |
| AGENT_GUIDE.md | 3 mesi fa | |
| CONTRIBUTING.md | 3 mesi fa | |
| Dockerfile | 3 mesi fa | |
| LICENSE | 5 mesi fa | |
| QUICK_START.md | 3 mesi fa | |
| README.md | 3 mesi fa | |
| RELEASE_NOTES.md | 3 mesi fa | |
| agent-config.yml | 3 mesi fa | |
| docker-compose.dev.yml | 3 mesi fa | |
| docker-compose.yml | 3 mesi fa | |
| mkdocs.yml | 5 mesi fa | |
| setup.sh | 5 mesi fa |
lambdagentpaas is a full-stack platform for building, deploying, and serving AI agents defined in a Lambda-calculus DSL. The monorepo contains the language, the backend, the web UI, and ~10 example agents shipped to production.
📖 New here? Start with
docs/INTRODUCTION.mdfor a project-level overview, then read this README for the DSL deep-dive.
This first release prioritizes predictable, single-deployment usage over breadth. The audit (docs/AUDIT_2026-06-05.md) led to a series of subtractions before the first tag:
agentpaas/api/v1/feishu.py + agentpaas/services/feishu.py) — it was an unfinished dev-stage surface that handed process-wide bot-rebind capability to anyone reaching port 8000. Will return in v2 with proper signing.agentexample/agent67/tools/shell_executor.py — LLM-controlled shell with a substring blocklist (RCE-via-prompt-injection). Was never wired into agent67's actual tool registry; the file is gone now too.POST /api/v1/setup/bootstrap only accepts loopback callers. Production deploys behind a reverse proxy should use the agentpaas CLI to create the initial tenant.tenant_id columns and the audit found the scoping mostly correct, v1.0 is intended for single-tenant deployments. Multi-tenant requires the full RBAC + integration-test pass deferred to v2.agentexample/qaagent67lambda ships with /home/67/knowledge/finance paths — treat as a reference implementation requiring path customization, not a turn-key template.Things v1.0 is good for: running the lambdagent DSL kernel, executing YAML-defined agents through the PaaS API, building a knowledge base, using the web UI for chat/run/inspection, deploying via Docker Compose or the native scripts.
Things v1.0 is not yet good for: untrusted multi-tenant SaaS, knowledge-dir-as-attack-surface (no pickle for shared dirs), Feishu integration, or anything that needs the where = [".."] empty-wheel pre-fix tooling.
| Directory | What it is | Run / install |
|---|---|---|
lambdagent/ |
The core DSL — Lambda-calculus agent language, runtime, MCP/A2A/RAG/sandbox. Published as a standalone package (pip install lambdagent). |
pip install -e lambdagent/ |
agentpaas/ |
PaaS layer — REST API, CLI, agent registry, run workspace, knowledge-base management. Wraps lambdagent for multi-tenant serving. |
python3 -m agentpaas serve |
webui/ |
React + Vite frontend — agent editor, chat, run inspector, knowledge-base UI. | cd webui && npm run dev |
agentexample/ |
Concrete agents in production: physics67 (research pipeline), qaagent67* (RAG QA), travelagent67, pptagent67, research67, agent67, etc. |
See each subdir's README |
lambdagent_guard/ |
Static-analysis & runtime safety layer for compiled Lambda terms. | imported by agentpaas |
deploy/ |
Native install + start/stop scripts (Bash, PowerShell, batch). | bash deploy/install-native.sh && bash deploy/start.sh |
docker-compose.yml (repo root) |
One-click Docker Compose deployment. | docker compose up -d |
demo/ |
End-to-end demos (notebooks, scripts) for talks and onboarding. | — |
docs/ |
Design docs, architecture, audits, comparison studies, INTRODUCTION.md. | — |
tests/ |
175+ pytest suite across DSL, compiler, runtime, cost vectors, algebraic laws. | pytest tests/ |
| Service | URL | Notes |
|---|---|---|
| maritime-qa | http://qa.lambdagent.cn:8080 |
海事法规 RAG |
| 投标-qa | http://qa.lambdagent.cn:8084 |
投标文件 RAG |
| clean-qa | http://qa.lambdagent.cn:8083 |
49 docs / 1527 chunks, BM25 + Graph + Wiki |
The remainder of this README documents the lambdagent/ subpackage — the Lambda-calculus DSL itself. For platform usage (REST API, web UI, deploying your own agent), see docs/INTRODUCTION.md and AGENT_GUIDE.md.
A Python DSL that models AI agents as Lambda calculus terms. Every agent is a function, every composition is function composition, every loop is a Y combinator. This is not a metaphor — it is a formal correspondence backed by a Church encoding verification.
Key insight: An (M, D) pair — a language model M plus a dataset/prompt D — is isomorphic to a Lambda term. LLM + Dataset = Lambda term.
Stats: ~11,300 lines of Python | 81 exported symbols | 4 patents filed
ConversationLam maintains full session persistence so the model never loses context mid-conversation, eliminating the hallucination caused by truncated history.provider: claude-code and use your Claude Code subscription directly. No API key, no billing dashboard, no environment variables.from_config() compiles it into a typed Lambda term tree.# agent-config.yml
model:
provider: claude-code
name: sonnet
# Interactive chat
python3 -m agentpaas chat lambda
# Or run the example agent directly
python3 agentexample/agent67/run.py --claude
No API key required -- uses your Claude Code Max Plan subscription.
| Provider | Config value | API Key needed | Notes |
|---|---|---|---|
| Claude Code (Max Plan) | claude-code |
No | Uses local Claude Code subscription |
| Anthropic API | anthropic |
Yes (ANTHROPIC_API_KEY) |
Direct Claude API access |
| OpenAI-compatible | dashscope / openai / deepseek / zhipu / moonshot |
Yes | Any OpenAI-compatible endpoint |
| Ollama (local) | ollama |
No | Runs models locally, requires Ollama installed |
lambdagent maps 11 core agent constructs to Lambda calculus, giving each one a precise denotational semantics:
| # | Lambda Calculus | DSL Construct | Description |
|---|---|---|---|
| 1 | Lambda abstraction λx.body |
Lam(name, prompt) |
An LLM with a system prompt |
| 2 | Application (f x) |
agent(input) |
Run agent on input |
| 3 | Composition λx.g(f(x)) |
f >> g |
Pipeline / chain |
| 4 | Church conditional IF |
If(cond, then_, else_) |
Conditional branching |
| 5 | Y combinator | Loop(body, condition) |
Iterative reasoning (ReAct) |
| 6 | Church pair PAIR |
Pair(f, g) |
Run two agents, return both |
| 7 | Projections FST / SND |
Fst() / Snd() |
Extract from pair |
| 8 | Primitive / Oracle | Tool(name, fn) |
External tool call |
| 9 | Generalized CASE | Route(classifier, routes) |
Multi-way dispatch |
| 10 | Dependent type {x:T\|P(x)} |
Guard(agent, validator) |
Output validation |
| 11 | Environment extension | Memory(agent, store) |
Persistent context |
Plus Par(f, g) as syntactic sugar for parallel execution (via | operator).
| # | Process Calculus | DSL Construct | Description |
|---|---|---|---|
| 12 | Channel c!(v) / c?(x) |
Channel + Send + Receive |
Inter-agent communication |
| 13 | Shared environment | SharedMemory |
Thread-safe shared state |
| 14 | Y_n(Loop + Route) | GroupChat |
Multi-agent group discussion |
| 15 | Dynamic CASE | Handoff |
Runtime dynamic delegation |
| 16 | Concurrent beta-reduction | AsyncPar |
Thread-pool true parallelism |
| Construct | Description |
|---|---|
Skill |
Named, reusable Lambda term with metadata |
SkillPack |
Collection of related skills (like a package) |
SkillRegistry |
Global singleton registry with search/discover |
SkillAgent |
Auto-discovers and executes best skill |
@skill |
Decorator to create and register skills |
| Module | Protocol | Description |
|---|---|---|
MCPServer/Tool |
MCP 2025-11-25 | Connect to MCP servers (HTTP + stdio) |
A2AServer/Client |
Google A2A v0.3 | Publish/discover/call remote agents |
RAGTool |
-- | TF-IDF or ChromaDB retrieval-augmented gen |
AgenticRAG |
-- | Agent decides when to retrieve |
Checkpoint |
-- | Serialize/restore execution state to JSON |
| Construct | Description |
|---|---|
SandboxedTool |
Tool that runs in isolated subprocess with resource limits |
SandboxPolicy |
Security policy (timeout, memory, network, etc.) |
SecureExecutor |
Auto-wraps all Tools in a term tree with sandbox |
ResourceLimiter |
Applies CPU/memory/fd limits via POSIX resource |
@sandboxed |
One-line decorator for sandboxed tool creation |
YAML Config ──→ from_config() ──→ Lambda Term ──→ Runtime ──→ Result
(compiler) (Term tree) (beta-reduction)
┌── Multi-Agent: Channel, GroupChat, Handoff, AsyncPar
├── Skills: Skill, SkillPack, SkillRegistry, SkillAgent
Lambda Term ──→ Runtime ──→ ├── MCP: MCPServer, MCPTool (HTTP + stdio)
├── A2A: AgentCard, A2AServer, A2AClient
├── RAG: RAGTool, AgenticRAG, SimpleVectorStore
├── Checkpoint: save/load execution state
└── Sandbox: SandboxedTool, SecureExecutor, ResourceLimiter
The system has five layers:
lambdagent.core, lambdagent.primitives, lambdagent.extensions) — the 11 core constructs as Python classes, each a subclass of Term.lambdagent.multiagent) — 5 pi-calculus constructs for inter-agent communication, group chat, dynamic delegation, and true parallelism.lambdagent.skills, lambdagent.mcp_client, lambdagent.a2a, lambdagent.rag, lambdagent.checkpoint) — reusable skills, MCP/A2A protocol integration, retrieval-augmented generation, and state persistence.lambdagent.fromconfig) — parses YAML configs into Lambda term trees. Includes schema validation and lint.lambdagent.agentruntime) — executes Lambda terms via beta-reduction, handling LLM calls, MCP tool invocation, memory, and tracing. 支持双执行引擎切换 (recursive/cek/adaptive), 通过 runtime.engine 配置。CEK 引擎提供逐步成本监控、暂停/恢复和循环检测能力。pip install lambdagent
For LLM provider support:
pip install lambdagent[anthropic] # Anthropic Claude
pip install lambdagent[openai] # OpenAI-compatible (Dashscope, etc.)
from lambdagent import Lam, Compose, Loop, Tool, Memory
# A single agent is a Lambda abstraction
writer = Lam("writer", "You are a technical writer. Write clear documentation.")
# Composition is function composition
reviewer = Lam("reviewer", "Review the text for clarity and correctness.")
pipeline = writer >> reviewer # = lambda x. reviewer(writer(x))
# ReAct agent is a Y combinator
# `condition` takes (result, step_index) and returns bool;
# `max_steps` is the unfolding bound (default 10).
searcher = Tool("search", lambda q: web_search(q))
researcher = Loop(
body=Lam("think", "Analyze the question. Use search if needed."),
condition=lambda result, step: "DONE" in result,
max_steps=10,
)
# Add memory for persistent context.
# `store` is an optional dict of {key: value} pre-loaded into the agent's
# environment; further entries are added via `agent.remember(k, v)`.
agent = Memory(researcher, store={"recent_topic": "LLM agents"})
# Execute = beta-reduction
result = agent("What are the latest advances in LLM agents?")
agentId: research-assistant
name: ResearchAssistant
type: react
systemPrompt: |
You are a research assistant. Search for information,
analyze it, and produce a comprehensive report.
model:
provider: dashscope
name: qwen3-max-2026-01-23
temperature: 0.7
maxTokens: 4096
react:
maxSteps: 15
runtime:
engine: recursive # recursive | cek | adaptive
memory:
enabled: true
strategy: local
size: 20
mcp:
onlineTool:
example-mcp-server:
- everything_get_sum
localTools:
- terminate
from lambdagent import from_config
agent = from_config("agent-config.yml")
result = agent("Summarize recent progress in AI safety research")
from lambdagent import Lam, GroupChat, SharedMemory
researcher = Lam("researcher", "You are a researcher. Find evidence.")
critic = Lam("critic", "You are a critic. Challenge weak arguments.")
synthesizer = Lam("synthesizer", "You synthesize the discussion into conclusions.")
chat = GroupChat(
agents=[researcher, critic, synthesizer],
max_rounds=6,
scheduler="round_robin",
)
result = chat("Should we invest in quantum computing?")
from lambdagent import mcp_tools, mcp_tool
# Get all tools from an MCP server
tools = mcp_tools("http://localhost:3000/mcp")
# Or get a single tool
search = mcp_tool("http://localhost:3000/mcp", "search")
result = search({"query": "AI agents"})
from lambdagent import create_rag, AgenticRAG, Lam
rag = create_rag(["Python is a programming language.", "Lambda calculus is..."])
agent = Lam("qa", "Answer questions using the provided context.")
agentic = AgenticRAG(agent, rag, decider=lambda x: "?" in x)
result = agentic("What is Lambda calculus?")
from lambdagent import Context, save_context, load_context
ctx = Context()
agent("long running task", ctx)
save_context(ctx, "checkpoint.json", last_input="long running task")
# Later, resume:
ctx = load_context("checkpoint.json")
agent("continue from here", ctx)
from lambdagent import SandboxedTool, SandboxPolicy, SecureExecutor, sandboxed
# One-line decorator
@sandboxed(timeout=10, memory_mb=128)
def risky_calc(x):
return eval(x)
# Or explicit construction with policy presets
tool = SandboxedTool("calc", lambda x: eval(x), policy=SandboxPolicy.strict())
# Secure an entire term tree — wraps all Tools in sandboxes
secure_tree = SecureExecutor(policy=SandboxPolicy.default()).sandbox_all_tools(agent)
python experiments/nl2agent.py "Build a research assistant that can search the web and write reports, up to 20 steps, with memory"
Or programmatically:
from experiments.nl2agent import one_sentence_to_agent
one_sentence_to_agent(
"Build a code review pipeline: check security, then style, then performance",
user_input="Review this Python function: def login(u, p): ...",
)
# Compile YAML to Lambda term (no execution)
lambdagent compile agent-config.yml
# Compile and execute
lambdagent run agent-config.yml "Write a quicksort in Python"
# Interactive REPL
lambdagent repl agent-config.yml
# Static analysis (lint)
lambdagent lint agent-config.yml
# Export pure Lambda expression
lambdagent lambda agent-config.yml
# Unix pipes work (composition = pipe)
echo "Hello world" | lambdagent run agent-config.yml -
Term — Abstract base class. All constructs are Terms.Context — Evaluation environment with beta-reduction tracing.Lam(name, prompt) — Lambda abstraction. Wraps an LLM call.Compose(f, g) / f >> g — Function composition.If(cond, then_, else_) — Church conditional.Loop(body, condition) — Y combinator with termination.Pair(f, g) / Par(f, g) — Church pair / parallel execution.Fst() / Snd() — Pair projections.Tool(name, fn) — External oracle (MCP tool, shell command, etc.).Route(classifier, routes) — Generalized Church boolean (CASE).Guard(agent, validator) — Dependent type / output validation.Memory(agent, store) — Environment extension with persistent state.Channel(name, capacity) — pi-calculus channel for inter-agent communication.Send(agent, channel) — Send agent output to channel.Receive(channel, handler) — Receive from channel, optionally process with handler.SharedMemory(store, append_only) — Thread-safe shared state across agents.GroupChat(agents, scheduler, max_rounds) — Multi-agent group discussion (Y + Route).Handoff(selector, registry, fallback) — Runtime dynamic delegation.AsyncPar(*agents) — True parallel execution via thread pool.Skill(name, term, description, signature, tags) — Named, reusable Lambda term with metadata.SkillPack(name) — Collection of related skills.SkillRegistry() — Global singleton registry (search, discover, build_route).SkillAgent(classifier, registry) — Auto-discovers and executes best skill.@skill(name, description, tags) — Decorator to create and auto-register skills.MCPServer.http(url) / MCPServer.stdio(command) — Connect to MCP servers.MCPTool(server, tool_name) — MCP tool wrapped as lambdagent Term.mcp_tools(url) — One-liner to get all tools from a server.mcp_tool(url, name) — One-liner to get a single tool.AgentCard — A2A Agent capability description (JSON).A2AServer(agent, port) — Publish agent as A2A HTTP service.A2AClient(url) — Call remote A2A agent as local Term.skill_to_agent_card(skill) — Convert Skill to AgentCard.RAGTool(store, top_k) — Retrieval tool (TF-IDF or ChromaDB).AgenticRAG(agent, rag, decider) — Agent decides when to retrieve.SimpleVectorStore() — Zero-dependency TF-IDF vector store.create_rag(documents, top_k) — One-liner to create RAG tool.Checkpoint(context, shared_data) — Execution state snapshot.CheckpointManager(directory) — Manage multiple checkpoints with auto-cleanup.save_context(ctx, path) / load_context(path) — Save/restore Context.SandboxedTool(name, fn, policy) — Tool running in isolated subprocess with resource limits.SandboxPolicy(timeout, memory_mb, network, ...) — Security policy. Presets: .strict(), .default(), .permissive().SecureExecutor(policy) — Auto-wraps all Tools in a term tree via sandbox_all_tools().ResourceLimiter — Applies POSIX RLIMIT_CPU, RLIMIT_AS, RLIMIT_NOFILE, RLIMIT_NPROC.@sandboxed(timeout, memory_mb, ...) — Decorator for one-line sandboxed tool creation.SandboxViolation, TimeoutViolation, MemoryViolation, OutputViolation.from_config(path_or_dict) — YAML to Lambda term.lint_config(path_or_dict) — Static analysis.to_lambda_expr(path_or_dict) — Export formal Lambda expression.describe_config(path_or_dict) — Human-readable structure description.Runtime — Executes Lambda terms with LLM backends.ReActEngine — Implements the Y combinator loop for ReAct agents.MCPClient — Model Context Protocol tool invocation.TraceStore — Records beta-reduction traces for debugging.lambdagent is grounded in a formal correspondence between agent constructs and Lambda calculus:
If construct uses Church booleans, Pair/Fst/Snd use Church pairs, and Route uses generalized Church numerals.Lam and application together can encode S and K combinators, from which all computable functions follow.Loop is not ad-hoc iteration; it is the Y combinator Y = λf.(λx.f(x x))(λx.f(x x)) with a bounded unfolding (max_iterations) to ensure termination.For the full formal treatment, see docs/INTRODUCTION.md and the design docs under docs/ (Church-encoding proofs, cost-vector semantics, algebraic laws).
Business Source License 1.1 — Copyright (c) 2025 kenny67nju
Non-production use (development, testing, personal projects, academic research) is always permitted. Production use is free for organizations with ≤10 individual users or employees. On 2031-04-05 (the Change Date), the license automatically converts to Apache License 2.0.
For production use beyond the 10-user limit before the Change Date, contact the licensor for a commercial license.
If you use lambdagent in academic work, please cite:
@software{lambdagentpaas2025,
title = {lambdagentpaas: A Lambda Calculus Agent Platform},
author = {kenny67nju},
year = {2025},
url = {https://github.com/kenny67nju/lambdagentpaas},
}
To cite the DSL specifically (the lambdagent/ subpackage, also published standalone on PyPI):
@software{lambdagent2025,
title = {lambdagent: A Lambda Calculus Agent DSL},
author = {kenny67nju},
year = {2025},
url = {https://github.com/kenny67nju/lambdagent},
}