# AI SDK v6 优化报告 - Foliko 项目

> 本报告基于 [AI SDK v6 文档](https://ai-sdk.dev/docs/getting-started) 和 [Cookbook](https://ai-sdk.dev/cookbook) 分析，为 Foliko 项目提供具体的优化建议。

## 一、项目当前 AI SDK 使用分析

### 1.1 已集成的 AI SDK 组件

| 组件                        | 版本    | 用途               |
| --------------------------- | ------- | ------------------ |
| `ai`                        | 6.0.116 | 核心 SDK           |
| `@ai-sdk/openai`            | 3.0.41  | OpenAI Provider    |
| `@ai-sdk/anthropic`         | 3.0.58  | Anthropic Provider |
| `@ai-sdk/openai-compatible` | 2.0.35  | 兼容 Provider      |
| `@ai-sdk/mcp`               | 1.0.25  | MCP 集成           |
| `zod`                       | 3.24.0  | Schema 验证        |
| `tiktoken`                  | 1.0.22  | Token 计数         |

### 1.2 当前使用的 AI SDK 功能

```javascript
// ✅ 已使用
- ToolLoopAgent (工具调用循环)
- generateText (上下文总结)
- streamText 架构
- 基础 Provider 配置
- Zod schema (工具参数)
```

### 1.3 相关文件位置

| 功能            | 文件位置                        | 用途                     |
| --------------- | ------------------------------- | ------------------------ |
| `ToolLoopAgent` | `src/core/agent-chat.js`        | 工具调用循环             |
| `generateText`  | `src/core/agent-chat.js`        | 上下文总结、工具结果压缩 |
| `@ai-sdk/mcp`   | `src/executors/mcp-executor.js` | MCP 服务器集成           |
| `Zod`           | 全局                            | 工具参数 schema          |
| `tiktoken`      | `src/core/agent-chat.js`        | Token 计数、上下文压缩   |

---

## 二、优化建议

### 🔴 【高优先级】

#### ✅ 2.1 结构化输出 - `generateObject` / `streamObject` **[已完成]**

**现状**：项目使用 `generateText` 进行总结，但未使用结构化输出

**优化位置**：`src/core/agent-chat.js`

**已实现功能**：

- ✅ `IntentClassificationSchema` - 意图识别 Zod Schema
- ✅ `TaskStructuredSchema` - 任务结构化解析 Schema
- ✅ `SummarySchema` - 摘要生成 Schema
- ✅ `_classifyIntent()` - 意图分类方法
- ✅ `_parseStructuredTask()` - 任务结构化解析方法
- ✅ `_summarizeMessages()` - 智能摘要方法（使用结构化输出）
- ✅ `configureIntentClassification()` - 意图识别配置方法
- ✅ `getLastIntent()` - 获取上次意图识别结果
- ✅ `getCacheStatus()` - 缓存状态查询

**收益**：

- 输出类型安全，减少解析错误
- 支持智能意图路由
- 为任务分解提供结构化基础
- 可根据意图自动调整 `maxSteps`

---

#### ✅ 2.2 Prompt Caching 集成 **[已完成]**

**现状**：使用 tiktoken 手动计算 token，未利用 AI SDK 原生缓存

**优化位置**：`src/core/agent-chat.js`

**已实现功能**：

- ✅ `_supportsPromptCache()` - 检测模型是否支持 Prompt Caching
- ✅ `_buildSystemPrompt()` - 构建可缓存的系统提示
- ✅ `_applyPromptCacheToMessages()` - 应用缓存标记到消息
- ✅ `_getSystemPrompt()` - 获取缓存的系统提示
- ✅ `configurePromptCache()` - Prompt Cache 配置方法
- ✅ `getCacheStatus()` - 缓存状态查询

**收益**：

- 降低 30-50% token 消耗
- 加快响应速度
- 减少 API 调用成本
- 支持模型自动检测

---

### 🟡 【中优先级】

#### 2.3 流式响应增强 - `smoothStream` / `streamObject`

**现状**：流式使用 `stream` 但未使用平滑输出

**优化位置**：`src/core/agent-chat.js`

**建议修改**：

```javascript
// 2.3.1 平滑流式输出
async *chatStream(message, options = {}) {
  // ...

  const result = await framework.runWithContext(context, async () => {
    return agent.stream({
      messages,
      ...this.providerOptions,
      ...smoothStream({
        delayInMs: 14  // 14ms 平滑间隔
      })
    })
  })

  // ...
}

// 2.3.2 结构化流式输出 - 新增方法
async *streamStructured(message, schema, options = {}) {
  const { streamObject } = require('ai')

  const { partialObjectStream } = await streamObject({
    model: this._aiClient,
    schema,
    prompt: message,
    ...smoothStream({ delayInMs: 14 })
  })

  for await (const partialObject of partialObjectStream) {
    yield { type: 'partial', data: partialObject }
  }
}
```

**收益**：

- 更流畅的实时输出体验
- 支持部分对象流式渲染

---

#### 2.4 推理模型支持 - o1/o3/R1

**现状**：未针对推理模型配置

**优化位置**：`src/core/provider.js` 和 `src/core/agent-chat.js`

**建议修改**：

```javascript
// 2.4.1 provider.js - 新增推理模型配置
const REASONING_MODELS = {
  'o1-mini': { type: 'reasoning', supportsTools: false, maxTokens: 25000 },
  'o1-preview': { type: 'reasoning', supportsTools: false, maxTokens: 25000 },
  'o3-mini': { type: 'reasoning', supportsTools: false, maxTokens: 100000 },
  'deepseek-r1': { type: 'reasoning', supportsTools: true, maxTokens: 64000 },
  'deepseek-r1-distill-qwen-32b': { type: 'reasoning', supportsTools: true, maxTokens: 32000 }
}

// 2.4.2 agent-chat.js - 根据模型类型调整配置
_getAgentConfig() {
  const modelId = this.model.toLowerCase()

  // 检测是否是推理模型
  const isReasoningModel = Object.keys(REASONING_MODELS)
    .some(name => modelId.includes(name))

  if (isReasoningModel) {
    const config = REASONING_MODELS[Object.keys(REASONING_MODELS)
      .find(name => modelId.includes(name))]

    return {
      // 推理模型通常不需要 system prompt
      includeSystemInMessages: false,
      // 推理模型不支持工具或需要特殊处理
      supportsTools: config.supportsTools,
      // 增大 maxTokens
      maxTokens: config.maxTokens
    }
  }

  return {
    includeSystemInMessages: true,
    supportsTools: true,
    maxTokens: 8192
  }
}
```

**收益**：

- 支持 o1/o3/DeepSeek R1 等推理模型
- 自动适配推理模型的特殊配置
- 优化推理任务的性能

---

#### 2.5 中间件系统

**现状**：缺乏统一的中间件机制

**优化位置**：新增 `src/middleware/ai-middleware.js`

**建议新增**：

```javascript
// src/middleware/ai-middleware.js
const { extractReasoningMiddleware, defaultSettingsMiddleware, withTelemetry } = require('ai');

/**
 * 创建 AI 中间件
 */
function createAIMiddleware(options = {}) {
  const middlewares = [];

  // 1. 推理提取中间件
  if (options.extractReasoning !== false) {
    middlewares.push(
      extractReasoningMiddleware({
        tagName: 'thinking',
        onChunk: (chunk) => {
          options.onReasoning?.(chunk);
        },
      })
    );
  }

  // 2. 默认设置中间件
  middlewares.push(
    defaultSettingsMiddleware({
      settings: {
        [options.defaultModel]: {
          temperature: options.temperature || 0.7,
          maxTokens: options.maxTokens || 8192,
        },
      },
    })
  );

  // 3. 遥测中间件
  if (options.telemetry) {
    middlewares.push(
      withTelemetry({
        serviceName: 'foliko-agent',
        metadata: {
          version: options.version,
          sessionId: options.sessionId,
        },
      })
    );
  }

  return middlewares;
}

/**
 * 创建日志中间件（自定义）
 */
function createLoggingMiddleware() {
  return {
    async wrapModel(model, { doStream }) {
      return {
        doStream: async (prompt, options) => {
          const startTime = Date.now();
          console.log('[AI] Request started:', {
            promptLength: typeof prompt === 'string' ? prompt.length : 'array',
          });

          try {
            const result = await doStream();
            const duration = Date.now() - startTime;
            console.log('[AI] Request completed:', { duration });
            return result;
          } catch (error) {
            console.error('[AI] Request failed:', error.message);
            throw error;
          }
        },
      };
    },
  };
}

module.exports = {
  createAIMiddleware,
  createLoggingMiddleware,
};
```

**收益**：

- 统一的日志、监控、遥测
- 推理过程可追踪
- 支持自定义中间件扩展

---

#### 2.6 Embeddings 支持

**现状**：未实现嵌入功能

**优化位置**：新增到 `src/plugins/ai-plugin.js` 或创建新文件

**建议新增**：

```javascript
// src/plugins/embeddings-plugin.js 或在 ai-plugin.js 中新增
const { embed, embedMany } = require('ai');

class AIPlugin extends Plugin {
  // ... 现有代码

  /**
   * 获取嵌入模型
   */
  getEmbeddingModel() {
    if (this._embeddingModel) return this._embeddingModel;

    const embeddingModelId = this._getEmbeddingModelId();
    this._embeddingModel = this._embeddingProvider.textEmbeddingModel(embeddingModelId);

    return this._embeddingModel;
  }

  _getEmbeddingModelId() {
    const provider = this.config.provider?.toLowerCase();
    const modelMap = {
      openai: 'text-embedding-3-small',
      deepseek: 'deepseek-embed',
      ollama: 'nomic-embed-text',
    };
    return modelMap[provider] || 'text-embedding-3-small';
  }

  /**
   * 嵌入单个文本
   */
  async embedText(text) {
    const { embedding } = await embed({
      model: this.getEmbeddingModel(),
      value: text,
    });
    return embedding;
  }

  /**
   * 批量嵌入
   */
  async embedTexts(texts) {
    const { embeddings } = await embedMany({
      model: this.getEmbeddingModel(),
      values: texts,
    });
    return embeddings;
  }
}
```

**收益**：

- 支持 RAG 知识库构建
- 语义搜索基础
- 文本相似度计算

---

### 🟢 【低优先级】

#### 2.7 错误处理增强

**现状**：基础错误捕获

**优化位置**：`src/core/agent-chat.js`

**建议修改**：

```javascript
// 2.7.1 新增错误类型导入
const {
  AI_APICallError,
  AI_RetryableError,
  AI_NoSuchModelError,
  AIInvalidPromptError
} = require('ai')

// 2.7.2 增强错误处理
async chat(message, options = {}) {
  try {
    // ... 现有代码
  } catch (error) {
    if (error instanceof AI_APICallError) {
      switch (error.statusCode) {
        case 400:
          throw new Error(`无效请求: ${error.message}`)
        case 401:
          throw new Error('API 密钥无效或已过期')
        case 429:
          throw new Error('请求频率超限，请稍后重试')
        case 500:
        case 502:
        case 503:
          throw new Error(`AI 服务暂时不可用: ${error.message}`)
        default:
          throw error
      }
    } else if (error instanceof AI_NoSuchModelError) {
      throw new Error(`模型 ${this.model} 不存在或不可用`)
    } else if (error instanceof AIInvalidPromptError) {
      throw new Error(`提示词无效: ${error.message}`)
    }
    throw error
  }
}

// 2.7.3 重试装饰器
async withRetry(fn, maxRetries = 3, delayMs = 1000) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn()
    } catch (error) {
      if (i === maxRetries - 1) throw error
      if (!this._isRetryable(error)) throw error

      console.log(`[AgentChat] Retry ${i + 1}/${maxRetries} after ${delayMs}ms`)
      await new Promise(r => setTimeout(r, delayMs))
      delayMs *= 2  // 指数退避
    }
  }
}

_isRetryable(error) {
  if (error instanceof AI_APICallError) {
    return [429, 500, 502, 503].includes(error.statusCode)
  }
  return false
}
```

**收益**：

- 更健壮的错误恢复
- 用户友好的错误提示
- 自动重试机制

---

#### 2.8 MCP Elicitation 支持

**现状**：使用 MCP 但未支持用户确认

**优化位置**：`src/executors/mcp-executor.js`

**建议修改**：

```javascript
// 2.8.1 新增 MCP Elicitation 支持
async connect() {
  // ... 现有代码

  // 启用 Elicitation（用户确认）
  if (this.client && typeof this.client.requestConfirmation === 'function') {
    this._enableElicitation = true
  }
}

// 2.8.2 工具调用时请求确认
async executeToolWithConfirmation(toolName, args) {
  if (!this._enableElicitation) {
    return this.executeTool(toolName, args)
  }

  // 发送确认请求给用户
  const confirmed = await this._requestUserConfirmation({
    toolName,
    args,
    description: this._getToolDescription(toolName)
  })

  if (!confirmed) {
    return { error: 'User rejected tool execution' }
  }

  return this.executeTool(toolName, args)
}
```

**收益**：

- 用户可控制工具执行
- 提高安全性
- 支持敏感操作确认

---

## 三、优化优先级汇总

| 优先级 | 优化项                    | 状态      | 收益               | 影响范围                       |
| ------ | ------------------------- | --------- | ------------------ | ------------------------------ |
| 🔴 高  | `generateObject` 意图识别 | ✅ 已完成 | 类型安全、智能路由 | `agent-chat.js`                |
| 🔴 高  | Prompt Caching            | ✅ 已完成 | 降低30% token消耗  | `agent-chat.js`                |
| 🟡 中  | `smoothStream` 流式增强   | 待做      | 更流畅体验         | `agent-chat.js`                |
| 🟡 中  | 推理模型支持              | 待做      | o1/R1 优化         | `provider.js`, `agent-chat.js` |
| 🟡 中  | 中间件系统                | 待做      | 统一监控/日志      | 新建 `middleware/`             |
| 🟡 中  | Embeddings                | 待做      | RAG 基础           | `ai-plugin.js`                 |
| 🟢 低  | 错误处理增强              | 待做      | 更健壮             | `agent-chat.js`                |
| 🟢 低  | MCP Elicitation           | 待做      | 用户控制           | `mcp-executor.js`              |

---

## 四、实施路线图

### 第一阶段（立即可做）- ✅ 已完成

```
✅ generateObject 意图识别
   └── 在 agent-chat.js 新增 _classifyIntent() 方法
   └── 新增 IntentClassificationSchema, TaskStructuredSchema, SummarySchema
   └── 新增 configureIntentClassification(), getLastIntent(), getCacheStatus()

✅ Prompt Caching 集成
   └── 在 _buildSystemPrompt() 中使用缓存机制
   └── 新增 _supportsPromptCache(), _applyPromptCacheToMessages()
   └── 新增 configurePromptCache() 配置方法
```

### 第二阶段（1周内）

```
📦 smoothStream 流式增强
    └── 在 stream() 中添加 smoothStream 配置

📦 推理模型支持
    └── 在 provider.js 新增 REASONING_MODELS 配置

📦 错误处理增强
    └── 使用 AI SDK 错误类型替换基础 catch
```

### 第三阶段（长期）

```
📦 中间件系统
    └── 新建 src/middleware/ai-middleware.js

📦 Embeddings 支持
    └── 在 ai-plugin.js 新增 embedText/embedTexts 方法

📦 MCP Elicitation
    └── 在 mcp-executor.js 新增用户确认机制
```

---

## 五、新增配置选项

### 意图识别配置

```javascript
const agent = new AgentChatHandler(agent, {
  // 意图识别（默认开启）
  enableIntentClassification: true,
  // 可选：用于意图识别的专用模型
  intentModel: openai('gpt-4o-mini'),
});

// 运行时配置
agent.configureIntentClassification({
  enabled: true,
  model: openai('gpt-4o-mini'),
});

// 获取上次意图识别结果
const intent = agent.getLastIntent();
// { intent: 'create', confidence: 0.95, entities: [...], suggestedTools: [...] }
```

### Prompt Caching 配置

```javascript
const agent = new AgentChatHandler(agent, {
  // Prompt Caching（默认开启）
  enablePromptCache: true,
  // 缓存有效期（默认 1 小时）
  cacheMaxAgeMs: 1000 * 60 * 60,
});

// 运行时配置
agent.configurePromptCache({
  enabled: true,
  maxAgeMs: 1000 * 60 * 30, // 30 分钟
});

// 查看缓存状态
const status = agent.getCacheStatus();
// { promptCache: { enabled: true, supported: true, ... }, intentClassification: {...} }
```

### chat() / chatStream() 返回值变化

```javascript
// chat() 返回值新增 intent 字段
const result = await agent.chat('帮我创建一个文件');
// { success: true, message: "...", stepCount: 3, intent: { intent: 'create', confidence: 0.9, ... } }

// chatStream() 支持接收 intent 事件
for await (const chunk of agent.chatStream('查询天气')) {
  if (chunk.type === 'intent') {
    console.log('意图:', chunk.intent); // { intent: 'query', confidence: 0.95, ... }
  }
}

// 监听意图识别事件
agent.on('intent-classified', ({ message, intent }) => {
  console.log(`消息 "${message}" 被识别为: ${intent.intent}`);
});

agent.on('intent-detected', ({ message, intent }) => {
  console.log(`流式模式检测到意图: ${intent.intent}`);
});
```

---

## 六、需要安装的包

```bash
# 基础已安装
npm install ai @ai-sdk/openai @ai-sdk/anthropic

# 可能需要添加（根据需求）
npm install @ai-sdk/google        # Gemini 模型支持
npm install @ai-sdk/deepseek      # DeepSeek 模型支持
npm install @ai-sdk/amazon-bedrock # AWS Bedrock 支持
```

---

## 七、参考资料

- [AI SDK 官方文档](https://ai-sdk.dev/docs/getting-started)
- [AI SDK Cookbook](https://ai-sdk.dev/cookbook)
- [AI SDK API Reference](https://ai-sdk.dev/docs/api-reference)

---

_文档生成时间：2025-01-25_
_基于 AI SDK v6 版本分析_
_高优先级优化完成时间：2025-01-26_
