Sign in

    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
    Download zip
    Author
    Version
    0.5.1
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    52

    #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/llm 的 ToolRegistry
    • 链式编排:LLMChain —— prompt + provider + memory + output_parser,支持流式输出
    • ReAct Agent:AgentExecutor —— 封装 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)
    • 交互式 CLI:cmd/chat REPL —— 多轮对话、工具调用可视化、斜杠命令(/help /usage /clear)
    • 统一配置:.env / config.json / 环境变量,一处配置全局生效
    • MCP 协议:MCPClient / MCPServer 双向桥接 + sse_transport / stdio_transport 具体 transport

    #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 │ ← 本库(13 个子包,122 个测试) └─────┬─────┘ │ ┌─────┬─────┬─────┼─────┬─────┬─────┬─────┐ │ │ │ │ │ │ │ │ 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.1

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

    #配置(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_KEY、OPENAI_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.1 === 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 示例

    #测试覆盖

    122 个单元测试,三目标(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.mbt9invoke/parse/stream/无parser/无效JSON/缓存/错误日志
    agents/agent_executor_wbtest.mbt8invoke/stream/parse/无parser/invoke_tracked(3个)/e2e tool-call
    core/core_wbtest.mbt11pipe/map/SequentialChain/与wrapper组合
    observability/observability_wbtest.mbt18UsageTracker/CallTrace/TimingTracker/ErrorLogger(七类便捷方法)
    rag/splitter_wbtest.mbt10RecursiveCharacterTextSplitter/MarkdownLoader/VectorStore/MMR
    cache/cache_wbtest.mbt9InMemoryCache 存取/命中统计/上限/清空/key 生成
    async/async_wbtest.mbt1collect_many 空批次边界
    mcp/transport_wbtest.mbt3sse_transport 成功/错误/转发
    mcp/stdio_wbtest.mbt1stdio_transport 命令/请求/超时转发
    mcp/mcp_client_wbtest.mbt4transport 失败/畸形响应/成功静默/端到端

    #工具链

    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 + concrete sse_transport / stdio_transport

    #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 (13 sub-packages, 122 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.1

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

    #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.1 === 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

    122 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.mbt9invoke / parse / stream / no parser / invalid JSON / cache / error logger
    agents/agent_executor_wbtest.mbt8invoke / stream / parse / no parser / invoke_tracked (3) / e2e tool-call
    core/core_wbtest.mbt11pipe / map / SequentialChain / wrapper composition
    observability/observability_wbtest.mbt18UsageTracker / CallTrace / TimingTracker / ErrorLogger (7 convenience methods)
    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
    mcp/transport_wbtest.mbt3sse_transport success / error / forwarding
    mcp/stdio_wbtest.mbt1stdio_transport command / request / timeout forwarding
    mcp/mcp_client_wbtest.mbt4transport failure / malformed response / silent success / end-to-end

    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/core — RunnableWrapper[I, O] struct, the unified composable unit
    • weopqrst/agent/prompts — PromptTemplate, ChatPromptTemplate
    • weopqrst/agent/parsers — OutputParser, JsonOutputParser
    • weopqrst/agent/memory — Memory, BufferMemory, BufferWindowMemory, SummaryMemory
    • weopqrst/agent/tools — Tool trait, bridge to mizchi/llm's ToolRegistry
    • weopqrst/agent/chains — LLMChain
    • weopqrst/agent/agents — AgentExecutor
    • weopqrst/agent/config — ChatConfig, 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