llm-to-agent/docs/design.md
2026-08-21 16:33:06 +08:00

179 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# llm-to-agent 设计文档
## 架构设计
### 核心理念:微内核 + 事件驱动
Agent 的本质是一个循环:**用户输入 → LLM 思考 → 工具调用 → LLM 再思考 → 最终回复**。
本项目的答案是:**内核只做一件事——驱动这个循环**。LLM 调用、工具执行、日志输出等一切能力全部通过事件总线交给外部插件。
### 三层架构
```
┌──────────────────────────────────────────┐
│ Route 层 CLI / Desktop / Web │ ← 只决定 I/O 方式
├──────────────────────────────────────────┤
│ Plugin 层 provider / tool / hook │ ← 可替换的能力单元
├──────────────────────────────────────────┤
│ Core 层 Scheduler + HookBus │ ← 只做循环 + 事件路由
└──────────────────────────────────────────┘
```
### 事件总线
内核循环的每一步都通过 `HookBus` 发出事件,插件注册响应,形成“事件驱动 + 插件化”的架构。
### 插件类型
| 类型 | 职责 | 响应的事件 |
|------|------|-----------|
| `provider` | LLM 提供商适配 | `llm:call``tool:select` |
| `tool` | 工具能力 | `tool:schema``tool:execute` |
| `hook` | 生命周期副作用 | `tool:before``tool:after``run:end` |
| `prompt` | 系统提示词 | 通过配置注入,不响应事件 |
每个插件通过 `manifest.json` 声明元信息(名称、类型、提供的能力、适用平台),由 `PluginManager` 统一加载。
### 三条产品线
```
┌── @llm-to-agent/core ──┐
│ MicroKernel + HookBus │
└────────────────────────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
CLI Desktop Web
(readline) (Electron) (Browser HTTP)
│ │ │
┌───────┴────────┐ ┌──────┴───────┐ ┌──────┴───────┐
│ 本地工具全部 │ │ 同 CLI │ │ 仅远程工具 │
│ console 日志 │ │ IPC 日志 │ │ SSE 日志 │
└────────────────┘ └──────────────┘ └──────────────┘
```
CLI 与 Desktop 共享本地工具文件读写、Shell 执行Web 端通过 `platforms` 字段自动跳过本地工具。
---
## 项目目录设计
### Monorepo 结构pnpm workspace
```
llm-to-agent/
├── pnpm-workspace.yaml
├── package.json ← 根private统一 dev/test 脚本)
├── tsconfig.json
├── docs/ ← 设计文档
│ └── design.md
├── packages/
│ │
│ ├── types/ ← @llm-to-agent/types
│ │ └── src/index.ts ← 所有共享类型Message/ToolDef/PluginManifest/...
│ │
│ ├── core/ ← @llm-to-agent/core
│ │ └── src/
│ │ ├── hook-bus.ts ← 事件总线on/emit/request/collect
│ │ ├── scheduler.ts ← Agent 循环think→tool→think
│ │ ├── context.ts ← 消息上下文管理器
│ │ ├── plugin-manager.ts← 插件加载 + 生命周期
│ │ └── kernel.ts ← MicroKernel 入口(组合以上模块)
│ │
│ ├── plugins-builtin/ ← @llm-to-agent/plugins-builtin
│ │ └── [xxxxx]/ ← 内置插件
│ │
│ ├── cli/ ← @llm-to-agent/cli终端入口
│ │ └── src/index.ts ← readline 循环 + kernel.init([...])
│ │
│ ├── desktop/ ← @llm-to-agent/desktop桌面入口
│ │ └── src/main.ts ← Electron 主进程
│ │
│ ├── server/ ← @llm-to-agent/serverWeb 后端)
│ │ └── src/index.ts ← Express + SSE
│ │
│ ├── web/ ← @llm-to-agent/webWeb 前端)
│ │ └── index.html ← 待实现 React 聊天界面
│ │
│ ├── tests/ ← @llm-to-agent/tests
│ │ └── src/ ← *.test.tsNode 原生 test runner
│ │
│ └── old/ ← @llm-to-agent/old旧代码归档
│ └── src/ ← 重构前的 Agent 实现
```
### 包依赖关系
```
@llm-to-agent/types ← 零依赖,纯类型
↑ ↑
core plugins-builtin
↑ ↑
├───────────┴────────────┐
↓ ↓ ↓
cli desktop server
web
```
### 插件清单规范
每个插件目录包含 `manifest.json`
```json
{
"name": "@agent/tool-file",
"version": "1.0.0",
"type": "tool",
"provides": ["file-read", "file-write"],
"entry": "./index.ts",
"platforms": ["cli", "desktop"]
}
```
| 字段 | 说明 |
|------|------|
| `type` | `provider` / `tool` / `hook` / `prompt` |
| `provides` | 提供的能力标识 |
| `entry` | 入口文件,默认导出 `register(bus: HookBus)` |
| `platforms` | 可用平台PluginManager 加载时自动过滤 |
### 关键类型
```typescript
// 消息
interface Message {
role: 'system' | 'user' | 'assistant' | 'tool';
content: string;
tool_calls?: ToolCall[];
tool_call_id?: string;
}
// 工具定义OpenAI 兼容)
interface ToolDef {
type: 'function';
function: {
name: string;
description: string;
parameters: Record<string, unknown>;
};
}
// 插件清单
interface PluginManifest {
name: string;
version: string;
type: 'provider' | 'tool' | 'hook' | 'prompt';
provides: string | string[];
entry: string;
platforms?: ('cli' | 'desktop' | 'web')[];
}
// 事件总线
type EventName = string;
type Listener = (data: any) => any | Promise<any>;
```