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 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
- ## 📦 Install
14
-
15
- ```bash
16
- npm install agent-scene-toolkit @langchain/core @langchain/langgraph @langchain/openai langchain express
17
- ```
18
-
19
- ## 快速开始 — 最小示例
20
-
21
- ```typescript
22
- import { createAgent, defineProfile, defineToolKit, defineScene } from 'agent-scene-toolkit'
23
-
24
- // 1. 定义能力包
25
- const canvasToolKit = defineToolKit({
26
- name: 'canvas',
27
- tools: [bindElementTool],
28
- prompt: '画面调整时优先使用 canvas 工具...',
29
- })
30
-
31
- // 2. 定义角色
32
- const director = defineProfile({
33
- name: '导演',
34
- systemPrompt: '你是一位视频导演...',
35
- model: 'gpt-4o',
36
- })
37
-
38
- // 3. 定义场景
39
- const timelineScene = defineScene({
40
- name: 'timeline-editing',
41
- toolkits: ['canvas'],
42
- prompt: (ctx) => `视频时长: ${ctx.duration}秒`,
43
- })
44
-
45
- // 4. 创建 Agent
46
- const agent = createAgent({
47
- toolkits: [canvasToolKit],
48
- agents: [director],
49
- scene: timelineScene,
50
- llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
51
- })
52
-
53
- // 5. 发起对话
54
- for await (const event of agent.chat({ message: '你好', threadId: 'thread-001' })) {
55
- console.log(event)
56
- }
57
- ```
58
-
59
- ## 完整配置
60
-
61
- 展示所有可选字段:记忆持久化、滑动窗口、LangFuse 观测、Scene 生命周期回调、动态运行时上下文。
62
-
63
- ```typescript
64
- import { createAgent, defineProfile, defineToolKit, defineScene } from 'agent-scene-toolkit'
65
- import { MemorySaver } from '@langchain/langgraph'
66
- import { CallbackHandler } from 'langfuse-langchain'
67
-
68
- // LangFuse 观测回调(也可通过环境变量 LANGFUSE_SECRET_KEY / LANGFUSE_PUBLIC_KEY / LANGFUSE_HOST 配置)
69
- const langfuseHandler = new CallbackHandler({
70
- secretKey: 'sk-lf-xxx',
71
- publicKey: 'pk-lf-xxx',
72
- baseUrl: 'https://langfuse.your-domain.com', // 自部署地址
73
- })
74
-
75
- const agent = createAgent({
76
- toolkits: [canvasToolKit, aiToolKit],
77
- agents: [director],
78
- scene: defineScene({
79
- name: 'timeline-editing',
80
- toolkits: ['canvas', 'ai'],
81
- prompt: (ctx) => `用户在时间线编辑器,视频时长: ${ctx.duration}秒`,
82
- onToolEnd: (toolName, result) => { // 工具调用完成回调
83
- if (toolName === 'bindTrack') refreshTimeline()
84
- },
85
- }),
86
- checkpointer: new MemorySaver(), // 记忆持久化(生产环境用 PostgresSaver)
87
- maxMessages: 50, // 滑动窗口大小(默认 50)
88
- callbacks: [langfuseHandler], // 透传给 LLM + LangGraph,追踪完整执行链路
89
- llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
90
- })
91
-
92
- // 传入 sceneContext 注入动态运行时数据 → scene.prompt(ctx)
93
- for await (const event of agent.chat({
94
- message: '帮我调整第3秒的转场',
95
- threadId: 'thread-001',
96
- sceneContext: { duration: 30, currentTime: 3 },
97
- })) {
98
- switch (event.type) {
99
- case 'text': process.stdout.write(event.content); break
100
- case 'tool_start': console.log(`🔧 调用 ${event.toolName}`); break
101
- case 'tool_end': console.log(`✅ ${event.toolName}`, event.output); break
102
- case 'error': console.error(`❌ ${event.message}`); break
103
- case 'done': console.log('\n--- 结束 ---'); break
104
- }
105
- }
106
- ```
107
-
108
- ## 多 Agent 模式
109
-
110
- 配置 `supervisor` 后自动启用 Supervisor 策略,Supervisor 根据任务自动 handoff 给合适的 Worker。
111
-
112
- ```typescript
113
- const director = defineProfile({
114
- name: '导演',
115
- systemPrompt: '你是一位视频导演,负责统筹任务分派...',
116
- model: 'gpt-4o',
117
- })
118
- const screenwriter = defineProfile({
119
- name: '编剧',
120
- systemPrompt: '你是一位编剧,擅长剧本创作...',
121
- model: 'gpt-4o-mini',
122
- })
123
-
124
- const agent = createAgent({
125
- toolkits: [canvasToolKit, aiToolKit],
126
- agents: [director, screenwriter],
127
- supervisor: '导演', // ← 指定 Supervisor,自动启用多 Agent
128
- llm: { baseURL: 'https://api.bltcy.ai', apiKey: 'sk-xxx' },
129
- })
130
-
131
- for await (const event of agent.chat({ message: '写一个30秒的广告脚本', threadId: 'thread-002' })) {
132
- if (event.type === 'agent') console.log(`🎭 ${event.name} 正在回答`)
133
- if (event.type === 'handoff') console.log(`🔀 ${event.from} → ${event.to}`)
134
- if (event.type === 'text') process.stdout.write(event.content)
135
- }
136
- ```
137
-
138
- ## Express 集成
139
-
140
- ```typescript
141
- import express from 'express'
142
-
143
- const app = express()
144
- app.use(express.json())
145
-
146
- // 一行挂载 SSE 路由
147
- app.post('/chat', agent.handleRequest())
148
-
149
- // 请求体:{ message: string, threadId: string, sceneContext?: Record<string, any> }
150
- // 响应:SSE 事件流(text/event-stream)
151
- // data: {"type":"agent","name":"导演"}
152
- // data: {"type":"text","content":"我来帮你调整"}
153
- // data: {"type":"tool_start","toolName":"bindTrack","input":{"trackId":"t-01"}}
154
- // data: {"type":"tool_end","toolName":"bindTrack","output":{"success":true}}
155
- // data: {"type":"done"}
156
- ```
157
-
158
- ## 📡 SSE Event Protocol
159
-
160
- | Event | Trigger | Payload |
161
- |-------|---------|---------|
162
- | `text` | LLM 输出文本 token | `{ content: string }` |
163
- | `tool_start` | 工具调用开始 | `{ toolName: string, input: Record<string, any> }` |
164
- | `tool_end` | 工具调用结束 | `{ toolName: string, output: any }` |
165
- | `handoff` | Agent 切换(多 Agent) | `{ from: string, to: string }` |
166
- | `agent` | 当前回答的 Agent 身份 | `{ name: string }` |
167
- | `error` | 执行出错 | `{ message: string }` |
168
- | `done` | 流结束 | `{}` |
169
-
170
- ## 📖 API Documentation
171
-
172
- ```bash
173
- npm run docs
174
- ```
175
-
176
- Generates TypeDoc documentation from TSDoc comments.
177
-
178
- ## 🛠️ Development
179
-
180
- ```bash
181
- npm run build # Build ESM + CJS + .d.ts
182
- npm run dev # Watch mode
183
- npm run typecheck # Type check
184
- npm run playground # Launch debug playground
185
- ```
186
-
187
- ## 📄 License
188
-
189
- MIT © [Lootoe](https://github.com/Lootoe)
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
+