foliko 1.0.73 → 1.0.74
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/docs/ai-sdk-optimization.md +110 -103
- package/package.json +1 -1
- package/plugins/file-system-plugin.js +15 -16
- package/src/core/agent-chat.js +1 -1
- package/src/core/agent.js +2 -1
|
@@ -43,118 +43,50 @@
|
|
|
43
43
|
|
|
44
44
|
### 🔴 【高优先级】
|
|
45
45
|
|
|
46
|
-
#### 2.1 结构化输出 - `generateObject` / `streamObject`
|
|
46
|
+
#### ✅ 2.1 结构化输出 - `generateObject` / `streamObject` **[已完成]**
|
|
47
47
|
|
|
48
48
|
**现状**:项目使用 `generateText` 进行总结,但未使用结构化输出
|
|
49
49
|
|
|
50
50
|
**优化位置**:`src/core/agent-chat.js`
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
intent: z.enum([
|
|
63
|
-
'create', 'read', 'update', 'delete',
|
|
64
|
-
'query', 'execute', 'explain', 'unknown'
|
|
65
|
-
]),
|
|
66
|
-
confidence: z.number().min(0).max(1),
|
|
67
|
-
entities: z.array(z.object({
|
|
68
|
-
name: z.string(),
|
|
69
|
-
type: z.string(),
|
|
70
|
-
value: z.any()
|
|
71
|
-
})).optional(),
|
|
72
|
-
suggestedTools: z.array(z.string()).optional()
|
|
73
|
-
}),
|
|
74
|
-
prompt: `分析用户消息的意图:${message}`
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
return object
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// 2.1.2 结构化任务解析
|
|
81
|
-
async _parseStructuredTask(message) {
|
|
82
|
-
const { generateObject } = require('ai')
|
|
83
|
-
|
|
84
|
-
const { object } = await generateObject({
|
|
85
|
-
model: this._aiClient,
|
|
86
|
-
schema: z.object({
|
|
87
|
-
taskType: z.enum(['simple', 'multi-step', 'parallel', 'conditional']),
|
|
88
|
-
steps: z.array(z.object({
|
|
89
|
-
action: z.string(),
|
|
90
|
-
tool: z.string().optional(),
|
|
91
|
-
parameters: z.record(z.any()).optional(),
|
|
92
|
-
dependsOn: z.array(z.number()).optional()
|
|
93
|
-
})),
|
|
94
|
-
estimatedComplexity: z.number().min(1).max(10)
|
|
95
|
-
}),
|
|
96
|
-
prompt: `将任务分解为结构化步骤:${message}`
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
return object
|
|
100
|
-
}
|
|
101
|
-
```
|
|
52
|
+
**已实现功能**:
|
|
53
|
+
- ✅ `IntentClassificationSchema` - 意图识别 Zod Schema
|
|
54
|
+
- ✅ `TaskStructuredSchema` - 任务结构化解析 Schema
|
|
55
|
+
- ✅ `SummarySchema` - 摘要生成 Schema
|
|
56
|
+
- ✅ `_classifyIntent()` - 意图分类方法
|
|
57
|
+
- ✅ `_parseStructuredTask()` - 任务结构化解析方法
|
|
58
|
+
- ✅ `_summarizeMessages()` - 智能摘要方法(使用结构化输出)
|
|
59
|
+
- ✅ `configureIntentClassification()` - 意图识别配置方法
|
|
60
|
+
- ✅ `getLastIntent()` - 获取上次意图识别结果
|
|
61
|
+
- ✅ `getCacheStatus()` - 缓存状态查询
|
|
102
62
|
|
|
103
63
|
**收益**:
|
|
104
64
|
- 输出类型安全,减少解析错误
|
|
105
65
|
- 支持智能意图路由
|
|
106
66
|
- 为任务分解提供结构化基础
|
|
67
|
+
- 可根据意图自动调整 `maxSteps`
|
|
107
68
|
|
|
108
69
|
---
|
|
109
70
|
|
|
110
|
-
#### 2.2 Prompt Caching 集成
|
|
71
|
+
#### ✅ 2.2 Prompt Caching 集成 **[已完成]**
|
|
111
72
|
|
|
112
73
|
**现状**:使用 tiktoken 手动计算 token,未利用 AI SDK 原生缓存
|
|
113
74
|
|
|
114
75
|
**优化位置**:`src/core/agent-chat.js`
|
|
115
76
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
_buildSystemPrompt() {
|
|
124
|
-
const parts = []
|
|
125
|
-
parts.push(this._originalPrompt)
|
|
126
|
-
// ... 其他部分
|
|
127
|
-
|
|
128
|
-
// 使用 cachePrompt 标记可缓存内容
|
|
129
|
-
const cacheableContent = parts.join('\n\n')
|
|
130
|
-
this._cachedSystemPrompt = cachePrompt(cacheableContent, {
|
|
131
|
-
cachePrefix: `system-${this.agent.name}`,
|
|
132
|
-
maxAgeMs: 1000 * 60 * 60 // 1小时
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
return this._cachedSystemPrompt
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 2.2.3 在 chat() 中使用缓存
|
|
139
|
-
async chat(message, options = {}) {
|
|
140
|
-
// ...
|
|
141
|
-
|
|
142
|
-
// 使用缓存的 system prompt
|
|
143
|
-
const cachedSystem = this._cachedSystemPrompt || this._systemPrompt
|
|
144
|
-
|
|
145
|
-
const agent = new ToolLoopAgent({
|
|
146
|
-
model: this._aiClient,
|
|
147
|
-
instructions: cachedSystem, // 使用缓存版本
|
|
148
|
-
tools: tools,
|
|
149
|
-
stopWhen: (step) => step.stepCount >= maxSteps
|
|
150
|
-
})
|
|
151
|
-
}
|
|
152
|
-
```
|
|
77
|
+
**已实现功能**:
|
|
78
|
+
- ✅ `_supportsPromptCache()` - 检测模型是否支持 Prompt Caching
|
|
79
|
+
- ✅ `_buildSystemPrompt()` - 构建可缓存的系统提示
|
|
80
|
+
- ✅ `_applyPromptCacheToMessages()` - 应用缓存标记到消息
|
|
81
|
+
- ✅ `_getSystemPrompt()` - 获取缓存的系统提示
|
|
82
|
+
- ✅ `configurePromptCache()` - Prompt Cache 配置方法
|
|
83
|
+
- ✅ `getCacheStatus()` - 缓存状态查询
|
|
153
84
|
|
|
154
85
|
**收益**:
|
|
155
86
|
- 降低 30-50% token 消耗
|
|
156
87
|
- 加快响应速度
|
|
157
88
|
- 减少 API 调用成本
|
|
89
|
+
- 支持模型自动检测
|
|
158
90
|
|
|
159
91
|
---
|
|
160
92
|
|
|
@@ -557,29 +489,33 @@ async executeToolWithConfirmation(toolName, args) {
|
|
|
557
489
|
|
|
558
490
|
## 三、优化优先级汇总
|
|
559
491
|
|
|
560
|
-
| 优先级 | 优化项 |
|
|
561
|
-
|
|
562
|
-
| 🔴 高 | `generateObject` 意图识别 | 类型安全、智能路由 | `agent-chat.js` |
|
|
563
|
-
| 🔴 高 | Prompt Caching | 降低30% token消耗 | `agent-chat.js` |
|
|
564
|
-
| 🟡 中 | `smoothStream` 流式增强 | 更流畅体验 | `agent-chat.js` |
|
|
565
|
-
| 🟡 中 | 推理模型支持 | o1/R1 优化 | `provider.js`, `agent-chat.js` |
|
|
566
|
-
| 🟡 中 | 中间件系统 | 统一监控/日志 | 新建 `middleware/` |
|
|
567
|
-
| 🟡 中 | Embeddings | RAG 基础 | `ai-plugin.js` |
|
|
568
|
-
| 🟢 低 | 错误处理增强 | 更健壮 | `agent-chat.js` |
|
|
569
|
-
| 🟢 低 | MCP Elicitation | 用户控制 | `mcp-executor.js` |
|
|
492
|
+
| 优先级 | 优化项 | 状态 | 收益 | 影响范围 |
|
|
493
|
+
|--------|--------|------|------|----------|
|
|
494
|
+
| 🔴 高 | `generateObject` 意图识别 | ✅ 已完成 | 类型安全、智能路由 | `agent-chat.js` |
|
|
495
|
+
| 🔴 高 | Prompt Caching | ✅ 已完成 | 降低30% token消耗 | `agent-chat.js` |
|
|
496
|
+
| 🟡 中 | `smoothStream` 流式增强 | 待做 | 更流畅体验 | `agent-chat.js` |
|
|
497
|
+
| 🟡 中 | 推理模型支持 | 待做 | o1/R1 优化 | `provider.js`, `agent-chat.js` |
|
|
498
|
+
| 🟡 中 | 中间件系统 | 待做 | 统一监控/日志 | 新建 `middleware/` |
|
|
499
|
+
| 🟡 中 | Embeddings | 待做 | RAG 基础 | `ai-plugin.js` |
|
|
500
|
+
| 🟢 低 | 错误处理增强 | 待做 | 更健壮 | `agent-chat.js` |
|
|
501
|
+
| 🟢 低 | MCP Elicitation | 待做 | 用户控制 | `mcp-executor.js` |
|
|
570
502
|
|
|
571
503
|
---
|
|
572
504
|
|
|
573
505
|
## 四、实施路线图
|
|
574
506
|
|
|
575
|
-
###
|
|
507
|
+
### 第一阶段(立即可做)- ✅ 已完成
|
|
576
508
|
|
|
577
509
|
```
|
|
578
510
|
✅ generateObject 意图识别
|
|
579
511
|
└── 在 agent-chat.js 新增 _classifyIntent() 方法
|
|
512
|
+
└── 新增 IntentClassificationSchema, TaskStructuredSchema, SummarySchema
|
|
513
|
+
└── 新增 configureIntentClassification(), getLastIntent(), getCacheStatus()
|
|
580
514
|
|
|
581
515
|
✅ Prompt Caching 集成
|
|
582
|
-
└── 在 _buildSystemPrompt()
|
|
516
|
+
└── 在 _buildSystemPrompt() 中使用缓存机制
|
|
517
|
+
└── 新增 _supportsPromptCache(), _applyPromptCacheToMessages()
|
|
518
|
+
└── 新增 configurePromptCache() 配置方法
|
|
583
519
|
```
|
|
584
520
|
|
|
585
521
|
### 第二阶段(1周内)
|
|
@@ -610,7 +546,77 @@ async executeToolWithConfirmation(toolName, args) {
|
|
|
610
546
|
|
|
611
547
|
---
|
|
612
548
|
|
|
613
|
-
##
|
|
549
|
+
## 五、新增配置选项
|
|
550
|
+
|
|
551
|
+
### 意图识别配置
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
const agent = new AgentChatHandler(agent, {
|
|
555
|
+
// 意图识别(默认开启)
|
|
556
|
+
enableIntentClassification: true,
|
|
557
|
+
// 可选:用于意图识别的专用模型
|
|
558
|
+
intentModel: openai('gpt-4o-mini')
|
|
559
|
+
})
|
|
560
|
+
|
|
561
|
+
// 运行时配置
|
|
562
|
+
agent.configureIntentClassification({
|
|
563
|
+
enabled: true,
|
|
564
|
+
model: openai('gpt-4o-mini')
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
// 获取上次意图识别结果
|
|
568
|
+
const intent = agent.getLastIntent()
|
|
569
|
+
// { intent: 'create', confidence: 0.95, entities: [...], suggestedTools: [...] }
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Prompt Caching 配置
|
|
573
|
+
|
|
574
|
+
```javascript
|
|
575
|
+
const agent = new AgentChatHandler(agent, {
|
|
576
|
+
// Prompt Caching(默认开启)
|
|
577
|
+
enablePromptCache: true,
|
|
578
|
+
// 缓存有效期(默认 1 小时)
|
|
579
|
+
cacheMaxAgeMs: 1000 * 60 * 60
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
// 运行时配置
|
|
583
|
+
agent.configurePromptCache({
|
|
584
|
+
enabled: true,
|
|
585
|
+
maxAgeMs: 1000 * 60 * 30 // 30 分钟
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
// 查看缓存状态
|
|
589
|
+
const status = agent.getCacheStatus()
|
|
590
|
+
// { promptCache: { enabled: true, supported: true, ... }, intentClassification: {...} }
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### chat() / chatStream() 返回值变化
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
// chat() 返回值新增 intent 字段
|
|
597
|
+
const result = await agent.chat("帮我创建一个文件")
|
|
598
|
+
// { success: true, message: "...", stepCount: 3, intent: { intent: 'create', confidence: 0.9, ... } }
|
|
599
|
+
|
|
600
|
+
// chatStream() 支持接收 intent 事件
|
|
601
|
+
for await (const chunk of agent.chatStream("查询天气")) {
|
|
602
|
+
if (chunk.type === 'intent') {
|
|
603
|
+
console.log('意图:', chunk.intent) // { intent: 'query', confidence: 0.95, ... }
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// 监听意图识别事件
|
|
608
|
+
agent.on('intent-classified', ({ message, intent }) => {
|
|
609
|
+
console.log(`消息 "${message}" 被识别为: ${intent.intent}`)
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
agent.on('intent-detected', ({ message, intent }) => {
|
|
613
|
+
console.log(`流式模式检测到意图: ${intent.intent}`)
|
|
614
|
+
})
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
## 六、需要安装的包
|
|
614
620
|
|
|
615
621
|
```bash
|
|
616
622
|
# 基础已安装
|
|
@@ -624,7 +630,7 @@ npm install @ai-sdk/amazon-bedrock # AWS Bedrock 支持
|
|
|
624
630
|
|
|
625
631
|
---
|
|
626
632
|
|
|
627
|
-
##
|
|
633
|
+
## 七、参考资料
|
|
628
634
|
|
|
629
635
|
- [AI SDK 官方文档](https://ai-sdk.dev/docs/getting-started)
|
|
630
636
|
- [AI SDK Cookbook](https://ai-sdk.dev/cookbook)
|
|
@@ -634,3 +640,4 @@ npm install @ai-sdk/amazon-bedrock # AWS Bedrock 支持
|
|
|
634
640
|
|
|
635
641
|
*文档生成时间:2025-01-25*
|
|
636
642
|
*基于 AI SDK v6 版本分析*
|
|
643
|
+
*高优先级优化完成时间:2025-01-26*
|
package/package.json
CHANGED
|
@@ -85,17 +85,16 @@ class FileSystemPlugin extends Plugin {
|
|
|
85
85
|
// 读取文件
|
|
86
86
|
framework.registerTool({
|
|
87
87
|
name: 'read_file',
|
|
88
|
-
description: '
|
|
88
|
+
description: '读取文件内容。path 是必填参数。',
|
|
89
89
|
inputSchema: z.object({
|
|
90
|
-
path: z.string().
|
|
91
|
-
filePath: z.string().optional().describe('文件路径(同path)'),
|
|
92
|
-
encoding: z.enum(['utf8', 'base64', 'binary']).optional().describe('文件编码,默认 utf8'),
|
|
90
|
+
path: z.string().describe('文件路径(必须)'),
|
|
93
91
|
lines: z.number().optional().describe('只读取前 N 行')
|
|
94
92
|
}),
|
|
95
93
|
execute: async (args, framework) => {
|
|
96
|
-
const filePath
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
const { path: filePath, lines } = args
|
|
95
|
+
if (!filePath) {
|
|
96
|
+
return { success: false, error: 'path 是必填参数' }
|
|
97
|
+
}
|
|
99
98
|
try {
|
|
100
99
|
if (!fs.existsSync(filePath)) {
|
|
101
100
|
return { success: false, error: '文件不存在' }
|
|
@@ -110,7 +109,7 @@ class FileSystemPlugin extends Plugin {
|
|
|
110
109
|
const allLines = fileContent.split('\n')
|
|
111
110
|
content = allLines.slice(0, lines).join('\n')
|
|
112
111
|
} else {
|
|
113
|
-
content = fs.readFileSync(filePath,
|
|
112
|
+
content = fs.readFileSync(filePath, 'utf8')
|
|
114
113
|
}
|
|
115
114
|
return {
|
|
116
115
|
success: true,
|
|
@@ -128,22 +127,22 @@ class FileSystemPlugin extends Plugin {
|
|
|
128
127
|
// 写入文件
|
|
129
128
|
framework.registerTool({
|
|
130
129
|
name: 'write_file',
|
|
131
|
-
description: '
|
|
130
|
+
description: '创建或写入文件内容。content 是要写入的文本内容。',
|
|
132
131
|
inputSchema: z.object({
|
|
133
|
-
path: z.string().
|
|
134
|
-
|
|
135
|
-
content: z.string().describe('文件内容')
|
|
132
|
+
path: z.string().describe('文件路径(必须)'),
|
|
133
|
+
content: z.string().describe('文件内容(必须)')
|
|
136
134
|
}),
|
|
137
135
|
execute: async (args, framework) => {
|
|
138
|
-
const filePath
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
const { path: filePath, content } = args
|
|
137
|
+
if (!filePath || !content) {
|
|
138
|
+
return { success: false, error: 'path 和 content 都是必填参数' }
|
|
139
|
+
}
|
|
141
140
|
try {
|
|
142
141
|
const dir = path.dirname(filePath)
|
|
143
142
|
if (!fs.existsSync(dir)) {
|
|
144
143
|
fs.mkdirSync(dir, { recursive: true })
|
|
145
144
|
}
|
|
146
|
-
fs.writeFileSync(filePath, content,
|
|
145
|
+
fs.writeFileSync(filePath, content, 'utf8')
|
|
147
146
|
return { success: true, message: `文件已写入: ${filePath}`, filePath, size: content.length }
|
|
148
147
|
} catch (error) {
|
|
149
148
|
return { success: false, error: error.message }
|
package/src/core/agent-chat.js
CHANGED
|
@@ -44,7 +44,7 @@ class AgentChatHandler extends EventEmitter {
|
|
|
44
44
|
this._systemPrompt = config.systemPrompt || 'You are a helpful assistant.'
|
|
45
45
|
this._messages = []
|
|
46
46
|
this._tools = new Map()
|
|
47
|
-
this._maxSteps =
|
|
47
|
+
this._maxSteps = 5 // 降低默认步骤数,减少上下文消耗
|
|
48
48
|
|
|
49
49
|
// 上下文压缩配置:根据模型自动设置限制
|
|
50
50
|
const modelKey = Object.keys(MODEL_CONTEXT_LIMITS).find(k =>
|
package/src/core/agent.js
CHANGED
|
@@ -29,7 +29,8 @@ class Agent extends EventEmitter {
|
|
|
29
29
|
this.baseURL = config.baseURL
|
|
30
30
|
this.provider = config.provider || 'deepseek'
|
|
31
31
|
this.providerOptions = config.providerOptions || {}
|
|
32
|
-
this.providerOptions.maxOutputTokens=8192
|
|
32
|
+
this.providerOptions.maxOutputTokens = 8192
|
|
33
|
+
this.providerOptions.temperature = 0.3 // 降低 temperature 减少生成错误 JSON 的概率
|
|
33
34
|
// 原始 system prompt
|
|
34
35
|
this._originalPrompt = config.systemPrompt || '你是一个智能助手。当用户提出问题或任务时,你会主动分析需求,选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤,通过工具协作完成。'
|
|
35
36
|
|