BeamAI - Erlang Agent Framework
July 17, 2026 · View on GitHub
English | 中文
基于 Erlang/OTP 的高性能 AI Agent 应用框架核心库,提供构建 Agent 的基础能力。
项目说明: 本项目是 BeamAI 框架的核心库,提供 Kernel、Filter(含会话记忆)、LLM 客户端和 SimpleAgent 等核心功能。
扩展功能(Tools 库、RAG、A2A/MCP 协议)位于 beamai_extra 扩展项目。
Process Framework 流程编排引擎与存储/快照引擎(原
beamai_process/beamai_memory)已移除,两个仓库均不再包含。
核心功能与扩展
核心项目 (本项目)
提供构建 AI Agent 的基础设施(三大核心职责):
- beamai_core - Kernel 基座:Context、Filter(洋葱式 around 模型)、Tool 的构建与调用
- beamai_agent - SimpleAgent:以 ReAct 为主的 Agent 框架(上下文记忆由 filter-memory 实现、多轮对话、回调、中断/恢复)
- beamai_llm - 统一的 LLM 客户端(支持 OpenAI、Anthropic、DeepSeek、Zhipu、DashScope、Ollama)
扩展项目 (beamai_extra)
基于核心库构建的扩展功能(共四个 app):
- beamai_tools - 文件、Shell、Todo、人机交互工具 + Middleware 系统
- beamai_rag - 检索增强生成
- beamai_mcp - MCP (Model Context Protocol)
- beamai_a2a - A2A (Agent-to-Agent) 协议
特性
-
Kernel/Tool 架构: 语义化的工具注册和调用系统
- 基于 Semantic Kernel 理念的 Kernel 核心(无状态,不记录消息)
- 统一的 Tool 定义和管理
- Filter 洋葱式拦截和安全验证
-
会话记忆 (Memory Filter): 对话历史与 Kernel 解耦
- 每次 invoke 只传单条最新消息,历史由 Memory Filter 按
conversation_id管理 - 可插拔存储后端(ETS / DETS 持久化 / 自定义 behaviour);滑动窗口由 Agent 侧的 memory provider 提供
- 详见 docs/MEMORY.md
- 每次 invoke 只传单条最新消息,历史由 Memory Filter 按
-
统一 LLM 客户端: 6 家 Provider 统一同步/流式
- OpenAI、Anthropic、DeepSeek、Zhipu、DashScope、Ollama
- 多模态输入、Anthropic 缓存/Web Search/引用、速率限制头、Retry-After 重试、统一错误结构
-
Output Parser: 结构化输出
- JSON/XML/CSV 解析
- 自动重试机制
快速开始
1. 启动 Shell
export ZHIPU_API_KEY=your_key_here
rebar3 shell
2. LLM 调用
%% 创建 LLM 配置
LLM = beamai_chat_completion:create(zhipu, #{
model => <<"glm-4.7">>,
api_key => list_to_binary(os:getenv("ZHIPU_API_KEY"))
}),
%% 发送聊天请求
{ok, Response} = beamai_chat_completion:chat(LLM, [
{role, user, content, <<"你好!"/utf8>>}
]),
3. Kernel + Tool(工具注册)
%% 创建 Kernel
Kernel = beamai_kernel:new(),
%% 定义 Tool
SearchTool = #{
name => <<"search">>,
description => <<"搜索信息"/utf8>>,
parameters => #{
<<"query">> => #{type => string, required => true, description => <<"搜索关键词"/utf8>>}
},
handler => fun(#{<<"query">> := Query}, _Context) ->
{ok, <<"搜索结果: ", Query/binary>>}
end
},
%% 注册工具
Kernel1 = beamai_kernel:add_tool(Kernel, SearchTool),
%% 调用单个工具
{ok, Result, _NewCtx} = beamai_kernel:invoke_tool(Kernel1, <<"search">>, #{
<<"query">> => <<"Erlang"/utf8>>
}, beamai_context:new()).
4. Filter(洋葱式拦截)
%% 一个 filter 含 3 个可选 around hook(around_chat/around_tool/around_turn)
%% 每个 around 用单个闭包 fun(Req, FCtx, Next) -> Resp 包裹同一次调用,
%% 前置/后置同处一处,不调 Next 即短路。
%% filter 在构建 kernel 时一次性给出,注册顺序即层序(列表靠前 = 外层)。
%% 一个 around_tool:参数校验(短路)+ 结果翻倍
ValidateTransform = beamai:filter(<<"validate_transform">>, #{
around_tool => fun(#{args := #{a := A}, context := Ctx} = Req, _FCtx, Next) ->
case A > 1000 of
true ->
%% 参数超限:不调 Next,短路跳过工具执行
#{result => {error, <<"a exceeds limit">>}, context => Ctx};
false ->
%% 正常:进入内层后把结果翻倍
#{result := Result} = Resp = Next(Req),
case is_number(Result) of
true -> Resp#{result => Result * 2};
false -> Resp
end
end
end
}),
K0 = beamai:kernel(#{}, [ValidateTransform]),
K1 = beamai:add_tool(K0, beamai:tool(<<"add">>,
fun(#{a := A, b := B}) -> {ok, A + B} end,
#{description => <<"Add two numbers">>,
parameters => #{
a => #{type => integer, required => true},
b => #{type => integer, required => true}
}})),
%% 调用(3 + 5 = 8,后置翻倍后 = 16)
{ok, 16, _} = beamai:invoke_tool(K1, <<"add">>, #{a => 3, b => 5}, beamai:context()).
详见 Filter 文档。
流程编排 / 状态快照 已迁移到 beamai_extra(Process Framework、存储/快照引擎)。
5. Output Parser(结构化输出)
%% 创建 JSON 解析器
Parser = beamai_output_parser:json(#{
schema => #{
type => object,
properties => #{
<<"title">> => #{type => string},
<<"count">> => #{type => integer}
},
required => [<<"title">>, <<"count">>]
}
}),
%% 解析 LLM 响应
{ok, Parsed} = beamai_output_parser:parse(Parser, LLMResponse).
架构
应用结构
apps/
├── beamai_core/ # 核心框架
│ ├── Kernel # beamai_kernel, beamai_tool, beamai_context,
│ │ # beamai_filter, beamai_prompt, beamai_result
│ ├── Memory Filter # beamai_memory_filter(会话历史按 conversation_id 管理)
│ ├── HTTP # beamai_http, beamai_http_gun, beamai_http_pool
│ ├── Behaviours # beamai_chat_behaviour, beamai_http_behaviour
│ └── Utils # beamai_id, beamai_jsonrpc, beamai_sse, beamai_utils
│
├── beamai_llm/ # LLM 客户端
│ ├── Chat # beamai_chat_completion, beamai_llm_error
│ ├── Parser # beamai_output_parser, beamai_parser_json
│ ├── Adapters # beamai_llm_message_adapter, beamai_llm_response_parser, beamai_llm_tool_adapter
│ └── Providers # OpenAI, Anthropic, DeepSeek, Zhipu, DashScope, Ollama
│
└── beamai_agent/ # SimpleAgent(ReAct)
└── Agent # beamai_agent, beamai_agent_state, beamai_agent_tool_loop,
# beamai_agent_callbacks, beamai_agent_interrupt
流程编排引擎与存储/快照引擎(原
beamai_process/beamai_memory)已移除, beamai 与 beamai_extra 两个仓库均不再包含。
依赖关系
┌───────────────────────┐ ┌───────────────────────┐
│ Agent 层 │ │ LLM 层 │
│ (beamai_agent) │ │ (beamai_llm) │
└───────────┬───────────┘ └───────────┬───────────┘
│ │
┌───────────┴─────────────────────────┴───────────┐
│ 核心层 │
│ (beamai_core) │
└─────────────────────────────────────────────────┘
beamai_core 通过 Behaviour 接口和
{Module, Ref}动态分发模式解耦, 不依赖上层应用。beamai_llm 和 beamai_agent 平级,互不依赖。
核心概念
1. Kernel 架构
Kernel 是 BeamAI 的核心抽象,管理 Tool 的注册与调用:
%% 创建 Kernel 实例
Kernel = beamai_kernel:new(),
%% 从 Tool 模块加载工具
Kernel1 = beamai_kernel:add_tool_module(Kernel, beamai_tool_file),
%% 或添加单个工具
Tool = #{
name => <<"read_file">>,
description => <<"读取文件内容"/utf8>>,
parameters => #{
<<"path">> => #{type => string, required => true}
},
handler => fun(#{<<"path">> := Path}, _Ctx) ->
file:read_file(Path)
end
},
Kernel2 = beamai_kernel:add_tool(Kernel1, Tool),
%% 调用注册的工具
{ok, Result, _NewCtx} = beamai_kernel:invoke_tool(Kernel2, <<"read_file">>, #{
<<"path">> => <<"/tmp/test.txt">>
}, beamai_context:new()).
2. 会话记忆 (Memory Filter)
Kernel 本身无状态、不记录消息;多轮对话历史由 Memory Filter(beamai_memory_filter)以 conversation_id 为单位管理。每次 invoke 只携带单条最新消息,filter 负责注入历史与持久化增量。
- 可插拔存储后端(ETS / DETS 持久化 / 自定义 behaviour);滑动窗口由 Agent 侧的 memory provider 提供
- SimpleAgent 的跨轮记忆即基于此实现
- 详见 docs/MEMORY.md
配置
LLM 配置
LLM 配置使用 beamai_chat_completion:create/2 创建:
%% 创建 LLM 配置
LLM = beamai_chat_completion:create(zhipu, #{
model => <<"glm-4.7">>,
api_key => list_to_binary(os:getenv("ZHIPU_API_KEY")),
temperature => 0.7
}).
%% 发送请求
{ok, Response} = beamai_chat_completion:chat(LLM, [
{role, user, content, <<"你好"/utf8>>}
]).
支持的 Provider:
| Provider | 模块 | API 模式 | 说明 |
|---|---|---|---|
anthropic | beamai_llm_provider_anthropic | Anthropic | Anthropic Claude API |
openai | beamai_llm_provider_openai | OpenAI | OpenAI API |
deepseek | beamai_llm_provider_deepseek | OpenAI 兼容 | DeepSeek API |
zhipu | beamai_llm_provider_zhipu | OpenAI 兼容 | 智谱 AI (GLM 系列) |
dashscope | beamai_llm_provider_dashscope | DashScope 原生 | 阿里云百炼 (通义千问系列) |
ollama | beamai_llm_provider_ollama | OpenAI 兼容 | Ollama 本地模型 |
HTTP 后端配置
BeamAI 的 HTTP 后端经 beamai_http_behaviour 可插拔,内置实现只有 Gun
(支持 HTTP/2),即默认后端,无需配置。
%% 在 sys.config 中配置(可选);Gun 后端有三个用途分池
%% (短请求/SSE 流式/异步长轮询),只需配置要覆盖的池和键。
%% 遗留 http_pool 键仍兼容。详见 docs/HTTP.md
{beamai_core, [
{http_backend, beamai_http_gun},
{http_pools, #{
http_pool_stream => #{max_connections_per_host => 20,
idle_timeout => 120000}
}}
]}.
HTTP 全线走 Gun 后端(beamai_http_gun):支持 HTTP/2、内置三个用途分池
(beamai_http_pool 实例)、TLS 自动使用系统 CA 证书。后端本身经
beamai_http_behaviour 可插拔,但 Gun 是唯一内置实现,无需配置。
文档
核心文档
- docs/API_REFERENCE.md - API 参考文档
- docs/FILTER.md - Filter 洋葱系统文档
- docs/MEMORY.md - 会话记忆(Memory Filter)文档
- docs/HTTP.md - HTTP 连接池(用途分池、配置与调优)
- docs/OUTPUT_PARSER.md - Output Parser 指南
- docs/DEPENDENCIES.md - 依赖关系详解
模块文档
| 模块 | 说明 | 文档 |
|---|---|---|
| beamai_core | 核心框架:Kernel、Context、Filter、Tool、HTTP、Behaviours | README |
| beamai_agent | SimpleAgent:ReAct Agent 框架(多轮对话、回调、中断/恢复) | README |
| beamai_llm | LLM 客户端:6 家 Provider 统一同步/流式;多模态输入、Anthropic 缓存/Web Search/引用、速率限制头、Retry-After 重试、统一错误结构 | README |
运行示例
# 编译
rebar3 compile
# 启动 Shell
rebar3 shell
项目统计
| 指标 | 数量 |
|---|---|
| OTP 应用 | 3 个(beamai_core、beamai_agent、beamai_llm) |
| 源代码模块 | ~73 个 |
| 测试文件 | ~38 个 |
| 单元测试 | ~380 个 |
测试运行
# 运行所有测试
rebar3 eunit
# 运行特定应用的测试
rebar3 eunit --app=beamai_llm
# 运行代码检查
rebar3 dialyzer
性能
- 基于 Erlang/OTP 轻量级进程
- 并发工具调用
- HTTP 连接池(Gun,支持 HTTP/2)
- ETS 高速存储
设计原则
- 简单: 清晰的 API,易于理解
- 模块化: 每个模块职责单一
- 可扩展: Behaviour 设计,易于自定义
- 高性能: 利用 Erlang 并发特性
- 可观测: 完善的日志、追踪、监控
许可证
Apache-2.0
贡献
欢迎提交 Issue 和 Pull Request!