@llej/micro-agent
v0.1.1
Published
一个微小而完备、可以方便嵌入到任何地方帮您干活的 AI Agent
Readme
micro-agent
一个微小而完备、可以方便嵌入到任何地方帮您干活的 AI Agent。
特性
- 统一会话 API —
createSession推荐入口,一行代码创建 / 多轮对话 / 流式输出 / 自动释放 - 中间件管道 — Express/Koa 风格洋葱模型,7 个预置中间件(日志/限流/超时/重试/转换/条件)
- 虚拟终端架构 — 基于 CliCommand 的可扩展命令系统,Agent 通过
bash工具调用命令 - 50+ 内置命令 — 文件操作、文本处理、数据处理、网络请求、Shell 执行,支持管道组合
- Skill 系统 — 可扩展的技能配置,每个 Skill 包含命令集 + 系统提示词 + 摘要生成器
- 上下文管理 — 智能压缩长对话历史,命令感知截断策略,自动清理冗余工具结果
- 流式输出 — 完整的 AsyncIterable 流式事件系统(text / thinking / tool_call / tool_result / phase)
- 序列化/反序列化 — 会话状态可 JSON 持久化,支持断点恢复和多实例同步
- 自动恢复执行 —
executeWithRecovery内置指数退避重试,自动识别限流/网络/超时错误 - RPC 远程执行 — 跨设备命令注册与 HTTP 调用,Agent 和 Bash 可运行在不同机器上
- SubAgent 并行 — 主 Agent 可启动独立子 Agent 处理任务,节省上下文不被污染
- 异步任务调度 — 后台任务管理,FIFO 队列 + 并发控制 + 自动淘汰
- 双端运行 — 浏览器和 Node.js 同一套代码
- 零依赖核心 — Agent 核心不依赖任何框架,可直接嵌入任意 JS 环境
快速开始
浏览器(Web Component)
<!-- 最简用法 — 一行代码嵌入 AI 对话 -->
<micro-agent api-key="sk-xxx"></micro-agent>
<!-- 完整配置 -->
<micro-agent
api-key="sk-xxx"
model="gpt-4o"
theme="dark"
placeholder="输入问题..."
height="500px"
></micro-agent>
<!-- 自定义 slot 插槽 -->
<micro-agent api-key="sk-xxx">
<div slot="header">智能助手</div>
<div slot="footer">Powered by micro-agent</div>
</micro-agent>
<!-- 只读模式 -->
<micro-agent api-key="sk-xxx" disabled></micro-agent>
<script type="module">
import 'micro-agent/web-component';
const el = document.querySelector('micro-agent');
// JS API — 发送消息并获取回复
const reply = await el.ask('你好');
// JS API — 监听事件
el.addEventListener('message', (e) => {
console.log(e.detail.type, e.detail.content);
});
// JS API — 批量配置
el.configure({ apiKey: 'sk-xxx', theme: 'dark', height: '600px' });
</script>Web Component 属性:
| 属性 | 说明 | 默认值 |
|------|------|--------|
| api-key | API 密钥 | — |
| base-url | API 地址 | OpenAI |
| model | 模型名称 | gpt-4o |
| theme | 主题 (light/dark/auto) | auto |
| placeholder | 输入框占位符 | 输入消息... |
| height | 组件高度 | 400px |
| system-prompt | 自定义系统提示词 | — |
| disabled | 禁用交互(只读) | — |
| auto-focus | 自动聚焦输入框 | 开启 |
| stream-mode | 流式输出模式 | — |
Slot 插槽:
| 名称 | 位置 | 用途 |
|------|------|------|
| header | 顶部 | 自定义标题栏 |
| empty | 消息区空状态 | 自定义空状态提示 |
| status-extra | 状态栏右侧 | 额外状态信息 |
| input-prefix | 输入框左侧 | 前置按钮/图标 |
| input-suffix | 输入框右侧 | 后置按钮/图标 |
| footer | 底部 | 页脚内容 |
Node.js CLI
# 单条消息
OPENAI_API_KEY=sk-xxx pnpm cli "1+1等于几"
# 交互式对话
OPENAI_API_KEY=sk-xxx pnpm cli
# JSON 结构化输出
OPENAI_API_KEY=sk-xxx pnpm cli --json "你好"
# 自定义提示词 + 温度
SYSTEM_PROMPT="你只用法语回复" TEMPERATURE=1.2 pnpm cli "自我介绍"
# 指定工作目录 + 限制可执行的系统命令
OPENAI_API_KEY=sk-xxx pnpm cli --work-dir /path/to/project --allowed-exec "git,node,cat"一行启动(quickStart)
最简嵌入式用法 — 自动管理 Agent 生命周期:
import { quickStart } from 'micro-agent/quick-start';
// 最简用法(自动读取 OPENAI_API_KEY)
const reply = await quickStart('1+1=?');
console.log(reply); // 2
// 带自定义配置
const reply = await quickStart('分析这个项目', {
model: 'gpt-4o-mini',
workDir: './my-project',
onProgress: (e) => {
if (e.type === 'text') process.stdout.write(e.content);
},
});Builder 链式 API
流式配置接口,支持预设和链式调用:
import { AgentBuilder } from 'micro-agent/builder';
// 使用预设一键创建
const agent = AgentBuilder.preset('coder')
.apiKey('sk-xxx')
.workDir('./my-project')
.build();
// 完全自定义链式配置
const agent = AgentBuilder.create()
.apiKey('sk-xxx')
.baseUrl('https://api.example.com/v1')
.model('gpt-4o')
.temperature(0.7)
.maxRounds(20)
.systemPrompt('你是专业助手')
.onEvent((e) => { if (e.type === 'text') console.log(e.content) })
.build();
// 一行问答(自动管理生命周期)
const reply = await AgentBuilder.ask('你好', { apiKey: 'sk-xxx' });内置预设:
| 预设 | 模型 | 温度 | 适用场景 |
|------|------|------|----------|
| coder | gpt-4o | 0.1 | 编程助手(文件操作工作流) |
| chatbot | gpt-4o-mini | 0.7 | 友好对话 |
| analyst | gpt-4o | 0.3 | 数据分析(启用深度思考) |
| translator | gpt-4o-mini | 0.3 | 专业翻译 |
| writer | gpt-4o | 0.8 | 写作助手 |
| tutor | gpt-4o | 0.4 | 学习导师(启用深度思考) |
纯对话模式(零配置,无需终端)
最轻量嵌入方式——只需 API Key,自动使用 NoopTerminal(无文件系统访问):
import { createSession } from 'micro-agent';
// 一行问答(自动创建 + 自动释放)
const reply = await createSession({ apiKey: 'sk-xxx' }).ask('1+1=?');
console.log(reply); // 2
// 翻译服务
const translator = createSession({
apiKey: 'sk-xxx',
model: 'gpt-4o-mini',
systemPrompt: '你是一个专业翻译。只返回翻译结果,不要解释。',
});
const result = await translator.ask('Translate "Hello World" to Chinese');
console.log(result); // 你好世界
translator.dispose();
// 文本分类/情感分析
const classifier = createSession({ apiKey: 'sk-xxx' });
const sentiment = await classifier.ask('这段话的情感是正面还是负面:太棒了!');
classifier.dispose();纯对话模式的特性:
- 无需
terminal参数(自动注入 NoopTerminal) - 无需
workDir/allowedExec(不执行任何命令) - 完整的多轮对话、流式输出、中间件管道、序列化全部可用
- 内存占用最小化(无虚拟 bash 引擎开销)
嵌入式 API(createSession — 推荐入口)
createSession 是推荐的嵌入式入口,统一了生命周期管理和多模式访问:
import { createSession } from 'micro-agent';
// 单次问答(最简,自动管理生命周期)
const reply = await createSession({ apiKey: 'sk-xxx' }).ask('你好');
console.log(reply);
// 多轮对话(上下文保持)
const chat = createSession({ apiKey: 'sk-xxx' });
await chat.ask('我叫小明');
await chat.ask('我叫什么?'); // 记住上下文
chat.dispose(); // 用完释放
// 流式输出
const session = createSession({ apiKey: 'sk-xxx' });
for await (const event of session.chat('写一首诗')) {
if (event.type === 'text') process.stdout.write(event.content);
}
session.dispose();
// 完整结果(含思考过程和统计)
const { text, thinking, stats, toolCalls, durationMs } =
await session.sendFull('解释量子计算');
session.dispose();
// 序列化 / 反序列化(断点恢复)
const snapshot = session.serialize();
fs.writeFileSync('session.json', JSON.stringify(snapshot));
// ... 后续请求恢复 ...
const raw = JSON.parse(fs.readFileSync('session.json', 'utf-8'));
const restored = AgentSession.deserialize(raw, { llm: myLLM });
await restored.ask('继续之前的话题');SessionOptions 配置项:
| 选项 | 类型 | 说明 |
|------|------|------|
| apiKey | string | API Key(不传则读 OPENAI_API_KEY 环境变量) |
| model | string | 模型名称 |
| baseUrl | string | API 基础地址 |
| llm | LLMCaller | 自定义 LLM 调用函数(传入后忽略 apiKey/model/baseUrl) |
| maxRounds | number | 最大循环轮数 |
| systemPrompt | string | 自定义系统提示词 |
| temperature | number | LLM 温度 [0, 2] |
| terminal | ITerminalInstance | 终端实例(不传自动使用 NoopTerminal) |
| skills | SkillConfig[] | 自定义技能 |
| memoryStore | MemoryStore | 记忆存储 |
| contextTransform | (msgs) => msgs | 上下文转换钩子 |
核心方法:
| 方法 | 说明 |
|------|------|
| session.ask(msg) | 简单问答,返回文本 |
| session.run(msg) | 完整执行,返回 RunResult(含 thinking/stats/toolCalls) |
| session.chat(msg) | 流式对话,返回 AsyncIterable<ChatEvent> |
| session.streamText(msg) | 纯文本流式输出(自动拼接 text 事件) |
| session.streamEvents(msg) | 分类收集流式事件(按 text/thinking/toolCalls/errors 分组) |
| session.chatSingle(msg) | 单轮无状态对话(不影响多轮上下文) |
| session.batch(tasks) | 批量并行执行多个独立任务 |
| session.serialize() | 序列化会话状态(可 JSON 持久化) |
| AgentSession.deserialize(data, opts) | 从快照恢复会话(静态方法) |
| session.reset() | 重置会话(清空上下文) |
| session.dispose() | 释放资源(多次调用安全) |
中间件管道
Session 支持类似 Express/Koa 的中间件模式,可在请求处理链中注入自定义逻辑:
import { createSession, loggingMiddleware, rateLimitMiddleware } from 'micro-agent';
const session = createSession({ apiKey: 'sk-xxx' })
// 日志中间件:记录每次请求和响应
.use(loggingMiddleware({ prefix: '[MY-APP]' }))
// 限流中间件:每分钟最多 10 次
.use(rateLimitMiddleware({ maxRequests: 10, windowMs: 60_000 }))
// 自定义中间件:修改消息或转换输出
.use(async (ctx, next) => {
console.log('before:', ctx.message);
const result = await next();
console.log('after:', result.text);
return { ...result, text: result.text.toUpperCase() };
});
const reply = await session.ask('hello'); // 经过所有中间件处理
session.dispose();内置中间件:
| 中间件 | 说明 |
|--------|------|
| loggingMiddleware | 记录请求/响应日志 |
| rateLimitMiddleware | 滑动窗口限流 |
| timeoutMiddleware | 单次请求超时控制 |
| retryMiddleware | 自动重试失败请求 |
| transformMiddleware | 输入消息转换 |
| conditionalMiddleware | 条件执行目标中间件 |
| compose(mws) | 组合多个中间件为一个 |
嵌入式 API(createMicroAgent)
底层工厂函数,需要完全自定义时使用:
import { createMicroAgent } from 'micro-agent';
const agent = createMicroAgent({
apiKey: 'sk-...',
model: 'gpt-4o',
});
for await (const event of agent.chat('今天天气怎么样')) {
if (event.type === 'text') process.stdout.write(event.content);
}
const answer = await agent.ask('1+1等于几?');
agent.reset();
agent.destroy();HTTP Server
零依赖 HTTP 服务端,提供 SSE 流式和 REST API:
import { createAgentServer } from 'micro-agent/server';
const server = createAgentServer({
port: 3000,
apiKey: 'sk-xxx',
model: 'gpt-4o',
});
// POST /chat — 发送消息(SSE 流式响应)
// POST /ask — 简单问答(JSON 响应)
// GET /status — 获取状态
// POST /reset — 重置会话
// GET /messages — 获取历史消息核心 API
createMicroAgent(config)
一站式创建 Agent(推荐),自动创建 LLM 适配器和默认技能。
const agent = createMicroAgent({
apiKey: 'sk-...', // API Key(必须)
baseUrl: '...', // API 地址(默认 OpenAI)
model: 'gpt-4o', // 模型名称
workDir: '/path/to/dir', // 工作目录(Node.js 环境下文件操作的基础路径)
allowedExec: 'git,ls,cat', // exec 命令白名单(逗号分隔,为空则允许全部)
systemPrompt: '...', // 追加到默认系统提示词之后
temperature: 0.7, // LLM 温度
maxTokens: 4096, // 最大输出 token
maxRounds: 80, // 最大循环轮数
extraCommands: [...], // 额外的自定义命令
rpcCommands: [...], // RPC 远程命令
});createAgent(config)
高级用法,需要自定义 LLM 适配器时使用。
import { createAgent, createOpenAILLMCaller, createDefaultSkill } from 'micro-agent';
const agent = createAgent({
llm: createOpenAILLMCaller({ apiKey, baseUrl, model }),
skills: [createDefaultSkill()],
systemPrompt: '...',
initialEnv: { WORK_DIR: '/path' }, // 注入虚拟环境变量
});返回值方法:
| 方法 | 说明 |
|------|------|
| agent.chat(msg) | 流式对话,返回 AsyncIterable<ChatEvent> |
| agent.ask(msg) | 简单问答,返回完整文本(自动处理工具调用) |
| agent.stop() | 停止当前运行 |
| agent.pause() / agent.resume() | 暂停 / 恢复 |
| agent.reset() | 重置会话(清空上下文) |
| agent.sendUserMessage(msg) | 向运行中的 Agent 发送插话 |
| agent.getStats() | 获取会话统计 |
| agent.getMessages() | 获取上下文消息 |
| agent.exportMarkdown() | 导出对话为 Markdown |
ChatEvent 类型:
type ChatEvent =
| { type: 'text'; content: string }
| { type: 'thinking'; content: string }
| { type: 'tool_call'; name: string; args: string }
| { type: 'tool_result'; name: string; result: string; success: boolean; duration?: number }
| { type: 'status'; status: 'idle' | 'running' | 'paused' | 'done' | 'error' }
| { type: 'usage'; usage: LLMUsage }
| { type: 'log'; entry: LogEntry }
| { type: 'done' };自定义 Skill
const mySkill = {
name: 'database',
description: '数据库操作技能',
commands: [
{
name: 'query',
help: '查询数据库\n用法: query <SQL>',
exec: (args) => db.execute(args.join(' ')),
},
],
systemPrompt: '你是一个数据库助手,使用 query 命令执行 SQL 查询。',
buildSummary: ({ toolCount, successCount }) =>
`已执行 ${toolCount} 次查询(成功 ${successCount})`,
initialMessage: '我可以用 query 命令帮你查询数据库。',
};
const agent = createAgent({
llm: createOpenAILLMCaller({ apiKey: 'sk-...' }),
skills: [mySkill],
});内置命令
核心
| 命令 | 说明 | 示例 |
|------|------|------|
| eval | 执行 JavaScript(支持 async/await) | eval await fetch('url').then(r=>r.json()) |
| fetch | HTTP 请求(支持 GET/POST/PUT) | fetch https://api.github.com/repos/vuejs/core |
| calc | 数学计算 | calc Math.sin(Math.PI / 2) |
| json | JSON 格式化 | json {"a":1} |
| jq | JSON 路径提取 | jq .name data.json |
| time | 获取当前时间 | time |
| help | 查看所有可用命令 | help 或 help grep |
系统(仅 Node.js)
| 命令 | 说明 | 示例 |
|------|------|------|
| exec | 执行系统 shell 命令 | exec git status |
| read | 读取文件内容 | read ./package.json |
| write | 写入文件 | write ./out.txt "Hello" |
| ls | 列出目录 | ls src/ |
| glob | 文件模式匹配 | glob "**/*.ts" |
文本处理
grep sed awk sort head tail wc tr cut uniq nl reverse trim replace split join map xargs yes
数据转换
base64 urlencode urldecode md5 sha len seq sum
支持管道 | 和链式 && / || 组合:eval JSON.stringify({a:1}) | cat
环境变量
| 变量 | 说明 | 默认值 |
|------|------|--------|
| OPENAI_API_KEY | API 密钥 | — |
| OPENAI_BASE_URL | API 地址 | https://api.openai.com/v1 |
| OPENAI_MODEL | 默认模型 | gpt-4o |
| SYSTEM_PROMPT | 自定义系统提示词 | — |
| TEMPERATURE | LLM 温度参数 | 0.7 |
架构
src/agent/
├── session.ts # 统一会话管理 API(createSession 推荐入口)
├── agent-session.ts # 请求驱动型 Agent 会话核心引擎
├── agent-api.ts # 嵌入式 API 工厂(createAgent / createMicroAgent)
├── agent-loop.ts # Agent 循环引擎(callLLMWithRetry + executeToolCall)
├── agent-state.ts # AgentPhase 状态机 + 命令循环检测
├── async-utils.ts # 异步工具(withTimeout / jitterBackoff / isRetryableError)
├── tool-definition.ts # 工具定义构建 + 内置命令工厂
├── system-prompt.ts # System Prompt 模块化构建器
├── context-builder.ts # 上下文构建统一管理层
├── context-compress.ts # 上下文压缩子系统
├── llm-adapters.ts # LLM 适配器(OpenAI 兼容 SSE 流式)
├── micro-agent.ts # 一站式入口(createMicroAgent)
├── quick-start.ts # 快速启动(quickStart / quickChat)
├── builder.ts # Builder 链式配置 API
├── middlewares.ts # 预置中间件工厂(7 个)
├── virtual-bash.ts # 虚拟终端引擎(词法/语法/执行/管道)
├── rpc-server.ts # RPC HTTP 服务端(跨设备命令执行)
├── task-scheduler.ts # 异步任务调度器
├── event-manager.ts # 事件管理器(on/off/once + 延迟注册)
├── errors.ts # 统一错误处理(AgentError 工厂函数)
├── types.ts # 公开类型定义(ChatEvent / RunResult / AgentStats)
├── config-validation.ts # 配置验证
├── server.ts # Node.js HTTP 服务端嵌入
├── web-component.ts # <micro-agent> 自定义元素
├── agent-core.ts # 核心接口 + CliCommand 类型
├── terminal-types.ts # ITerminalView 接口(解除 Vue 隐式依赖)
├── file-tracker.ts # 文件变更追踪
├── memory.ts # 记忆系统(TTL + 重要性评分)
├── context-debug.ts # 上下文 Debug 能力
├── exec-result-store.ts # 执行结果存储与查询
├── multimodal.ts # 多模态支持(图片/文件)
├── subagent.ts # SubAgent 并行能力
├── cli/ # CLI 实现
│ ├── index.ts # CLI 入口 + REPL 循环
│ └── slash-commands/ # 斜杠命令(4 组 → 27 个功能子模块)
│ ├── code/ # 代码操作(git-core/git-ops/ai-assist/exec/file-ops/search/system/analysis/init)
│ ├── info/ # 信息查看(env-sys/file-dir/info-view/network/data-convert/devtools)
│ ├── session/ # 会话管理(session-mgmt/data-persist/search-history/export-copy/exec-pipe/monitor)
│ ├── conversation/ # 对话控制(conv-control/edit-input/info-view/config/quick)
│ ├── types.ts # 命令类型定义
│ ├── shared.ts # ANSI 颜色工具
│ ├── helpers.ts # chatWithStats 等辅助函数
│ └── index.ts # 命令注册表聚合入口
└── __tests__/ # 测试套件(1051 用例)设计理念:
- 依赖倒置 — LLM 通过
LLMCaller接入注入,不绑定任何 SDK - 单一工具 — Agent 只有一个
bash工具,所有命令通过虚拟终端执行 - Skill 扩展 — 新能力通过添加
CliCommand实现,无需改核心代码 - 中间件管道 — Express/Koa 风格洋葱模型,请求/响应全链路可插拔
- 纯函数优先 — 核心逻辑独立可测试,状态机严格转换验证
开发
pnpm tsc # 类型检查(vue-tsc)
pnpm test # 运行测试(1051 用例,vitest)
pnpm dev # 启动开发服务器
pnpm build # 构建生产版本
pnpm tse src/xxx # 执行单个 TypeScript 文件测试
项目包含 1051+ 个测试用例,覆盖核心模块:
src/agent/__tests__/
├── embedded-e2e.test.ts # 嵌入式 E2E 集成测试(79 用例)
├── session-wrapper.test.ts # AgentSession 生命周期测试(31 用例)
├── builder.test.ts # Builder 链式 API + 预设系统
├── quick-start.test.ts # quickStart / quickChat
├── llm-adapter.test.ts # LLM 适配器
├── server.test.ts # HTTP Server 嵌入测试
├── middlewares.test.ts # 中间件管道
├── storage.test.ts # KV 存储系统
├── skills.test.ts # Skill 技能系统
└── ... # 更多测试(35 个文件)