anginel-ai
v0.1.0
Published
Anginel 是一个 multi-agents runtime 框架,用于快速构建高可扩展的 agents 系统。
Readme
Anginel
Anginel 是一个基于 @earendil-works/pi-ai 构建的 multi-agents runtime 框架,用于快速构建高可扩展的 agents 系统。
核心思想
- 每个 agent 是独立的运行个体,有自己的记忆与状态
- 每个 agent 维护自己的 messages queue
- agent 之间通过消息传递进行通信
- 以 hooks 的形式暴露 agent 的生命周期,方便开发者扩展 agent 生命周期内的行为与状态
Quick Start
npm install anginelimport { Anginel, getModel } from 'anginel';
Anginel.addAgent({
name: 'my-agent',
systemPrompt: '你是一个智能助手,根据用户的问题生成符合要求的回答。',
model: {
default: getModel({
apiKey: 'sk-xxx',
provider: 'openai',
name: 'gpt-4',
}),
lite: getModel({
apiKey: 'sk-xxx',
provider: 'openai',
name: 'gpt-4o-mini',
}),
},
useRespStream: async (chunk, ctx) => {
process.stdout.write(chunk.content);
},
});
Anginel.run();Core Concepts
Agent
每个 agent 是一个独立的运行个体:
interface AgentConfig {
name: string; // 唯一标识
model: { default: Model; lite?: Model }; // 模型配置(lite 用于压缩等轻量任务)
tools?: Tool[]; // 自定义 tools
systemPrompt?: string; // 系统提示词
maxToolCallRounds?: number; // 最大 toolCall 轮次(默认 10)
tokenWarningThreshold?: number; // token 告警阈值(默认 80000)
// ... hooks(见下方 hooks API)
}Message 生命周期
Message 可能来自外部输入或其他 agent 的 send 调用:
pending → processing → processedpending:等待处理processing:正在被 agent 处理processed:已处理完毕,结果写入message.result
状态转换可通过 onMessageStatusChange hook 监听。
Task
Task 将一组相关的 message 组织在一起,包含 task 级别的背景上下文,贯穿整个处理流程。
Ctx(上下文)
ctx 贯穿整个 agent 生命周期,作为最后一个参数传入所有 hooks:
interface Ctx {
state: PiMessage[]; // 运行时记忆(可能被压缩),最终输入 model 的基础
message: Message; // 当前正在处理的消息
task: Task; // 当前 task 及其背景上下文
memory: Memory; // agent 完整记忆,含历史所有消息的处理记录
agentName: string; // 当前 agent 名称
systemPrompt: string; // 系统提示词
metadata: Record<string, unknown>; // 扩展元数据
}Memory
Agent 维护的完整历史记录,包含每次消息处理的所有步骤(modelCall、toolCall、contextCompress)。处理新消息时,与当前 task 相关的 memory 会自动注入 system prompt。
Model
Model 是基于 @earendil-works/pi-ai 的封装,支持 25+ LLM providers:
declare function getModel(config: ModelConfig): Model;
interface ModelConfig {
apiKey?: string;
provider: string; // openai, anthropic, deepseek, ...
name: string; // 模型 ID
baseUrl?: string; // 自定义 endpoint
}
interface Model {
provider: string;
name: string;
stream(ctx: PiContext, options?: ModelOptions): AsyncIterable<ModelChunk>;
send(ctx: PiContext, options?: ModelOptions): Promise<ModelResponse>;
}对于自定义 provider,内部自动通过 registerFauxProvider 注册为 OpenAI-compatible endpoint。
Context 压缩
当 token 超过阈值或 toolCall 轮次过多时,自动触发上下文压缩:
- 默认策略:调用 lite model 对历史对话做摘要,压缩结果作为 assistant message 注入上下文
- Fallback:LLM 调用失败时降级为截断策略(保留 system prompt + 最近消息)
- 自定义压缩:通过
onContextCompresshook 完全接管压缩逻辑 - 压缩判断:通过
shouldCompresshook 自定义是否触发压缩
Hooks API
Anginel 提供完整的 agent 生命周期 hooks:
| Hook | 触发时机 | 签名 |
|------|---------|------|
| useRespStream | 收到响应流片段 | (chunk: ModelChunk, ctx: Ctx) => Promise<void> |
| useResp | 收到完整响应 | (resp: ModelResponse, ctx: Ctx) => Promise<void> |
| beforeMessageProcess | 消息处理前 | (ctx: Ctx) => Promise<Ctx> |
| afterMessageProcess | 消息处理后 | (ctx: Ctx) => Promise<void> |
| onMessageStatusChange | 消息状态变更 | (msg, oldStatus, newStatus, ctx) => Promise<void> |
| onContextCompress | 上下文压缩 | (ctx: Ctx) => Promise<Ctx> |
| shouldCompress | 是否触发压缩 | (ctx, round, tokens, threshold) => boolean |
| onError | 处理出错 | (error: Error, ctx: Ctx) => Promise<void> |
| beforeToolCall | tool 调用前 | (toolCall: ToolCall, ctx: Ctx) => Promise<void> |
| afterToolCall | tool 调用后 | (toolCall: ToolCall, result, ctx: Ctx) => Promise<void> |
ModelChunk
interface ModelChunk {
content: string;
thinking?: string;
toolCallDelta?: {
index: number;
id?: string;
name?: string;
arguments?: string;
};
finishReason?: string;
}ModelResponse
interface ModelResponse {
content: string;
thinking?: string;
toolCalls?: ToolCall[];
finishReason?: string;
usage?: { promptTokens: number; completionTokens: number };
}Built-in Tools
每个 agent 自动拥有 8 个基础 tools(可通过同名 config tool 或 skill 覆盖):
| Tool | 描述 |
|------|------|
| writeFile | 写入文件内容 |
| deleteFile | 删除文件 |
| createFile | 创建新文件 |
| execCommand | 执行 CLI 命令 |
| getHelpfulAgent | 查找指定 agent 是否可用 |
| createAndRunAgent | 动态创建并注册新 agent |
| stopAgent | 停止指定 agent |
| send | 发送消息到指定 agent |
自定义 Tool
使用 Type(TypeBox)定义参数 schema:
import { Type, Anginel } from 'anginel';
Anginel.addAgent({
name: 'coder',
model: { default: getModel({ ... }) },
tools: [{
def: {
name: 'searchCode',
description: 'Search codebase for a pattern',
parameters: Type.Object({
pattern: Type.String({ description: 'Search pattern' }),
path: Type.Optional(Type.String({ description: 'Directory to search' })),
}),
},
execute: async (args, ctx) => {
// 执行搜索逻辑
return { matches: [...] };
},
}],
});Skills
addSkill 用于向所有已注册及未来注册的 agent 注入 tool:
Anginel.addSkill({
def: {
name: 'log',
description: 'Log a message to the console',
parameters: Type.Object({
level: Type.String(),
message: Type.String(),
}),
},
execute: async (args, ctx) => {
console.log(`[${ctx.agentName}] ${args.level}: ${args.message}`);
return { success: true };
},
});同名 tool 优先级:config tool > skill > built-in tool。
Multi-Agent Communication
Agent 之间通过 message 通信。系统自动将其他 agent 列表注入每个 agent 的 system prompt:
Anginel.addAgent({ name: 'planner', model: { default: plannerModel }, systemPrompt: '你负责拆解任务并分派给其他 agent' });
Anginel.addAgent({ name: 'coder', model: { default: coderModel }, systemPrompt: '你负责编写代码' });
Anginel.addAgent({ name: 'reviewer', model: { default: reviewerModel }, systemPrompt: '你负责审阅代码' });
// planner 的 system prompt 中自动追加:
// ## Available Agents
// You can send messages to these agents using the `send` tool:
// - coder
// - reviewer
Anginel.run();使用 send 进行 agent 间通信:
// 在 planner agent 的 tool 或 prompt 中:
// 调用 send tool 将子任务发给 coder
Anginel.send('coder', 'Please implement the login module', taskId, 'planner');Runtime API
interface Runtime {
addAgent(config: AgentConfig): void; // 注册 agent
getModel(config: ModelConfig): Model; // 创建 model 实例
send(target, content, taskId?, from?): Promise<Message>; // 发送消息
addSkill(skill: Skill): void; // 注册全局 skill
stop(name: string): Promise<void>; // 停止 agent
run(): Promise<void>; // 启动 runtime
}导出类型
import type {
AgentConfig, Ctx, Memory, Message, MessageListener, MessageStatus,
Model, ModelChunk, ModelConfig, ModelOptions, ModelResponse,
Runtime, Task, Tool, ToolCall, Skill,
PiMessage, PiUserMessage, PiAssistantMessage, PiToolResultMessage,
PiToolCall, PiTool, PiContext, PiModel,
} from 'anginel';
import { Type } from 'anginel';