agent

MoonBit version of LangChain core library — type-safe, composable, embeddable AI Agent framework. Depends on mizchi/llm for LLM clients.

ai
agent
llm
langchain
react
tool-calling
memory
prompt
parser
chain
moon add weopqrst/agent@0.5.0
Download zip
Author
Version
0.5.0
License
Apache-2.0
Last updated
3 days ago
Downloads
16

Dependencies

README

#moon-agent

MoonBit 版 LangChain 核心库 —— 类型安全、可组合、可嵌入的 AI Agent 框架

CI mooncakes License Version


#中文说明

#简介

moon-agent 是 MoonBit 生态下的 AI Agent 工程化核心库,定位为 LangChain 核心抽象的 MoonBit 移植版本。在已有底层库(mizchi/llm 提供 LLM 客户端)之上,构建可组合的高层抽象,让 MoonBit 开发者用极少的代码实现 LLM 调用、工具编排、多轮对话、结构化输出解析等 AI Agent 能力。

#特性

#核心抽象

  • Prompt 模板PromptTemplate{variable} 字符串插值)+ ChatPromptTemplate(多角色有序消息,保留插入顺序,支持 few-shot)
  • 输出解析OutputParser trait + JsonOutputParser(容忍 markdown 代码围栏,兼容 CRLF 换行)
  • 对话记忆BufferMemory(全量历史)、BufferWindowMemory(滑动窗口)、SummaryMemory(周期性 LLM 摘要长对话)、BoxedMemory(trait 对象装箱,支持任意 Memory 实现)
  • 工具抽象Tool trait(声明式 name/description/args_schema/run)+ register_into 桥接到 mizchi/llmToolRegistry
  • 链式编排LLMChain —— prompt + provider + memory + output_parser,支持流式输出
  • ReAct AgentAgentExecutor —— 封装 run_agent,集成 memory、output_parser、max_steps、流式输出
  • 可组合单元RunnableWrapper[I,O] —— LCEL 式管道组合(pipe)/ 输出变换(map
  • 多链编排SequentialChain[T] —— 同质多步骤链,顺序执行并传递输出
  • 可观测性UsageTracker(Token 统计 + 成本估算)、CallTrace(Agent 决策链路追踪)、TimingTracker(工具耗时统计)
  • RAG 检索Document + MarkdownLoader + RecursiveCharacterTextSplitter + VectorStore + Embedder + Retriever + MMR 多样性检索 + RetrievalTool(Agent 工具版 RAG)
  • 交互式 CLIcmd/chat REPL —— 多轮对话、工具调用可视化、斜杠命令(/help /usage /clear
  • 统一配置.env / config.json / 环境变量,一处配置全局生效
  • MCP 协议MCPClient / MCPServer 双向桥接

#V0.2 / V0.3 新增

版本功能
V0.2-1LLMChain::with_output_parser + invoke_and_parse —— 输出解析接入
V0.2-2LLMChain::invoke_stream —— 流式输出回调
V0.2-3RunnableWrapper::pipe / map + LLMChain::as_runnable —— LCEL 式组合
V0.2-4SummaryMemory —— 周期性 LLM 摘要长对话
V0.2-5AgentExecutor::invoke_stream —— Agent 流式输出
V0.3-1AgentExecutor::with_output_parser + invoke_and_parse —— Agent 输出解析
V0.3-2SequentialChain[T] —— 多链编排

#架构

你的 MoonBit 应用 │ ┌─────┴─────┐ │ moon-agent │ ← 本库(12 个子包,109 个测试) └─────┬─────┘ │ ┌─────┬─────┬─────┼─────┬─────┬─────┬─────┐ │ │ │ │ │ │ │ │ core prompts parsers memory tools chains agents │ │ │ │ │ │ │ └─────┴─────┴─────┴──┬──┴─────┴─────┘ │ config / observability / mcp / rag │ mizchi/llm ← LLM 客户端底层(Provider、流式、tool_call) │ OpenAI / Anthropic / ...

#安装

moon add weopqrst/agent@0.5.0

这会在 moon.mod 中添加:
import { "mizchi/llm@0.3.1", "weopqrst/agent@0.5.0", }

#配置(v0.9 新增,v0.10 扩展)

推荐使用 .env 文件(参考 .env.example):

OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://api.deepseek.com OPENAI_MODEL=deepseek-chat

或使用 config.json

{ "api_key": "sk-...", "base_url": "https://api.deepseek.com", "model": "deepseek-chat", "max_tokens": 4096, "system_prompt": "" }

或设置环境变量:OPENAI_API_KEYOPENAI_BASE_URL(可选)、OPENAI_MODEL(可选)。

@config.load_config() 按以下顺序查找:
  1. ./.env(推荐)
  2. ./config.json
  3. ../.env(子目录如 cmd/chat 运行时)
  4. ../config.json
  5. 环境变量回退

#交互式 REPL(cmd/chat)

配置好 API 后,直接启动多轮对话 REPL:

moon run cmd/chat --target js

=== moon-agent chat v0.5.0 === Endpoint: https://api.deepseek.com | Model: deepseek-chat Type /help for commands, /exit to quit You: 15 * 23 + 100 等于多少? Agent: [→ calling tool: calculator] input: {"expression":"15*23+100"} [← calculator result] 445 445 Tokens: in=128 out=24 total=152 | Est. cost: $0.000

REPL 斜杠命令:

命令功能
/exit, /quit退出
/help查看命令
/tools列出内置工具
/clear清除对话记忆
/usage查看 Token 用量和费用
/errors查看错误日志

#快速开始(5 分钟)

最简 LLMChain

///|
fn main {
let api_key = @env.get_env_var("OPENAI_API_KEY")
match api_key {
Some(key) => {
let prompt = @prompts.ChatPromptTemplate::new()
|> @prompts.ChatPromptTemplate::with_system(
"You are a helpful assistant.",
)
|> @prompts.ChatPromptTemplate::with_user(
"What is {topic}? Answer in one sentence.",
)

let model = @openai.OpenAIProvider::new(key)
let provider = @llm.BoxedProvider::new(model)
let chain = @chains.LLMChain::new(provider, prompt)

let vars : Map[String, String] = Map([])
vars["topic"] = "MoonBit"
let answer = chain.invoke(vars)
println(answer)
}
None => println("Please set OPENAI_API_KEY environment variable.")
}
}

带记忆的多轮对话

let chain = @chains.LLMChain::new(provider, prompt)
|> @chains.LLMChain::with_memory(@memory.BufferMemory::new())

chain.invoke({ "input": "我叫张三" })
let answer = chain.invoke({ "input": "我叫什么名字?" }) // → "你叫张三"

LCEL 式组合

///|
let chain = @chains.LLMChain::new(provider, prompt).as_runnable()

///|
let post = @core.RunnableWrapper::new(fn(s : String) -> String {
"Answer length: " + s.length().to_string()
})

///|
let composed = chain.pipe(post)
// 调用 LLM → 取结果长度,一步完成

ReAct Agent + 工具

let registry = @llm_tools.ToolRegistry::new()
@tools.register_into(registry, MyWeatherTool::new(api_key))

let executor = @agents.AgentExecutor::new(provider, registry)
|> @agents.AgentExecutor::with_memory(@memory.BufferMemory::new())
|> @agents.AgentExecutor::with_max_steps(5)

let result = executor.invoke("帮我查一下北京的天气")

流式输出

let chain = @chains.LLMChain::new(provider, prompt)
chain.invoke_stream(vars, fn(delta) {
print(delta) // 实时逐字输出
})

#子包

文件说明
corecore.mbtRunnableWrapper[I,O] 可组合单元 + pipe/map + SequentialChain[T] + RouterChain
promptstemplate.mbt, chat_prompt.mbtPromptTemplate{var} 插值)+ ChatPromptTemplate(多角色有序消息)
parsersparser.mbt, boxed_parser.mbtOutputParser trait + JsonOutputParser + BoxedOutputParser
memorymemory.mbt, buffer_memory.mbt, summary_memory.mbt, boxed_memory.mbtMemory trait + BufferMemory + BufferWindowMemory + SummaryMemory + BoxedMemory
toolstool.mbt, calculator.mbt, datetime.mbt, http.mbt, file_read.mbt, file_write.mbt, shell.mbt, schema.mbt, tool_guard.mbt, tool_middleware.mbt, retrieval_tool.mbtTool trait + 6 个内置工具 + 中间件 + RetrievalTool
chainsllm_chain.mbtLLMChain —— prompt + provider + memory + output_parser + 流式
agentsagent_executor.mbtAgentExecutor —— ReAct Agent 循环 + memory + output_parser + 流式
cachecache.mbt, boxed.mbtLLMCache trait + InMemoryCache + BoxedCache —— 响应缓存
asyncasync.mbt, async_native.mbtcollect_many 并发 LLM 调用(JS 真并发 / 非 JS 串行回退)
configconfig.mbtChatConfig —— .env / config.json / env vars 统一加载
observabilityobservability.mbtUsageTracker + CallTrace + TimingTracker + ErrorLogger
mcpmcp_types.mbt, mcp_client.mbt, mcp_server.mbt, mcp_bridge.mbtMCP 协议双向桥接
ragloader.mbt, splitter.mbt, store.mbt, embedder.mbt, retriever.mbt, boxed.mbtDocument + MarkdownLoader + RecursiveCharacterTextSplitter + VectorStore + Embedder + Retriever
cmd/chatmain.mbt交互式 REPL(多轮对话、工具调用可视化)
examples/quickstartmain.mbt最小 LLMChain 示例
examples/react_agentmain.mbt自定义 Tool + ReAct Agent 示例

#测试覆盖

109 个单元测试,三目标(native / wasm-gc / js)全绿:

测试文件测试数覆盖内容
prompts/template_wbtest.mbt6render / render_one / variables / ChatPromptTemplate 顺序
memory/buffer_memory_wbtest.mbt5BufferMemory 存取/clear / BufferWindowMemory 窗口/副本
memory/summary_memory_wbtest.mbt5摘要触发条件/load_messages/clear/保留最近消息
parsers/parser_wbtest.mbt7strip_code_fence / JsonOutputParser 含/不含围栏 / CRLF
tools/tool_wbtest.mbt19CalculatorTool/DateTimeTool/ToolGuard/ToolMiddleware
chains/llm_chain_wbtest.mbt7invoke/parse/stream/无parser/无效JSON/向后兼容
agents/agent_executor_wbtest.mbt7invoke/stream/parse/无parser/invoke_tracked(3个)
core/core_wbtest.mbt11pipe/map/SequentialChain/与wrapper组合
observability/observability_wbtest.mbt16UsageTracker/CallTrace/TimingTracker/ErrorLogger
rag/splitter_wbtest.mbt10RecursiveCharacterTextSplitter/MarkdownLoader/VectorStore/MMR
cache/cache_wbtest.mbt9InMemoryCache 存取/命中统计/上限/清空/key 生成
async/async_wbtest.mbt1collect_many 空批次边界

#工具链

moon update # 更新 registry 索引 moon fmt --check # 格式检查 moon build --target js # 构建 JS 目标 moon build --target wasm-gc # 构建 wasm-gc 目标 moon test --target js # 运行测试 moon info # 更新生成接口文件

#相关链接


#English Guide

#Overview

moon-agent is an AI Agent engineering core library for the MoonBit ecosystem, positioned as a MoonBit port of LangChain's core abstractions. It builds composable high-level abstractions on top of the mizchi/llm LLM client library, enabling MoonBit developers to implement LLM calls, tool orchestration, multi-turn conversations, and structured output parsing with minimal code.

#Features

#Core Abstractions

  • Prompt Templates: PromptTemplate ({variable} string interpolation) + ChatPromptTemplate (multi-role ordered messages with insertion-order preservation, supports few-shot)
  • Output Parsing: OutputParser trait + JsonOutputParser (tolerates markdown code fences, CRLF-compatible)
  • Conversation Memory: BufferMemory (full history), BufferWindowMemory (sliding window), SummaryMemory (periodic LLM summarization for long conversations), BoxedMemory (trait object boxing for any Memory implementation)
  • Tool Abstraction: Tool trait (declarative name/description/args_schema/run) + register_into bridge to mizchi/llm's ToolRegistry
  • Chain Orchestration: LLMChain — prompt + provider + memory + output_parser, supports streaming
  • ReAct Agent: AgentExecutor — wraps run_agent, integrates memory, output_parser, max_steps, streaming
  • Composable Units: RunnableWrapper[I,O] — LCEL-style pipeline composition (pipe) / output transformation (map)
  • Multi-chain Orchestration: SequentialChain[T] — homogeneous multi-step chains, sequential execution with output passing
  • Observability: UsageTracker (token stats + cost), CallTrace (agent decision trail), TimingTracker (tool latency), ErrorLogger (structured error logging)
  • RAG Retrieval: Document + MarkdownLoader + RecursiveCharacterTextSplitter + VectorStore + Embedder + Retriever + MMR diversity search
  • Interactive CLI: cmd/chat REPL — multi-turn conversations, tool call visualization, slash commands
  • Unified Config: .env / config.json / env vars — configure once, run anywhere
  • MCP Protocol: MCPClient / MCPServer bidirectional bridge

#V0.2 / V0.3 Additions

VersionFeature
V0.2-1LLMChain::with_output_parser + invoke_and_parse — output parsing integration
V0.2-2LLMChain::invoke_stream — streaming output callback
V0.2-3RunnableWrapper::pipe / map + LLMChain::as_runnable — LCEL composition
V0.2-4SummaryMemory — periodic LLM summarization
V0.2-5AgentExecutor::invoke_stream — Agent streaming output
V0.3-1AgentExecutor::with_output_parser + invoke_and_parse — Agent output parsing
V0.3-2SequentialChain[T] — multi-chain orchestration

#Architecture

Your MoonBit Application │ ┌─────┴─────┐ │ moon-agent │ ← This library (12 sub-packages, 109 tests) └─────┬─────┘ │ ┌─────┬─────┬─────┼─────┬─────┬─────┬─────┐ │ │ │ │ │ │ │ │ core prompts parsers memory tools chains agents │ │ │ │ │ │ │ └─────┴─────┴─────┴──┬──┴─────┴─────┘ │ config / observability / mcp / rag │ mizchi/llm ← LLM client (Provider, streaming, tool_call) │ OpenAI / Anthropic / ...

#Installation

moon add weopqrst/agent@0.5.0

This adds to your moon.mod:
import { "mizchi/llm@0.3.1", "weopqrst/agent@0.5.0", }

#Interactive REPL (cmd/chat)

After configuring the API, start the multi-turn chat REPL directly:

moon run cmd/chat --target js

=== moon-agent chat v0.5.0 === Endpoint: https://api.deepseek.com | Model: deepseek-chat Type /help for commands, /exit to quit You: What is 15 * 23 + 100? Agent: [→ calling tool: calculator] input: {"expression":"15*23+100"} [← calculator result] 445 445 Tokens: in=128 out=24 total=152 | Est. cost: $0.000

REPL slash commands:

CommandAction
/exit, /quitExit
/helpShow commands
/toolsList built-in tools
/clearClear conversation memory
/usageShow token usage & cost
/errorsShow error log

#Quickstart (5 minutes)

Minimal LLMChain:

///|
fn main {
let api_key = @env.get_env_var("OPENAI_API_KEY")
match api_key {
Some(key) => {
let prompt = @prompts.ChatPromptTemplate::new()
|> @prompts.ChatPromptTemplate::with_system(
"You are a helpful assistant.",
)
|> @prompts.ChatPromptTemplate::with_user(
"What is {topic}? Answer in one sentence.",
)

let model = @openai.OpenAIProvider::new(key)
let provider = @llm.BoxedProvider::new(model)
let chain = @chains.LLMChain::new(provider, prompt)

let vars : Map[String, String] = Map([])
vars["topic"] = "MoonBit"
let answer = chain.invoke(vars)
println(answer)
}
None => println("Please set OPENAI_API_KEY environment variable.")
}
}

Multi-turn with memory:

let chain = @chains.LLMChain::new(provider, prompt)
|> @chains.LLMChain::with_memory(@memory.BufferMemory::new())

chain.invoke({ "input": "My name is John" })
let answer = chain.invoke({ "input": "What's my name?" }) // → "Your name is John"

LCEL Composition:

///|
let chain = @chains.LLMChain::new(provider, prompt).as_runnable()

///|
let post = @core.RunnableWrapper::new(fn(s : String) -> String {
"Answer length: " + s.length().to_string()
})

///|
let composed = chain.pipe(post)
// Calls LLM → gets result length, in one step

ReAct Agent + Tool:

let registry = @llm_tools.ToolRegistry::new()
@tools.register_into(registry, MyWeatherTool::new(api_key))

let executor = @agents.AgentExecutor::new(provider, registry)
|> @agents.AgentExecutor::with_memory(@memory.BufferMemory::new())
|> @agents.AgentExecutor::with_max_steps(5)

let result = executor.invoke("What's the weather in Beijing?")

Streaming output:

let chain = @chains.LLMChain::new(provider, prompt)
chain.invoke_stream(vars, fn(delta) {
print(delta) // real-time character-by-character output
})

#Sub-packages

PackageFilesDescription
corecore.mbtRunnableWrapper[I,O] composable unit + pipe/map + SequentialChain[T]
promptstemplate.mbt, chat_prompt.mbtPromptTemplate ({var} interpolation) + ChatPromptTemplate (multi-role ordered messages)
parsersparser.mbt, boxed_parser.mbtOutputParser trait + JsonOutputParser + BoxedOutputParser
memorymemory.mbt, buffer_memory.mbt, summary_memory.mbt, boxed_memory.mbtMemory trait + BufferMemory + BufferWindowMemory + SummaryMemory + BoxedMemory
toolstool.mbt + 10 built-in tool filesTool trait + 6 built-in tools + middleware + RetrievalTool
chainsllm_chain.mbtLLMChain — prompt + provider + memory + output_parser + streaming
agentsagent_executor.mbtAgentExecutor — ReAct Agent loop + memory + output_parser + streaming
cachecache.mbt, boxed.mbtLLMCache trait + InMemoryCache + BoxedCache — response caching
asyncasync.mbt, async_native.mbtcollect_many concurrent LLM calls (JS real concurrency / non-JS serial fallback)
configconfig.mbtChatConfig.env / config.json / env vars unified loading
observabilityobservability.mbtUsageTracker + CallTrace + TimingTracker + ErrorLogger
mcp4 filesMCP protocol bidirectional bridge
ragloader.mbt, splitter.mbt, store.mbt, embedder.mbt, retriever.mbt, boxed.mbtDocument + MarkdownLoader + RecursiveCharacterTextSplitter + VectorStore + Embedder + Retriever
cmd/chatmain.mbtInteractive REPL (multi-turn, tool visualization)
examples/quickstartmain.mbtMinimal LLMChain example
examples/react_agentmain.mbtCustom Tool + ReAct Agent example

#Test Coverage

109 unit tests, all green across three targets (native / wasm-gc / js):

Test FileTestsCoverage
prompts/template_wbtest.mbt6render / render_one / variables / ChatPromptTemplate ordering
memory/buffer_memory_wbtest.mbt5BufferMemory save/load/clear / BufferWindowMemory window/copy
memory/summary_memory_wbtest.mbt5Summary trigger conditions / load_messages / clear / recent message preservation
parsers/parser_wbtest.mbt7strip_code_fence / JsonOutputParser with/without fence / CRLF
tools/tool_wbtest.mbt19CalculatorTool / DateTimeTool / ToolGuard / ToolMiddleware
chains/llm_chain_wbtest.mbt7invoke / parse / stream / no parser / invalid JSON / backward compat
agents/agent_executor_wbtest.mbt7invoke / stream / parse / no parser / invoke_tracked (3)
core/core_wbtest.mbt11pipe / map / SequentialChain / wrapper composition
observability/observability_wbtest.mbt16UsageTracker / CallTrace / TimingTracker / ErrorLogger
rag/splitter_wbtest.mbt10RecursiveCharacterTextSplitter / MarkdownLoader / VectorStore / MMR
cache/cache_wbtest.mbt9InMemoryCache save/load / hit stats / limit / clear / key generation
async/async_wbtest.mbt1collect_many empty-batch boundary

#
version

let version : String

moon-agent: MoonBit version of LangChain core library.

A type-safe, composable, embeddable AI Agent framework built on top of mizchi/llm (LLM clients).

This root package provides only metadata. Actual functionality lives in sub-packages:

  • weopqrst/agent/coreRunnableWrapper[I, O] struct, the unified composable unit
  • weopqrst/agent/promptsPromptTemplate, ChatPromptTemplate
  • weopqrst/agent/parsersOutputParser, JsonOutputParser
  • weopqrst/agent/memoryMemory, BufferMemory, BufferWindowMemory, SummaryMemory
  • weopqrst/agent/toolsTool trait, bridge to mizchi/llm's ToolRegistry
  • weopqrst/agent/chainsLLMChain
  • weopqrst/agent/agentsAgentExecutor
  • weopqrst/agent/configChatConfig, unified config loader (config.json or env vars)
  • weopqrst/agent/mcp — MCP Client/Server for ecosystem interop

Quick start

let prompt = @prompts.ChatPromptTemplate::new()
|> @prompts.ChatPromptTemplate::with_system("You are a helpful assistant.")
|> @prompts.ChatPromptTemplate::with_user("What is {topic}?")

let chain = @chains.LLMChain::new(provider, prompt)

let vars : Map[String, String] = Map([])
vars["topic"] = "MoonBit"
let result = chain.invoke(vars)

Configuration

Executables can load API settings via config.json at project root or environment variables. See @config.load_config().

License

Apache-2.0

Source Files