Files
happy-life-star/.kiro/specs/coze-ai-integration/design.md
T

295 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design Document
## Overview
本设计文档描述了Coze AI通用接口调用服务的架构设计,以及爽文剧本AI生成功能的实现方案。核心目标是重构AiChatServiceImpl,提供一个通用的、可配置的AI接口调用方法,支持通过config_key获取配置并调用Coze工作流API。
## Architecture
### 系统架构图
```mermaid
graph TB
subgraph "Controller Layer"
EC[EpicScriptController]
end
subgraph "Service Layer"
ESS[EpicScriptServiceImpl]
ACS[AiChatServiceImpl]
AICS[AiConfigServiceImpl]
end
subgraph "Data Layer"
ACM[AiConfigMapper]
ESM[EpicScriptMapper]
end
subgraph "External"
COZE[Coze API]
end
EC --> ESS
ESS --> ACS
ACS --> AICS
AICS --> ACM
ESS --> ESM
ACS --> COZE
```
### 调用流程图
```mermaid
sequenceDiagram
participant C as Controller
participant ESS as EpicScriptService
participant ACS as AiChatService
participant AICS as AiConfigService
participant DB as Database
participant COZE as Coze API
C->>ESS: createScript(request)
ESS->>ESS: assembleInput(request)
ESS->>ACS: callWorkflowByConfigKey(configKey, input, userId)
ACS->>AICS: getByConfigKey(configKey)
AICS->>DB: SELECT * FROM t_ai_config WHERE config_key = ?
DB-->>AICS: AiConfig
AICS-->>ACS: AiConfig
ACS->>ACS: buildWorkflowRequest(config, input, userId)
ACS->>COZE: POST /v1/workflow/stream_run
COZE-->>ACS: SSE Stream Response
ACS->>ACS: parseStreamResponse(response)
ACS-->>ESS: AI Generated Content
ESS->>ESS: parseAndSaveScript(content)
ESS->>DB: INSERT INTO t_epic_script
ESS-->>C: EpicScriptResponse
```
## Components and Interfaces
### 1. AiChatService 接口扩展
```java
/**
* AI聊天服务接口 - 新增通用工作流调用方法
*/
public interface AiChatService {
// ... 现有方法 ...
/**
* 通过配置键调用Coze工作流API
*
* @param configKey AI配置键(如:coze.course.life.generate
* @param input 输入参数,将作为parameters.input传递给工作流
* @param userId 用户ID
* @return AI生成的内容
*/
String callWorkflowByConfigKey(String configKey, String input, String userId);
/**
* 通过配置键调用Coze工作流API(带自定义参数)
*
* @param configKey AI配置键
* @param parameters 自定义参数Map,将合并到请求的parameters中
* @param userId 用户ID
* @return AI生成的内容
*/
String callWorkflowByConfigKey(String configKey, Map<String, Object> parameters, String userId);
}
```
### 2. AiConfigService 接口扩展
```java
/**
* AI配置服务接口 - 新增按配置键获取方法
*/
public interface AiConfigService {
// ... 现有方法 ...
/**
* 根据配置键获取AI配置
*
* @param configKey 配置键
* @return AI配置,如果不存在或已禁用则返回null
*/
AiConfig getByConfigKey(String configKey);
}
```
### 3. EpicScriptService 接口(无变化)
现有接口保持不变,实现层调用新的AI服务方法。
## Data Models
### Coze工作流请求格式
```json
{
"workflow_id": "7586262962160762926",
"user_id": "user_123",
"stream": true,
"parameters": {
"input": "用户填写的信息组装后的字符串",
"user_id": "user_123"
}
}
```
### Coze工作流响应格式(SSE
```
id: 0
event: Message
data: {"node_title":"End","node_execute_uuid":"","usage":{"token_count":1571,"output_count":812,"input_count":759},"node_is_finish":true,"node_seq_id":"0","content":"{\"output\":\"AI生成的内容...\"}","content_type":"text","node_type":"End","node_id":"900001"}
id: 1
event: Done
data: {"node_execute_uuid":"","debug_url":"..."}
```
### 用户输入组装格式
```
剧本标题:{title}
主题/渴望:{theme}
风格:{style}
篇幅:{length}
序幕(低谷回响):{plotIntro}
转折(契机出现):{plotTurning}
高潮(命运抉择):{plotClimax}
结局(新的开始):{plotEnding}
```
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
### Property 1: Request Format Correctness (请求格式正确性)
*For any* valid AiConfig and input parameters, the generated Coze workflow request SHALL contain:
- workflow_id from the AiConfig
- user_id from the call parameters
- stream set to true
- parameters.input containing the input string
- Authorization header with "Bearer {api_token}"
- Content-Type header set to "application/json"
**Validates: Requirements 2.1, 2.2, 2.3, 2.4, 2.5, 2.6**
### Property 2: Stream Response Parsing (流式响应解析)
*For any* valid Coze SSE stream response containing an "event: Message" line followed by a "data:" line with JSON containing "node_type": "End" and a "content" field with nested JSON containing "output", the parser SHALL extract and return the output value.
**Validates: Requirements 3.1, 3.2, 3.3**
### Property 3: Input Assembly Completeness (输入组装完整性)
*For any* EpicScriptCreateRequest with non-null field values, the assembled input string SHALL contain all provided field values (title, theme, style, length, plotIntro, plotTurning, plotClimax, plotEnding).
**Validates: Requirements 4.2**
### Property 4: Configuration Application (配置应用正确性)
*For any* AiConfig retrieved by config_key:
- If is_enabled = 0, the system SHALL reject the config and throw an exception
- The api_base_url, api_token, and workflow_id SHALL be used in the request construction
- The custom_params SHALL be merged with runtime parameters
**Validates: Requirements 1.3, 5.2, 5.3**
### Property 5: Error Message Quality (错误消息质量)
*For any* error that occurs during AI API calls:
- The error message SHALL be meaningful and descriptive
- The error message SHALL NOT contain sensitive information such as API tokens
- The error message SHALL include relevant context (config_key, status code if applicable)
**Validates: Requirements 6.4, 6.5**
## Error Handling
### 错误类型和处理策略
| 错误类型 | 处理策略 | 返回值 |
|---------|---------|--------|
| 配置不存在 | 抛出RuntimeException | "未找到AI配置: {configKey}" |
| 配置已禁用 | 抛出RuntimeException | "AI配置已禁用: {configKey}" |
| API调用超时 | 重试(根据配置) | 重试失败后返回错误消息 |
| HTTP非200响应 | 记录日志,返回错误 | "AI服务调用失败: {statusCode}" |
| 流式解析失败 | 记录原始数据,返回错误 | "AI响应解析失败" |
| JSON解析失败 | 返回原始内容 | 原始content字符串 |
### 日志记录规范
```java
// 请求日志
log.info("调用Coze工作流: configKey={}, workflowId={}, userId={}", configKey, workflowId, userId);
// 响应日志
log.info("Coze工作流响应: configKey={}, contentLength={}", configKey, content.length());
// 错误日志
log.error("Coze工作流调用失败: configKey={}, statusCode={}, error={}", configKey, statusCode, errorMsg);
```
## Testing Strategy
### 单元测试
1. **AiConfigService测试**
- 测试getByConfigKey返回正确配置
- 测试配置不存在时返回null
- 测试配置禁用时返回null
2. **请求构建测试**
- 测试buildWorkflowRequest生成正确的请求格式
- 测试参数合并逻辑
3. **响应解析测试**
- 测试parseStreamResponse正确解析SSE格式
- 测试extractOutputFromContent正确提取output字段
4. **输入组装测试**
- 测试assembleInput正确组装用户输入
### 属性测试
使用JUnit 5进行属性测试,每个属性测试至少运行100次迭代:
1. **Property 1: Request Format Correctness**
- 生成随机的AiConfig和输入参数
- 验证生成的请求包含所有必需字段
- 验证请求头正确设置
- **Feature: coze-ai-integration, Property 1: Request Format Correctness**
2. **Property 2: Stream Response Parsing**
- 生成各种有效的SSE格式响应
- 验证正确提取output内容
- 测试边界情况(空content、嵌套JSON等)
- **Feature: coze-ai-integration, Property 2: Stream Response Parsing**
3. **Property 3: Input Assembly Completeness**
- 生成随机的EpicScriptCreateRequest
- 验证所有非空字段都出现在组装结果中
- **Feature: coze-ai-integration, Property 3: Input Assembly Completeness**
4. **Property 4: Configuration Application**
- 生成随机的AiConfig
- 验证配置值正确应用到请求
- 验证禁用配置被拒绝
- **Feature: coze-ai-integration, Property 4: Configuration Application**
5. **Property 5: Error Message Quality**
- 模拟各种错误场景
- 验证错误消息有意义且不包含敏感信息
- **Feature: coze-ai-integration, Property 5: Error Message Quality**
### 集成测试
1. 端到端测试:从Controller到Coze API的完整调用流程
2. 配置变更测试:验证配置更新后立即生效