# 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 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. 配置变更测试:验证配置更新后立即生效