agent-scene-toolkit 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +291 -190
- package/dist/index.cjs +122 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -3
- package/dist/index.d.ts +85 -3
- package/dist/index.js +123 -8
- package/dist/index.js.map +1 -1
- package/package.json +75 -75
package/README.md
CHANGED
|
@@ -1,190 +1,291 @@
|
|
|
1
|
-
# agent-scene-toolkit
|
|
2
|
-
|
|
3
|
-
Lightweight Agent orchestration library built on LangChain.
|
|
4
|
-
|
|
5
|
-
> **3 分钟上手**:定义 Profile → 定义 ToolKit → 创建 Agent → 对话。
|
|
6
|
-
|
|
7
|
-
## 核心概念
|
|
8
|
-
|
|
9
|
-
- **ToolKit**:静态能力包,按领域分组的工具集 + 使用策略 Prompt
|
|
10
|
-
- **AgentProfile**:角色身份,只需定义 name + systemPrompt + model
|
|
11
|
-
- **Scene**:运行时场景,注入动态上下文 + 决定当前可用的 ToolKit
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
import {
|
|
66
|
-
import {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
1
|
+
# agent-scene-toolkit
|
|
2
|
+
|
|
3
|
+
Lightweight Agent orchestration library built on LangChain.
|
|
4
|
+
|
|
5
|
+
> **3 分钟上手**:定义 Profile → 定义 ToolKit → 创建 Agent → 对话。
|
|
6
|
+
|
|
7
|
+
## 核心概念
|
|
8
|
+
|
|
9
|
+
- **ToolKit**:静态能力包,按领域分组的工具集 + 使用策略 Prompt
|
|
10
|
+
- **AgentProfile**:角色身份,只需定义 name + systemPrompt + model
|
|
11
|
+
- **Scene**:运行时场景,注入动态上下文 + 决定当前可用的 ToolKit
|
|
12
|
+
- **KnowledgeBase**:知识库(RAG),纯文本数据 + 语义检索,AI 按需查阅
|
|
13
|
+
|
|
14
|
+
## 📦 Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install agent-scene-toolkit @langchain/core @langchain/langgraph @langchain/openai langchain express
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始 — 最小示例
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { createAgent, defineProfile, defineToolKit, defineScene } from 'agent-scene-toolkit'
|
|
24
|
+
|
|
25
|
+
// 1. 定义能力包
|
|
26
|
+
const canvasToolKit = defineToolKit({
|
|
27
|
+
name: 'canvas',
|
|
28
|
+
tools: [bindElementTool],
|
|
29
|
+
prompt: '画面调整时优先使用 canvas 工具...',
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// 2. 定义角色
|
|
33
|
+
const director = defineProfile({
|
|
34
|
+
name: '导演',
|
|
35
|
+
systemPrompt: '你是一位视频导演...',
|
|
36
|
+
model: 'gpt-4o',
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// 3. 定义场景
|
|
40
|
+
const timelineScene = defineScene({
|
|
41
|
+
name: 'timeline-editing',
|
|
42
|
+
toolkits: ['canvas'],
|
|
43
|
+
prompt: (ctx) => `视频时长: ${ctx.duration}秒`,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// 4. 创建 Agent
|
|
47
|
+
const agent = createAgent({
|
|
48
|
+
toolkits: [canvasToolKit],
|
|
49
|
+
agents: [director],
|
|
50
|
+
scene: timelineScene,
|
|
51
|
+
llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// 5. 发起对话
|
|
55
|
+
for await (const event of agent.chat({ message: '你好', threadId: 'thread-001' })) {
|
|
56
|
+
console.log(event)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 完整配置
|
|
61
|
+
|
|
62
|
+
展示所有可选字段:记忆持久化、滑动窗口、Scene 生命周期回调、动态运行时上下文。
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { createAgent, defineProfile, defineToolKit, defineScene } from 'agent-scene-toolkit'
|
|
66
|
+
import { MemorySaver } from '@langchain/langgraph'
|
|
67
|
+
|
|
68
|
+
const agent = createAgent({
|
|
69
|
+
toolkits: [canvasToolKit, aiToolKit],
|
|
70
|
+
agents: [director],
|
|
71
|
+
scene: defineScene({
|
|
72
|
+
name: 'timeline-editing',
|
|
73
|
+
toolkits: ['canvas', 'ai'],
|
|
74
|
+
prompt: (ctx) => `用户在时间线编辑器,视频时长: ${ctx.duration}秒`,
|
|
75
|
+
onToolEnd: (toolName, result) => { // 工具调用完成回调
|
|
76
|
+
if (toolName === 'bindTrack') refreshTimeline()
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
checkpointer: new MemorySaver(), // 记忆持久化(生产环境用 PostgresSaver)
|
|
80
|
+
maxMessages: 50, // 滑动窗口大小(默认 50)
|
|
81
|
+
llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
// 传入 sceneContext 注入动态运行时数据 → scene.prompt(ctx)
|
|
85
|
+
for await (const event of agent.chat({
|
|
86
|
+
message: '帮我调整第3秒的转场',
|
|
87
|
+
threadId: 'thread-001',
|
|
88
|
+
sceneContext: { duration: 30, currentTime: 3 },
|
|
89
|
+
})) {
|
|
90
|
+
switch (event.type) {
|
|
91
|
+
case 'text': process.stdout.write(event.content); break
|
|
92
|
+
case 'tool_start': console.log(`🔧 调用 ${event.toolName}`); break
|
|
93
|
+
case 'tool_end': console.log(`✅ ${event.toolName}`, event.output); break
|
|
94
|
+
case 'error': console.error(`❌ ${event.message}`); break
|
|
95
|
+
case 'done': console.log('\n--- 结束 ---'); break
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 多 Agent 模式
|
|
101
|
+
|
|
102
|
+
配置 `supervisor` 后自动启用 Supervisor 策略,Supervisor 根据任务自动 handoff 给合适的 Worker。
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const director = defineProfile({
|
|
106
|
+
name: '导演',
|
|
107
|
+
systemPrompt: '你是一位视频导演,负责统筹任务分派...',
|
|
108
|
+
model: 'gpt-4o',
|
|
109
|
+
})
|
|
110
|
+
const screenwriter = defineProfile({
|
|
111
|
+
name: '编剧',
|
|
112
|
+
systemPrompt: '你是一位编剧,擅长剧本创作...',
|
|
113
|
+
model: 'gpt-4o-mini',
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const agent = createAgent({
|
|
117
|
+
toolkits: [canvasToolKit, aiToolKit],
|
|
118
|
+
agents: [director, screenwriter],
|
|
119
|
+
supervisor: '导演', // ← 指定 Supervisor,自动启用多 Agent
|
|
120
|
+
llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
for await (const event of agent.chat({ message: '写一个30秒的广告脚本', threadId: 'thread-002' })) {
|
|
124
|
+
if (event.type === 'agent') console.log(`🎭 ${event.name} 正在回答`)
|
|
125
|
+
if (event.type === 'handoff') console.log(`🔀 ${event.from} → ${event.to}`)
|
|
126
|
+
if (event.type === 'text') process.stdout.write(event.content)
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## RAG 知识库
|
|
131
|
+
|
|
132
|
+
让 Agent 具备**按需检索外部知识**的能力。只需提供文本数据 + 嵌入模型,AI 自动判断何时检索。
|
|
133
|
+
|
|
134
|
+
### 基本用法
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { createAgent, defineProfile, defineKnowledgeBase } from 'agent-scene-toolkit'
|
|
138
|
+
// 使用者自行选择嵌入模型(本地免费 / OpenAI / 其他)
|
|
139
|
+
import { HuggingFaceTransformersEmbeddings } from '@langchain/community/embeddings/hf_transformers'
|
|
140
|
+
|
|
141
|
+
// 1. 定义知识库
|
|
142
|
+
const faqKB = defineKnowledgeBase({
|
|
143
|
+
name: 'faq',
|
|
144
|
+
description: '产品常见问题,当用户问功能、价格、退款等问题时检索',
|
|
145
|
+
documents: [
|
|
146
|
+
'7天内无理由退款,联系客服即可办理',
|
|
147
|
+
'基础版99元/月,专业版299元/月',
|
|
148
|
+
'支持微信、支付宝、银行卡付款',
|
|
149
|
+
'工作日 9:00-18:00 提供在线客服',
|
|
150
|
+
],
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
// 2. 创建 Agent,传入知识库 + 嵌入模型
|
|
154
|
+
const agent = createAgent({
|
|
155
|
+
agents: [defineProfile({ name: '客服', systemPrompt: '你是产品客服...', model: 'gpt-4o' })],
|
|
156
|
+
knowledgeBases: [faqKB],
|
|
157
|
+
embeddings: new HuggingFaceTransformersEmbeddings({
|
|
158
|
+
model: 'Xenova/all-MiniLM-L6-v2',
|
|
159
|
+
}),
|
|
160
|
+
llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// 3. 对话 — AI 自动判断是否需要检索
|
|
164
|
+
for await (const event of agent.chat({ message: '怎么退款?', threadId: 't-1' })) {
|
|
165
|
+
if (event.type === 'text') process.stdout.write(event.content)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 从数据库 / API 动态加载
|
|
170
|
+
|
|
171
|
+
`documents` 支持异步函数,Agent 创建时自动调用加载数据:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
const dynamicKB = defineKnowledgeBase({
|
|
175
|
+
name: 'product-docs',
|
|
176
|
+
description: '产品操作手册',
|
|
177
|
+
documents: async () => {
|
|
178
|
+
// 从数据库加载
|
|
179
|
+
const rows = await db.query('SELECT content FROM docs')
|
|
180
|
+
return rows.map(r => r.content)
|
|
181
|
+
|
|
182
|
+
// 或从 API 加载
|
|
183
|
+
// const res = await fetch('https://my-api.com/docs')
|
|
184
|
+
// return res.json()
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 多知识库
|
|
190
|
+
|
|
191
|
+
AI 根据每个知识库的 `description` 自动选择检索哪个:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const faqKB = defineKnowledgeBase({
|
|
195
|
+
name: 'faq',
|
|
196
|
+
description: '产品常见问题',
|
|
197
|
+
documents: ['7天内无理由退款', ...],
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const apiDocsKB = defineKnowledgeBase({
|
|
201
|
+
name: 'api-docs',
|
|
202
|
+
description: 'API 接口文档,当用户问技术集成、接口调用时检索',
|
|
203
|
+
documents: ['POST /api/users 创建用户', ...],
|
|
204
|
+
topK: 5, // 返回前 5 条最相关结果(默认 3)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
const agent = createAgent({
|
|
208
|
+
agents: [developer],
|
|
209
|
+
knowledgeBases: [faqKB, apiDocsKB],
|
|
210
|
+
embeddings: new HuggingFaceTransformersEmbeddings({ model: 'Xenova/all-MiniLM-L6-v2' }),
|
|
211
|
+
llm: { ... },
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### SSE 事件
|
|
216
|
+
|
|
217
|
+
知识库检索复用 `tool_start` / `tool_end` 事件,**前端无需任何改动**:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
data: {"type":"tool_start","toolName":"faq","input":{"query":"退款政策"}}
|
|
221
|
+
data: {"type":"tool_end","toolName":"faq","output":"7天内无理由退款,联系客服即可办理"}
|
|
222
|
+
data: {"type":"text","content":"根据我们的政策,7天内可以无理由退款..."}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 嵌入模型选择
|
|
226
|
+
|
|
227
|
+
库不内置嵌入模型,由使用者自行选择:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// 方案 A:本地免费模型(推荐)
|
|
231
|
+
import { HuggingFaceTransformersEmbeddings } from '@langchain/community/embeddings/hf_transformers'
|
|
232
|
+
const embeddings = new HuggingFaceTransformersEmbeddings({ model: 'Xenova/all-MiniLM-L6-v2' })
|
|
233
|
+
|
|
234
|
+
// 方案 B:OpenAI Embeddings(需 API Key)
|
|
235
|
+
import { OpenAIEmbeddings } from '@langchain/openai'
|
|
236
|
+
const embeddings = new OpenAIEmbeddings({ model: 'text-embedding-3-small' })
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Express 集成
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import express from 'express'
|
|
243
|
+
|
|
244
|
+
const app = express()
|
|
245
|
+
app.use(express.json())
|
|
246
|
+
|
|
247
|
+
// 一行挂载 SSE 路由
|
|
248
|
+
app.post('/chat', agent.handleRequest())
|
|
249
|
+
|
|
250
|
+
// 请求体:{ message: string, threadId: string, sceneContext?: Record<string, any> }
|
|
251
|
+
// 响应:SSE 事件流(text/event-stream)
|
|
252
|
+
// data: {"type":"agent","name":"导演"}
|
|
253
|
+
// data: {"type":"text","content":"我来帮你调整"}
|
|
254
|
+
// data: {"type":"tool_start","toolName":"bindTrack","input":{"trackId":"t-01"}}
|
|
255
|
+
// data: {"type":"tool_end","toolName":"bindTrack","output":{"success":true}}
|
|
256
|
+
// data: {"type":"done"}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## 📡 SSE Event Protocol
|
|
260
|
+
|
|
261
|
+
| Event | Trigger | Payload |
|
|
262
|
+
|-------|---------|---------|
|
|
263
|
+
| `text` | LLM 输出文本 token | `{ content: string }` |
|
|
264
|
+
| `tool_start` | 工具调用开始 | `{ toolName: string, input: Record<string, any> }` |
|
|
265
|
+
| `tool_end` | 工具调用结束 | `{ toolName: string, output: any }` |
|
|
266
|
+
| `handoff` | Agent 切换(多 Agent) | `{ from: string, to: string }` |
|
|
267
|
+
| `agent` | 当前回答的 Agent 身份 | `{ name: string }` |
|
|
268
|
+
| `error` | 执行出错 | `{ message: string }` |
|
|
269
|
+
| `done` | 流结束 | `{}` |
|
|
270
|
+
|
|
271
|
+
## 📖 API Documentation
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
npm run docs
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Generates TypeDoc documentation from TSDoc comments.
|
|
278
|
+
|
|
279
|
+
## 🛠️ Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
npm run build # Build ESM + CJS + .d.ts
|
|
283
|
+
npm run dev # Watch mode
|
|
284
|
+
npm run typecheck # Type check
|
|
285
|
+
npm run playground # Launch debug playground
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## 📄 License
|
|
289
|
+
|
|
290
|
+
MIT © [Lootoe](https://github.com/Lootoe)
|
|
291
|
+
|