lll-web-agent 0.1.0 → 0.5.0

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,8 +1,8 @@
1
1
  # lll-web-agent
2
2
 
3
- 开箱即用的 LLM Agent SDK。配个 API Key,定义几个工具,就能跑起一个完整的 AI Agent。
3
+ 开箱即用的 LLM Agent SDK — 配个 API Key 就能跑。
4
4
 
5
- 零依赖。支持 OpenAI / DeepSeek / 通义千问 / X-GROK / Moonshot / 智谱 等所有 OpenAI 兼容供应商。
5
+ 内置完整 Runtime 管线:意图识别 工具过滤 上下文管理(token 预算) ReAct 循环。
6
6
 
7
7
  ## 安装
8
8
 
@@ -10,386 +10,393 @@
10
10
  npm install lll-web-agent
11
11
  ```
12
12
 
13
- 要求 Node.js >= 18(使用内置 fetch API)。
13
+ ## 快速开始
14
14
 
15
- ## 30 秒上手
15
+ ### 基础用法(10 行代码)
16
16
 
17
- ```javascript
18
- import { Agent } from 'lll-web-agent'
17
+ ```js
18
+ import { Agent, defineTool } from 'lll-web-agent'
19
+
20
+ const readFile = defineTool({
21
+ name: 'read_file',
22
+ description: '读取文件内容',
23
+ parameters: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] },
24
+ execute: async ({ path }) => (await import('fs/promises')).readFile(path, 'utf-8'),
25
+ })
19
26
 
20
27
  const agent = new Agent({
21
28
  provider: 'openai',
22
29
  apiKey: process.env.OPENAI_API_KEY,
23
30
  model: 'gpt-4',
31
+ tools: [readFile],
24
32
  })
25
33
 
26
- const reply = await agent.chat('你好,介绍一下你自己')
34
+ const reply = await agent.chat('读取 package.json 并告诉我项目名称')
27
35
  console.log(reply)
28
36
  ```
29
37
 
30
- 就这么多。不需要配置 HTTP 客户端、不需要处理 SSE 解析、不需要理解 ReAct 循环。
31
-
32
- ---
38
+ ### Runtime 模式(完整管线)
33
39
 
34
- ## 注册工具
40
+ ```js
41
+ import { Agent, KnowledgeBase, createKnowledgeEntry } from 'lll-web-agent'
35
42
 
36
- 工具是 Agent 与外部世界交互的方式。LLM 会根据工具描述自主决定何时调用哪个工具。
43
+ // 1. 构建知识库
44
+ const kb = new KnowledgeBase()
45
+ kb.addEntry(createKnowledgeEntry('ARCHITECTURE', '项目架构', '本项目使用 monorepo 结构...'))
46
+ kb.addEntry(createKnowledgeEntry('ERROR_PATTERN', '常见错误', '避免在循环中使用 await...'))
37
47
 
38
- ### 基本用法
39
-
40
- ```javascript
41
- import { Agent, defineTool } from 'lll-web-agent'
42
-
43
- // 1. 用 defineTool 定义工具
44
- const getCurrentTime = defineTool({
45
- name: 'get_current_time', // 工具唯一名称
46
- description: '获取当前时间', // 告诉 LLM 这个工具能做什么
47
- parameters: { // JSON Schema 格式的参数定义
48
- type: 'object',
49
- properties: {}, // 无参数
50
- },
51
- execute: async () => { // 执行函数,返回字符串
52
- return new Date().toISOString()
48
+ // 2. 创建 Agent(启用 Runtime 管线)
49
+ const agent = new Agent({
50
+ provider: 'deepseek',
51
+ apiKey: process.env.DEEPSEEK_API_KEY,
52
+ model: 'deepseek-chat',
53
+ tools: [readFile, shellExec],
54
+ enableIntentRecognition: true, // 启用意图识别(sidecar LLM 调用)
55
+ knowledgeBase: kb, // 注入知识库
56
+ tokenBudget: { // 自定义 token 预算
57
+ totalTokens: 60000,
58
+ systemPromptRatio: 0.15,
59
+ knowledgeRatio: 0.20,
60
+ historyRatio: 0.45,
61
+ toolsRatio: 0.20,
53
62
  },
54
63
  })
55
64
 
56
- // 2. 传给 Agent
57
- const agent = new Agent({
58
- provider: 'openai',
59
- apiKey: process.env.OPENAI_API_KEY,
60
- model: 'gpt-4',
61
- tools: [getCurrentTime],
62
- })
65
+ const reply = await agent.chat('分析项目架构并找出潜在问题')
66
+ ```
63
67
 
64
- // 3. Agent 会自动决定是否调用工具
65
- const reply = await agent.chat('现在几点了?')
66
- // Agent 内部流程:
67
- // LLM 思考 -> 决定调用 get_current_time -> 执行 -> 拿到时间 -> 继续思考 -> 返回最终回答
68
+ ## 流式对话
69
+
70
+ ```js
71
+ for await (const event of agent.stream('帮我重构这个函数')) {
72
+ switch (event.type) {
73
+ case 'intent': console.log('意图:', event.intent); break
74
+ case 'delta': process.stdout.write(event.content); break
75
+ case 'tool_start': console.log(`\n🔧 ${event.name}(${JSON.stringify(event.arguments)})`); break
76
+ case 'tool_end': console.log(`✅ ${event.name} → ${event.result}`); break
77
+ case 'done': console.log('\n完成'); break
78
+ }
79
+ }
68
80
  ```
69
81
 
70
- ### 带参数的工具
82
+ ## 架构
71
83
 
72
- ```javascript
73
- const readFile = defineTool({
74
- name: 'read_file',
75
- description: '读取指定路径的文件内容',
76
- parameters: {
77
- type: 'object',
78
- properties: {
79
- path: {
80
- type: 'string',
81
- description: '文件路径,相对于当前工作目录',
82
- },
83
- },
84
- required: ['path'], // 必填参数
85
- },
86
- execute: async ({ path }) => {
87
- const fs = await import('fs/promises')
88
- try {
89
- return await fs.readFile(path, 'utf-8')
90
- } catch (err) {
91
- return `读取失败: ${err.message}` // 返回错误信息,LLM 会看到并处理
92
- }
93
- },
94
- })
84
+ ```
85
+ 用户消息
86
+
87
+ ├─ enableIntentRecognition=true?
88
+ │ └─ IntentRecognizer (sidecar LLM 调用)
89
+ │ → { clarity, complexity, recommendedStrategy, filteredToolNames }
90
+
91
+ ├─ ToolFilter
92
+ │ → 根据 intent 过滤工具(BaseTool 始终保留)
93
+
94
+ ├─ ContextManager (如果配置了 tokenBudget 或 knowledgeBase)
95
+ │ → 组装 prompt: systemPrompt + knowledge + history + tools
96
+ │ → 超预算时按优先级裁剪: TOOLS → HISTORY → KNOWLEDGE
97
+
98
+ └─ 执行策略(strategy)
99
+ ├─ react(默认)
100
+ │ → LLM 调用 → 工具执行 → 观察结果 → 继续/完成
101
+
102
+ └─ plan_and_execute
103
+ Phase 1: Planning(LLM 生成结构化计划)
104
+ → Phase 2: Execution(逐步执行,每步内部 ReAct 循环)
105
+ → Phase 3: Synthesis(汇总结果,生成最终回答)
106
+ → 支持自适应重规划(步骤失败时自动修订计划)
95
107
  ```
96
108
 
97
- ### 多个工具协作
109
+ ## 核心模块
98
110
 
99
- Agent 可以在一次对话中调用多个工具,自主决定调用顺序:
111
+ ### Agent
100
112
 
101
- ```javascript
102
- const listFiles = defineTool({
103
- name: 'list_files',
104
- description: '列出目录下的文件',
105
- parameters: {
106
- type: 'object',
107
- properties: {
108
- dir: { type: 'string', description: '目录路径' },
109
- },
110
- required: ['dir'],
111
- },
112
- execute: async ({ dir }) => {
113
- const fs = await import('fs/promises')
114
- const files = await fs.readdir(dir)
115
- return files.join('\n')
116
- },
117
- })
113
+ 主入口,支持两种模式:
118
114
 
119
- const agent = new Agent({
120
- provider: 'deepseek',
121
- apiKey: process.env.DEEPSEEK_API_KEY,
122
- model: 'deepseek-chat',
123
- tools: [listFiles, readFile], // 注册多个工具
124
- })
115
+ | 参数 | 默认值 | 说明 |
116
+ |------|--------|------|
117
+ | `provider` | (必需) | 供应商: openai, deepseek, qwen, moonshot, zhipu, x-grok |
118
+ | `apiKey` | (必需) | API Key |
119
+ | `model` | `'gpt-4'` | 模型名称 |
120
+ | `tools` | `[]` | 工具列表 |
121
+ | `maxRounds` | `300` | 最大 ReAct 轮次 |
122
+ | `enableIntentRecognition` | `false` | 启用意图识别 |
123
+ | `knowledgeBase` | `null` | 知识库实例 |
124
+ | `tokenBudget` | `null` | token 预算配置 |
125
+ | `memory` | `SlidingWindowMemory(40)` | 自定义记忆实例 |
126
+ | `strategy` | `'react'` | 执行策略: `'react'` 或 `'plan_and_execute'` |
127
+ | `planAndExecuteOpts` | `{}` | PlanAndExecute 策略配置(见下方) |
125
128
 
126
- // Agent 会先调用 list_files 看有哪些文件,再调用 read_file 读取感兴趣的文件
127
- const reply = await agent.chat('看看当前目录有什么文件,读一下 package.json 的内容')
128
- ```
129
+ ### IntentRecognizer
129
130
 
130
- ### 工具的 execute 函数规范
131
-
132
- ```javascript
133
- defineTool({
134
- name: 'my_tool',
135
- description: '...',
136
- parameters: { ... },
137
- execute: async (params) => {
138
- // params 是 LLM 传入的参数对象,结构与 parameters 定义一致
139
- // 必须返回字符串(LLM 只能理解文本)
140
- // 如果返回对象,会被自动 JSON.stringify
141
- // 抛出异常时,错误信息会被发送给 LLM,LLM 可能会重试或换一种方式
142
- return '执行结果'
143
- },
144
- })
145
- ```
131
+ Sidecar 方式独立 LLM 调用,分析用户请求:
146
132
 
147
- ### 实用工具示例
148
-
149
- ```javascript
150
- // Shell 命令执行
151
- const shellExec = defineTool({
152
- name: 'shell_exec',
153
- description: '执行 shell 命令并返回输出',
154
- parameters: {
155
- type: 'object',
156
- properties: {
157
- command: { type: 'string', description: 'shell 命令' },
158
- },
159
- required: ['command'],
160
- },
161
- execute: async ({ command }) => {
162
- const { execSync } = await import('child_process')
163
- try {
164
- return execSync(command, { encoding: 'utf-8', timeout: 10000 })
165
- } catch (err) {
166
- return `命令执行失败: ${err.message}`
167
- }
168
- },
169
- })
133
+ ```js
134
+ import { IntentRecognizer } from 'lll-web-agent'
170
135
 
171
- // HTTP 请求
172
- const httpGet = defineTool({
173
- name: 'http_get',
174
- description: '发送 HTTP GET 请求',
175
- parameters: {
176
- type: 'object',
177
- properties: {
178
- url: { type: 'string', description: 'URL 地址' },
179
- },
180
- required: ['url'],
181
- },
182
- execute: async ({ url }) => {
183
- const res = await fetch(url)
184
- return await res.text()
185
- },
136
+ const ir = new IntentRecognizer({
137
+ url: 'https://api.openai.com/v1/chat/completions',
138
+ apiKey: 'sk-xxx',
139
+ model: 'gpt-4',
186
140
  })
187
141
 
188
- // 数学计算
189
- const calculate = defineTool({
190
- name: 'calculate',
191
- description: '计算数学表达式',
192
- parameters: {
193
- type: 'object',
194
- properties: {
195
- expression: { type: 'string', description: '数学表达式' },
196
- },
197
- required: ['expression'],
198
- },
199
- execute: async ({ expression }) => {
200
- return String(Function(`"use strict"; return (${expression})`)())
201
- },
202
- })
142
+ const intent = await ir.analyze('帮我重构整个项目的错误处理', ['read_file', 'write_file', 'shell_exec'])
143
+ // { clarity: 'CLEAR', complexity: 'COMPLEX', recommendedStrategy: 'plan_and_execute', ... }
203
144
  ```
204
145
 
205
- ---
146
+ ### KnowledgeBase
206
147
 
207
- ## 流式输出
148
+ 项目知识管理,注入到 prompt 中:
208
149
 
209
- 通过 async generator 实时获取 Agent 的执行过程:
150
+ ```js
151
+ import { KnowledgeBase, createKnowledgeEntry } from 'lll-web-agent'
210
152
 
211
- ```javascript
212
- for await (const event of agent.stream('帮我分析这个项目')) {
213
- switch (event.type) {
214
- case 'delta': // LLM 文本增量
215
- process.stdout.write(event.content)
216
- break
217
- case 'tool_start': // 开始调用工具
218
- console.log(`\n[调用工具: ${event.name}]`)
219
- break
220
- case 'tool_end': // 工具执行完成
221
- console.log(`[结果: ${event.result}]`)
222
- break
223
- case 'done': // 对话完成
224
- console.log('\n--- 完成 ---')
225
- break
226
- }
227
- }
153
+ const kb = new KnowledgeBase()
154
+ kb.addEntry(createKnowledgeEntry('ARCHITECTURE', '技术栈', 'React + TypeScript + Vite'))
155
+ kb.addEntry(createKnowledgeEntry('ERROR_PATTERN', 'API 调用', '所有 API 调用必须有超时设置'))
156
+
157
+ console.log(kb.buildKnowledgePrompt())
158
+ // → ## 项目架构\n### 技术栈\nReact + TypeScript + Vite\n\n## 错误避免模式\n...
228
159
  ```
229
160
 
230
- ---
161
+ ### ContextManager
231
162
 
232
- ## 多轮对话
163
+ Token 预算管理和 prompt 组装:
233
164
 
234
- Agent 自动维护对话历史,支持多轮上下文:
165
+ ```js
166
+ import { ContextManager, defaultTokenBudget } from 'lll-web-agent'
235
167
 
236
- ```javascript
237
- const agent = new Agent({
238
- provider: 'openai',
239
- apiKey: process.env.OPENAI_API_KEY,
240
- model: 'gpt-4',
241
- tools: [readFile],
168
+ const cm = new ContextManager()
169
+ const result = cm.assemblePrompt({
170
+ systemPrompt: '你是一个编程助手',
171
+ userMessage: '帮我写排序',
172
+ history: [{ role: 'user', content: '你好' }, { role: 'assistant', content: '你好!' }],
173
+ filteredTools: myTools,
174
+ tokenBudget: { ...defaultTokenBudget(), totalTokens: 8000 },
242
175
  })
243
-
244
- await agent.chat('读一下 package.json')
245
- // Agent 记住了上一轮的内容
246
- await agent.chat('这个项目用了什么依赖?')
247
-
248
- // 开始新会话
249
- agent.reset()
250
- await agent.chat('你好') // 不记得之前的对话了
176
+ // result.messages → 组装好的 messages 数组
177
+ // result.trimmed → 是否发生了裁剪
251
178
  ```
252
179
 
253
- ---
180
+ ### Memory 策略
254
181
 
255
- ## 取消请求
182
+ ```js
183
+ import { SlidingWindowMemory, SummarizingMemory, TokenAwareMemory } from 'lll-web-agent'
256
184
 
257
- ```javascript
258
- const controller = new AbortController()
185
+ // 滑动窗口(默认)
186
+ const sw = new SlidingWindowMemory(40)
259
187
 
260
- // 5 秒后取消
261
- setTimeout(() => controller.abort(), 5000)
188
+ // 摘要记忆(超阈值时 LLM 压缩)
189
+ const sm = new SummarizingMemory({
190
+ threshold: 20,
191
+ keepRecent: 5,
192
+ summarizer: async (text) => await myLlmSummarize(text),
193
+ })
262
194
 
263
- try {
264
- const reply = await agent.chat('做一个很复杂的分析', {
265
- signal: controller.signal,
266
- })
267
- } catch (err) {
268
- if (err.name === 'AbortError') {
269
- console.log('请求已取消')
270
- }
271
- }
195
+ // Token 感知记忆
196
+ const ta = new TokenAwareMemory(50000)
197
+
198
+ // 注入到 Agent
199
+ const agent = new Agent({ ..., memory: sm })
272
200
  ```
273
201
 
274
- ---
202
+ ### ToolFilter
275
203
 
276
- ## 多供应商支持
204
+ ```js
205
+ import { ToolFilter, BASE_TOOLS } from 'lll-web-agent'
277
206
 
278
- 所有使用 OpenAI 兼容 API 的供应商都可以直接使用:
207
+ const filter = new ToolFilter()
208
+ const filtered = filter.filter(intentResult, allTools)
209
+ // BASE_TOOLS (keyword_search, read_file, write_file, shell_exec, project_tree) 始终保留
210
+ ```
279
211
 
280
- ```javascript
281
- // OpenAI
282
- new Agent({ provider: 'openai', apiKey: '...', model: 'gpt-4' })
212
+ ### PlanAndExecute 执行策略
283
213
 
284
- // DeepSeek
285
- new Agent({ provider: 'deepseek', apiKey: '...', model: 'deepseek-chat' })
214
+ 对应 Java 框架的 `PlanAndExecuteStrategy`。适用于复杂多步骤任务,相比 ReAct 的"边思考边行动",PlanAndExecute 先让 LLM 站在全局视角制定完整计划,然后逐步执行。
286
215
 
287
- // 通义千问
288
- new Agent({ provider: 'qwen', apiKey: '...', model: 'qwen-turbo' })
216
+ 三阶段流程:
217
+ 1. **Planning** 调用 LLM 生成结构化执行计划(JSON 步骤列表)
218
+ 2. **Execution** — 对每个步骤使用内部 ReAct 循环执行(支持工具调用)
219
+ 3. **Synthesis** — 汇总所有步骤结果,生成最终回答
289
220
 
290
- // X-GROK
291
- new Agent({ provider: 'x-grok', apiKey: '...', model: 'grok-2' })
221
+ #### 通过 Agent 切换策略
292
222
 
293
- // Moonshot (月之暗面)
294
- new Agent({ provider: 'moonshot', apiKey: '...', model: 'moonshot-v1-8k' })
223
+ ```js
224
+ import { Agent, defineTool } from 'lll-web-agent'
295
225
 
296
- // 智谱 AI
297
- new Agent({ provider: 'zhipu', apiKey: '...', model: 'glm-4' })
226
+ const readFile = defineTool({ name: 'read_file', description: '读取文件', /* ... */ })
227
+ const writeFile = defineTool({ name: 'write_file', description: '写入文件', /* ... */ })
228
+ const shellExec = defineTool({ name: 'shell_exec', description: '执行命令', /* ... */ })
298
229
 
299
- // 任意 OpenAI 兼容供应商(自定义 URL)
300
- new Agent({
230
+ // 使用 PlanAndExecute 策略
231
+ const agent = new Agent({
301
232
  provider: 'openai',
302
- url: 'https://my-proxy.com/v1/chat/completions',
303
- apiKey: '...',
304
- model: 'my-model',
233
+ apiKey: process.env.OPENAI_API_KEY,
234
+ model: 'gpt-4',
235
+ tools: [readFile, writeFile, shellExec],
236
+ strategy: 'plan_and_execute', // ← 切换策略
237
+ planAndExecuteOpts: { // ← 可选配置
238
+ maxPlanSteps: 10,
239
+ stepMaxRounds: 20,
240
+ maxReplanAttempts: 2,
241
+ },
305
242
  })
306
- ```
307
-
308
- ### 注册自定义供应商
309
243
 
310
- ```javascript
311
- import { registerProvider } from 'lll-web-agent/src/providers.js'
312
-
313
- registerProvider('my-llm', {
314
- url: 'https://api.my-llm.com/v1/chat/completions',
315
- })
244
+ // 同步对话 — 用法与 ReAct 完全一致
245
+ const reply = await agent.chat('重构项目中所有废弃的 API 调用')
246
+ console.log(reply)
316
247
 
317
- const agent = new Agent({ provider: 'my-llm', apiKey: '...', model: '...' })
248
+ // 流式对话 额外推送计划和步骤进度事件
249
+ for await (const event of agent.stream('分析项目架构并生成文档')) {
250
+ switch (event.type) {
251
+ case 'phase': console.log(`[${event.phase}] ${event.message}`); break
252
+ case 'plan_generated': console.log('计划:', event.plan); break
253
+ case 'step_start': console.log(`▶ Step ${event.index + 1}: ${event.description}`); break
254
+ case 'step_complete':
255
+ console.log(`${event.success ? '✅' : '❌'} Step ${event.index + 1} (${event.duration}ms)`)
256
+ break
257
+ case 'plan_revised': console.log('计划已修订:', event.plan); break
258
+ case 'done': console.log('最终结果:', event.content); break
259
+ }
260
+ }
318
261
  ```
319
262
 
320
- ---
263
+ #### 动态切换策略
321
264
 
322
- ## 全部配置项
323
-
324
- ```javascript
325
- new Agent({
326
- // 必填
327
- provider: 'openai', // 供应商名称
328
- apiKey: 'sk-xxx', // API Key
265
+ ```js
266
+ // 根据任务复杂度动态选择策略
267
+ function chooseStrategy(message) {
268
+ const complexKeywords = ['重构', '迁移', '分析整个', '批量修改', '全面检查']
269
+ return complexKeywords.some(k => message.includes(k)) ? 'plan_and_execute' : 'react'
270
+ }
329
271
 
330
- // 可选
331
- model: 'gpt-4', // 模型名称,默认 'gpt-4'
332
- systemPrompt: '你是一个助手', // 系统提示词,默认 'You are a helpful assistant.'
333
- url: 'https://...', // 自定义 API URL,覆盖供应商默认值
334
- tools: [], // 工具列表
335
- maxRounds: 30, // 最大 ReAct 轮次,默认 30
336
- maxMessages: 40, // 记忆窗口大小(保留最近 N 条消息),默认 40
337
- temperature: 1, // 温度,默认 1
272
+ const agent = new Agent({
273
+ provider: 'openai',
274
+ apiKey: process.env.OPENAI_API_KEY,
275
+ model: 'gpt-4',
276
+ tools: [readFile, writeFile, shellExec],
277
+ strategy: chooseStrategy(userMessage),
338
278
  })
339
279
  ```
340
280
 
341
- ---
342
-
343
- ## 工作原理
281
+ #### 结合意图识别自动选择策略
344
282
 
345
- Agent 内部运行 ReAct(Reasoning + Acting)循环:
283
+ ```js
284
+ import { Agent, IntentRecognizer } from 'lll-web-agent'
346
285
 
347
- ```
348
- 用户消息 + 工具描述 -> LLM
349
- |
350
- LLM 返回文本? -> 作为最终回答返回
351
- |
352
- LLM 返回工具调用?
353
- |
354
- 执行工具 -> 将结果加入对话历史
355
- |
356
- 回到顶部,再次调用 LLM
357
- ```
286
+ // 先用 IntentRecognizer 分析任务复杂度
287
+ const ir = new IntentRecognizer({
288
+ url: 'https://api.openai.com/v1/chat/completions',
289
+ apiKey: process.env.OPENAI_API_KEY,
290
+ model: 'gpt-4',
291
+ })
358
292
 
359
- 对话历史通过 SlidingWindowMemory 管理,超出窗口大小时自动丢弃最旧的消息(system prompt 始终保留)。
293
+ const intent = await ir.analyze(userMessage, toolNames)
294
+ // intent.recommendedStrategy → 'react' | 'plan_and_execute'
360
295
 
361
- ---
296
+ const agent = new Agent({
297
+ provider: 'openai',
298
+ apiKey: process.env.OPENAI_API_KEY,
299
+ model: 'gpt-4',
300
+ tools: myTools,
301
+ strategy: intent.recommendedStrategy, // ← 根据意图识别结果选择
302
+ })
362
303
 
363
- ## API 参考
304
+ const reply = await agent.chat(userMessage)
305
+ ```
364
306
 
365
- ### `Agent`
307
+ #### 独立使用 PlanAndExecuteStrategy
366
308
 
367
- | 方法 | 说明 |
368
- |------|------|
369
- | `new Agent(opts)` | 创建 Agent 实例 |
370
- | `agent.chat(message, opts?)` | 同步对话,返回 `Promise<string>` |
371
- | `agent.stream(message, opts?)` | 流式对话,返回 `AsyncGenerator<Event>` |
372
- | `agent.reset()` | 清空对话历史,开始新会话 |
309
+ 不通过 Agent,直接使用策略类:
373
310
 
374
- ### `defineTool(def)`
311
+ ```js
312
+ import { PlanAndExecuteStrategy } from 'lll-web-agent'
375
313
 
376
- | 字段 | 类型 | 必填 | 说明 |
377
- |------|------|------|------|
378
- | `name` | string | 是 | 工具唯一名称 |
379
- | `description` | string | 是 | 工具描述(供 LLM 理解) |
380
- | `parameters` | object | 否 | JSON Schema 格式的参数定义 |
381
- | `execute` | async function | 是 | 执行函数,接收参数对象,返回字符串 |
314
+ const strategy = new PlanAndExecuteStrategy({
315
+ url: 'https://api.openai.com/v1/chat/completions',
316
+ apiKey: process.env.OPENAI_API_KEY,
317
+ model: 'gpt-4',
318
+ tools: [readFile, writeFile, shellExec],
319
+ maxPlanSteps: 10,
320
+ stepMaxRounds: 20,
321
+ maxReplanAttempts: 2,
322
+
323
+ // 进度回调
324
+ onPhase: (phase, msg) => console.log(`[${phase}] ${msg}`),
325
+ onPlanGenerated: (steps) => {
326
+ console.log('执行计划:')
327
+ steps.forEach(s => console.log(` ${s.index + 1}. ${s.description}`))
328
+ },
329
+ onStepStart: (i, desc) => console.log(`▶ 开始步骤 ${i + 1}: ${desc}`),
330
+ onStepComplete: (i, ok, result) => console.log(`${ok ? '✅' : '❌'} 步骤 ${i + 1}: ${result}`),
331
+ onPlanRevised: (steps) => console.log('计划已修订,剩余步骤:', steps.length),
332
+ })
382
333
 
383
- ### 流式事件类型
334
+ // 同步执行
335
+ const { content, plan } = await strategy.execute('将项目从 CommonJS 迁移到 ESM')
336
+ console.log('最终结果:', content)
337
+ console.log('计划步骤:', plan.map(s => `${s.status} - ${s.description}`))
384
338
 
385
- | type | 字段 | 说明 |
386
- |------|------|------|
387
- | `delta` | `content` | LLM 文本增量 |
388
- | `tool_start` | `name`, `arguments` | 开始调用工具 |
389
- | `tool_end` | `name`, `result` | 工具执行完成 |
390
- | `done` | `content` | 对话完成,包含完整回复 |
339
+ // 流式执行
340
+ for await (const event of strategy.stream('批量修复所有 lint 错误')) {
341
+ console.log(event)
342
+ }
343
+ ```
391
344
 
392
- ---
345
+ #### PlanAndExecute 配置参数
346
+
347
+ | 参数 | 默认值 | 说明 |
348
+ |------|--------|------|
349
+ | `maxPlanSteps` | `35` | 计划步骤上限 |
350
+ | `stepMaxRounds` | `300` | 单个步骤内 ReAct 循环最大轮次 |
351
+ | `maxReplanAttempts` | `2` | 步骤失败时最大重规划次数 |
352
+ | `planningTimeoutMs` | `120000` | 规划阶段 LLM 调用超时(毫秒) |
353
+ | `synthesisTimeoutMs` | `120000` | 合成阶段 LLM 调用超时(毫秒) |
354
+ | `onPhase` | - | 阶段变更回调 `(phase, message) => void` |
355
+ | `onPlanGenerated` | - | 计划生成回调 `(steps) => void` |
356
+ | `onStepStart` | - | 步骤开始回调 `(index, description) => void` |
357
+ | `onStepComplete` | - | 步骤完成回调 `(index, success, result) => void` |
358
+ | `onPlanRevised` | - | 计划修订回调 `(steps) => void` |
359
+
360
+ #### 流式事件类型
361
+
362
+ | 事件 type | 字段 | 说明 |
363
+ |-----------|------|------|
364
+ | `phase` | `phase`, `message` | 阶段变更(planning / executing / synthesizing / completed / fallback) |
365
+ | `plan_generated` | `plan` | 计划生成完成 |
366
+ | `step_start` | `index`, `description` | 步骤开始执行 |
367
+ | `step_complete` | `index`, `success`, `result`, `duration` | 步骤执行完成 |
368
+ | `plan_revised` | `plan` | 计划被修订(步骤失败后重规划) |
369
+ | `done` | `content`, `plan` | 全部完成,包含最终结果和计划快照 |
370
+
371
+ ## 与 Java Runtime 的对应关系
372
+
373
+ | JS SDK | Java Runtime | 说明 |
374
+ |--------|-------------|------|
375
+ | `Agent` | `Agent + AgentBuilder + AgentRuntime` | 高层 API |
376
+ | `Agent({ strategy: 'react' })` | `ReActStrategy` | ReAct 执行策略(默认) |
377
+ | `Agent({ strategy: 'plan_and_execute' })` | `PlanAndExecuteStrategy` | Plan & Execute 执行策略 |
378
+ | `PlanAndExecuteStrategy` | `PlanAndExecuteStrategy` | 独立使用的策略类 |
379
+ | `PlanStep` / `StepStatus` | `PlanStep` / `PlanStep.Status` | 计划步骤模型 |
380
+ | `IntentRecognizer` | `fc.runtime.IntentRecognizer` | sidecar 意图识别 |
381
+ | `ToolFilter` | `fc.runtime.ToolFilter` | 工具过滤 |
382
+ | `ContextManager` | `fc.state.ContextManager` | prompt 组装 + token 预算 |
383
+ | `KnowledgeBase` | `fc.runtime.KnowledgeBase` | 知识库管理 |
384
+ | `SlidingWindowMemory` | `fc.memory.SlidingWindowMemory` | 滑动窗口记忆 |
385
+ | `SummarizingMemory` | `fc.memory.SummarizingMemory` | 摘要记忆 |
386
+ | `TokenAwareMemory` | `fc.memory.AdaptiveMemory` | token 感知记忆 |
387
+ | `streamChat / syncChat` | `LlmClient` | LLM 通信 |
388
+ | `defineTool` | `Tool` 接口 | 工具定义 |
389
+ | `resolveProviderUrl` | `LlmProviderAdapterRegistry` | 供应商适配 |
390
+
391
+ ## 浏览器使用
392
+
393
+ ```html
394
+ <script src="https://unpkg.com/lll-web-agent/dist/lll-web-agent.min.js"></script>
395
+ <script>
396
+ const { Agent, defineTool, KnowledgeBase } = LllWebAgent
397
+ // ...
398
+ </script>
399
+ ```
393
400
 
394
401
  ## License
395
402