From 28a0c3cfe40a05f2e3e4d8b744724459cff61f09 Mon Sep 17 00:00:00 2001 From: glz <694770232@qq.com> Date: Tue, 23 Jun 2026 17:55:48 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(service):=20=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E6=9C=9F=E5=88=8A=E7=9B=B8=E5=85=B3=E5=AE=9E=E4=BD=93=E7=9A=84?= =?UTF-8?q?=E5=85=B3=E8=81=94=E5=88=A0=E9=99=A4=E4=B8=8Eprompt=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 为JournalPageTaskService新增BasePrompt和CustomPrompt字段的赋值映射 2. 为JournalService注入JournalPageTaskAnswerRepository并完善关联删除逻辑,先删除任务答案再删除任务本身 --- .../JournalPageTaskService.cs | 2 ++ .../JournalService.cs | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs index 6eaac9f..e4d55ae 100644 --- a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs @@ -66,6 +66,8 @@ public class JournalPageTaskService(BaseRepository journalRepository, O task.Expression = input.Expression; task.Persuasiveness = input.Persuasiveness; task.AnswerTime = input.AnswerTime; + task.BasePrompt = input.BasePrompt; + task.CustomPrompt = input.CustomPrompt; var no = input.No.Split('-').Select(int.Parse).ToArray(); diff --git a/QYZH.InteractiveMagazine.Service/JournalService.cs b/QYZH.InteractiveMagazine.Service/JournalService.cs index 25dedce..129a5dc 100644 --- a/QYZH.InteractiveMagazine.Service/JournalService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalService.cs @@ -1,4 +1,4 @@ -using Mapster; +using Mapster; using Microsoft.Extensions.Logging; using QYZH.InteractiveMagazine.Common.Extensions; using QYZH.InteractiveMagazine.Infrastructure.OSS; @@ -18,6 +18,7 @@ namespace QYZH.InteractiveMagazine.Service; public class JournalService(BaseRepository JournalPageRepository, BaseRepository JournalPageTaskRepository, + BaseRepository JournalPageTaskAnswerRepository, BaseRepository JournalCatalogRepository, BaseRepository dotFileRepository, BaseRepository dotFileDetailRepository, OssService ossService, ILogger logger) : BaseRepository, IJournalService @@ -210,6 +211,20 @@ public class JournalService(BaseRepository JournalPageRepository, await base.DeleteAsync(d => ids.Contains(d.Id)); await JournalPageRepository.DeleteAsync(d => ids.Contains(d.JournalId)); await JournalCatalogRepository.DeleteAsync(d => ids.Contains(d.JournalId)); + + // 先查询要删除的 JournalPageTask Id 列表 + var taskIds = await JournalPageTaskRepository.Queryable() + .Where(d => ids.Contains(d.JournalId)) + .Select(d => d.Id) + .ToListAsync(); + + // 删除 JournalPageTaskAnswer + if (taskIds.Any()) + { + await JournalPageTaskAnswerRepository.DeleteAsync(d => taskIds.Contains(d.JournalPageTaskId)); + } + + // 再删除 JournalPageTask await JournalPageTaskRepository.DeleteAsync(d => ids.Contains(d.JournalId)); return true; }); From bf333cd7180b22efa9d8646c1af1d85b51380215 Mon Sep 17 00:00:00 2001 From: glz <694770232@qq.com> Date: Wed, 24 Jun 2026 15:06:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EAI=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E6=9C=8D=E5=8A=A1=EF=BC=8C=E9=87=8D=E6=9E=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=8F=90=E7=A4=BA=E8=AF=8D=E7=9B=B8=E5=85=B3=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增AI聊天服务接口、实现、控制器及相关DTO、配置类 2. 调整JournalPageTaskTypeEnum枚举值修正 3. 合并任务的基础Prompt和自定义Prompt为单个Prompt字段 4. 精简任务输出DTO冗余属性 --- .../IAiChatService.cs | 16 ++ .../Dto/Ai/AiChatDto.cs | 23 +++ .../Dto/Journal/JournalPageTaskOutput.cs | 77 +-------- .../Dto/Journal/JournalPageTaskUpdateInput.cs | 17 +- .../Entity/JournalPageTask.cs | 11 +- .../Enum/JournalPageTaskTypeEnum.cs | 2 +- .../Settings/AiChatSettings.cs | 37 +++++ .../AiChatService.cs | 154 ++++++++++++++++++ .../JournalPageTaskService.cs | 7 +- .../Controllers/AiChatController.cs | 50 ++++++ .../appsettings.json | 8 + 11 files changed, 300 insertions(+), 102 deletions(-) create mode 100644 QYZH.InteractiveMagazine.IService/IAiChatService.cs create mode 100644 QYZH.InteractiveMagazine.Models/Dto/Ai/AiChatDto.cs create mode 100644 QYZH.InteractiveMagazine.Models/Settings/AiChatSettings.cs create mode 100644 QYZH.InteractiveMagazine.Service/AiChatService.cs create mode 100644 QYZH.InteractiveMagazine.WebApi/Controllers/AiChatController.cs diff --git a/QYZH.InteractiveMagazine.IService/IAiChatService.cs b/QYZH.InteractiveMagazine.IService/IAiChatService.cs new file mode 100644 index 0000000..d355f8c --- /dev/null +++ b/QYZH.InteractiveMagazine.IService/IAiChatService.cs @@ -0,0 +1,16 @@ +using QYZH.InteractiveMagazine.Models.Dto; + +namespace QYZH.InteractiveMagazine.IService; + +/// +/// AI聊天服务接口 +/// +public interface IAiChatService +{ + /// + /// 发送消息进行AI对话 + /// + /// 聊天输入 + /// AI返回的提示词内容 + Task ChatAsync(AiChatInput input); +} diff --git a/QYZH.InteractiveMagazine.Models/Dto/Ai/AiChatDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Ai/AiChatDto.cs new file mode 100644 index 0000000..ca56d5c --- /dev/null +++ b/QYZH.InteractiveMagazine.Models/Dto/Ai/AiChatDto.cs @@ -0,0 +1,23 @@ +namespace QYZH.InteractiveMagazine.Models.Dto; + +/// +/// AI聊天输入 +/// +public class AiChatInput +{ + /// + /// 用户需求文本 + /// + public string Message { get; set; } = string.Empty; +} + +/// +/// AI聊天输出 +/// +public class AiChatOutput +{ + /// + /// AI返回的内容(Markdown格式提示词) + /// + public string Content { get; set; } = string.Empty; +} diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskOutput.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskOutput.cs index 4a531fd..7bb9e41 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskOutput.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskOutput.cs @@ -19,11 +19,6 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public long JournalPageId { get; set; } - /// - /// 学科Id - /// - public long SubjectId { get; set; } - /// /// 题号 /// @@ -36,33 +31,10 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal public string ShowType => Type.GetDescription(); - private string _task; - /// - /// 问题 - /// - public string Task - { - get { return _task.AddDomain(DomainHelper.OssDomain); } - set { _task = value; } - } - /// /// 答案列表 /// public List Answers { get; set; } - - private string _imageUrl; - /// - /// 图片地址 - /// - public string ImageUrl - { - get { return DomainHelper.OssFullUrl(_imageUrl); } - set { _imageUrl = value; } - } - - public List ImageUrls { get; set; } - /// /// 积分 /// @@ -98,55 +70,10 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public int AnswerTime { get; set; } - private string _audioUrl; /// - /// 音频地址 + /// Prompt配置 /// - public string AudioUrl - { - get { return DomainHelper.OssFullUrl(_audioUrl); } - set { _audioUrl = value; } - } - - private string _videoUrl; - /// - /// 视频地址 - /// - public string VideoUrl - { - get { return DomainHelper.OssFullUrl(_videoUrl); } - set { _videoUrl = value; } - } - - private string _pointsUrl; - /// - /// 点位数据地址 - /// - public string PointsUrl - { - get { return DomainHelper.OssFullUrl(_pointsUrl); } - set { _pointsUrl = value; } - } - - /// - /// 音频开始时间 - /// - public long AudioStartTime { get; set; } - - /// - /// 音频结束时间 - /// - public long AudioEndTime { get; set; } - - /// - /// 知识点 - /// - public string KnowledgePointIds { get; set; } - - /// - /// 年级 - /// - public int Grade { get; set; } + public string Prompt { get; set; } } /// diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs index dc0b78d..c797da2 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs @@ -1,4 +1,4 @@ -using QYZH.InteractiveMagazine.Models.Enum; +using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Models.Enum; using System; using System.Collections.Generic; @@ -67,18 +67,9 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public int AnswerTime { get; set; } /// - /// Desc:基础Prompt配置ID(为空则使用IsDefault=1的模板) - /// Default: - /// Nullable:True - /// - public string BasePrompt { get; set; } - - /// - /// Desc:个性化Prompt(追加到基础Prompt后面,可为空) - /// Default: - /// Nullable:True - /// - public string CustomPrompt { get; set; } + /// Prompt配置 + /// + public string Prompt { get; set; } } diff --git a/QYZH.InteractiveMagazine.Models/Entity/JournalPageTask.cs b/QYZH.InteractiveMagazine.Models/Entity/JournalPageTask.cs index ee69e2c..c7927b9 100644 --- a/QYZH.InteractiveMagazine.Models/Entity/JournalPageTask.cs +++ b/QYZH.InteractiveMagazine.Models/Entity/JournalPageTask.cs @@ -122,18 +122,11 @@ namespace QYZH.InteractiveMagazine.Models.Entity public bool NeedAiProcess { get; set; } /// - /// Desc:基础Prompt配置ID(为空则使用IsDefault=1的模板) + /// Desc:Prompt配置 /// Default: /// Nullable:True /// - public string BasePrompt { get; set; } - - /// - /// Desc:个性化Prompt(追加到基础Prompt后面,可为空) - /// Default: - /// Nullable:True - /// - public string CustomPrompt { get; set; } + public string Prompt { get; set; } /// /// Desc:作答参考时间 diff --git a/QYZH.InteractiveMagazine.Models/Enum/JournalPageTaskTypeEnum.cs b/QYZH.InteractiveMagazine.Models/Enum/JournalPageTaskTypeEnum.cs index 88d562d..af045c4 100644 --- a/QYZH.InteractiveMagazine.Models/Enum/JournalPageTaskTypeEnum.cs +++ b/QYZH.InteractiveMagazine.Models/Enum/JournalPageTaskTypeEnum.cs @@ -16,5 +16,5 @@ public enum JournalPageTaskTypeEnum /// 问答题 /// [Description("主观题")] - TaskAnswer = 4 + TaskAnswer = 0 } diff --git a/QYZH.InteractiveMagazine.Models/Settings/AiChatSettings.cs b/QYZH.InteractiveMagazine.Models/Settings/AiChatSettings.cs new file mode 100644 index 0000000..fc9ef85 --- /dev/null +++ b/QYZH.InteractiveMagazine.Models/Settings/AiChatSettings.cs @@ -0,0 +1,37 @@ +namespace QYZH.InteractiveMagazine.Models.Settings; + +/// +/// AI聊天配置 +/// +public class AiChatSettings +{ + /// + /// API密钥 + /// + public string? ApiKey { get; set; } + + /// + /// API基础地址(OpenAI兼容) + /// + public string? BaseUrl { get; set; } + + /// + /// 模型名称 + /// + public string? Model { get; set; } + + /// + /// 请求超时时间(秒) + /// + public int TimeoutSeconds { get; set; } = 300; + + /// + /// 最大生成Token数 + /// + public int MaxTokens { get; set; } = 2000; + + /// + /// 采样温度(0-2,值越低输出越确定) + /// + public double Temperature { get; set; } = 0.5; +} diff --git a/QYZH.InteractiveMagazine.Service/AiChatService.cs b/QYZH.InteractiveMagazine.Service/AiChatService.cs new file mode 100644 index 0000000..2f29ce4 --- /dev/null +++ b/QYZH.InteractiveMagazine.Service/AiChatService.cs @@ -0,0 +1,154 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using QYZH.InteractiveMagazine.IService; +using QYZH.InteractiveMagazine.Models.Common; +using QYZH.InteractiveMagazine.Models.Dto; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace QYZH.InteractiveMagazine.Service; + +/// +/// AI聊天服务实现(OpenAI API规范) +/// +public class AiChatService( + IHttpClientFactory httpClientFactory, + IConfiguration configuration, + ILogger logger) : IAiChatService +{ + /// + /// 预设系统提示词 + /// + private const string SystemPrompt = """ + # 提示词:AI 优化“题目评分/报告提示词” + + 你是一个专业的提示词优化专家。你的任务是**将用户输入的粗糙、口语化的“题目评分/报告提示词”重构为结构清晰、指令明确、便于 AI 直接执行的标准化提示词**。 + + 用户(题目制作者)当前输入的内容可能包含:题目描述、作答要求、打分规则、评分维度、报告层级、示例等,但组织混乱、表述模糊。你需要**保留所有原始信息,不增删任何实质性规则**,仅优化其结构、逻辑层次和表达精度。 + + --- + + ## 优化原则 + + 1. **信息完整**:用户原文中的所有要点、示例、层级区分必须全部保留。 + 2. **结构清晰**:将内容归入标准模块(如 `任务目标`、`输入格式`、`评分标准`、`报告生成要求`)。 + 3. **指令明确**:将模糊表述(如“要写得好一点”)转化为可操作的判定条件(如“必须包含三层结构:解释原因 + 表达情绪 + 提出方案”)。 + 4. **语言精练**:去除冗余修饰,保留关键限定词(如“仅”“必须”“至少”)。 + 5. **格式统一**:最终输出为 Markdown 格式,使用标题(`#` `##` `###`)、列表(`-`)、加粗/斜体等提升可读性。 + + --- + + ## 优化步骤 + + 1. **解析原文**:通读用户输入,标注出: + - 题目背景 / 情境 + - 学生作答要求 + - 评分维度(优秀/一般/薄弱)及其具体判定条件 + - 报告层级及其对应的评语模板或生成逻辑 + - 任何示例答案 + 2. **重组结构**:按以下标准模板组织内容(可灵活调整章节名称): + - `## 任务概述`(题目 + 要求) + - `## 输入数据`(学生作答的内容) + - `## 评分标准`(分档描述,含判定规则) + - `## 报告生成规范`(层级名称、触发条件、评语示例/生成规则) + - `## 注意事项`(如有特殊约束) + 3. **润色表达**: + - 将“可能”“大概”等不确定词改为明确的“必须”“至少”; + - 将并列条件用编号列表(1. 2. 3.)拆分; + - 将示例单独以代码块或引用块呈现,避免与规则混淆。 + 4. **保持原意**:不得添加用户未提及的新评分维度或报告层级,也不得删除任何已有规则。 + + --- + + ## 输出格式要求 + + - 只输出优化后的完整提示词(即 AI 可直接使用的评分/报告 prompt),不要输出分析过程。 + - 使用 Markdown 语法,标题层级从 `#` 开始。 + - 所有原有示例必须原样保留,并标明“示例”或放在引用块中。 + + --- + + 现在,请对**当前用户输入的原始提示词**执行上述优化过程,仅输出优化后的 Markdown 格式提示词。 + """; + + /// + /// AI聊天,根据用户需求生成提示词 + /// + public async Task ChatAsync(AiChatInput input) + { + if (string.IsNullOrWhiteSpace(input.Message)) + { + throw new BusinessException("消息内容不能为空", 400); + } + + var apiKey = configuration["AiChat:ApiKey"]; + var baseUrl = configuration["AiChat:BaseUrl"]; + var model = configuration["AiChat:Model"]; + var timeoutSeconds = configuration.GetValue("AiChat:TimeoutSeconds"); + var maxTokens = configuration.GetValue("AiChat:MaxTokens"); + var temperature = configuration.GetValue("AiChat:Temperature"); + + if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(baseUrl) || string.IsNullOrWhiteSpace(model)) + { + throw new BusinessException("AI聊天服务配置不完整,请检查 AiChat 配置节", 500); + } + + logger.LogInformation("开始调用AI聊天服务,消息长度:{Length}", input.Message.Length); + + // 构建 OpenAI Chat Completions 请求体 + var requestBody = new + { + model = model, + messages = new[] + { + new { role = "system", content = SystemPrompt }, + new { role = "user", content = input.Message } + }, + max_tokens = maxTokens, + temperature = temperature + }; + + var jsonContent = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }); + + // 创建 HttpClient 并发起请求 + var client = httpClientFactory.CreateClient(); + client.Timeout = TimeSpan.FromSeconds(timeoutSeconds > 0 ? timeoutSeconds : 300); + var request = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl.TrimEnd('/')}/chat/completions"); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); + request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); + + var response = await client.SendAsync(request); + var responseContent = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) + { + logger.LogError("AI聊天服务调用失败,状态码:{StatusCode},响应:{Response}", response.StatusCode, responseContent); + throw new BusinessException($"AI服务调用失败:{response.StatusCode}", 500); + } + + // 解析 OpenAI 响应 + using var doc = JsonDocument.Parse(responseContent); + var choices = doc.RootElement.GetProperty("choices"); + if (choices.GetArrayLength() == 0) + { + throw new BusinessException("AI未返回有效内容", 500); + } + + var content = choices[0] + .GetProperty("message") + .GetProperty("content") + .GetString(); + + logger.LogInformation("AI聊天服务调用成功,返回内容长度:{Length}", content?.Length ?? 0); + + return new AiChatOutput + { + Content = content ?? string.Empty + }; + } +} diff --git a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs index e4d55ae..504f9e5 100644 --- a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs @@ -1,4 +1,4 @@ -using Mapster; +using Mapster; using QYZH.InteractiveMagazine.Common.Extensions; using QYZH.InteractiveMagazine.Infrastructure.OSS; using QYZH.InteractiveMagazine.IService; @@ -66,8 +66,7 @@ public class JournalPageTaskService(BaseRepository journalRepository, O task.Expression = input.Expression; task.Persuasiveness = input.Persuasiveness; task.AnswerTime = input.AnswerTime; - task.BasePrompt = input.BasePrompt; - task.CustomPrompt = input.CustomPrompt; + task.Prompt = input.Prompt; var no = input.No.Split('-').Select(int.Parse).ToArray(); @@ -97,7 +96,6 @@ public class JournalPageTaskService(BaseRepository journalRepository, O JournalPageId = task.JournalPageId, No = task.No, Type = task.Type, - Task = task.Task, Points = task.Points, GrowthPoint = task.GrowthPoint ?? 0, Comprehension = task.Comprehension, @@ -105,6 +103,7 @@ public class JournalPageTaskService(BaseRepository journalRepository, O Expression = task.Expression, Persuasiveness = task.Persuasiveness, AnswerTime = task.AnswerTime, + Prompt = task.Prompt }; // 查询答案列表 diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/AiChatController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/AiChatController.cs new file mode 100644 index 0000000..8e1d9c9 --- /dev/null +++ b/QYZH.InteractiveMagazine.WebApi/Controllers/AiChatController.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Mvc; +using QYZH.InteractiveMagazine.IService; +using QYZH.InteractiveMagazine.Models.Common; +using QYZH.InteractiveMagazine.Models.Dto; +using QYZH.InteractiveMagazine.Models.Enum; + +namespace QYZH.InteractiveMagazine.WebApi.Controllers; + +/// +/// AI聊天控制器 +/// +[Route("api/[controller]")] +[ApiController] +[ApiExplorerSettings(GroupName = nameof(ApiVersionEnum.Platform))] +public class AiChatController : BaseController +{ + private readonly IAiChatService _aiChatService; + private readonly ILogger _logger; + + public AiChatController(IAiChatService aiChatService, ILogger logger) + { + _aiChatService = aiChatService; + _logger = logger; + } + + /// + /// AI聊天,根据需求生成提示词 + /// + /// 用户需求消息 + /// AI生成的提示词(Markdown格式) + [HttpPost] + public async Task> ChatAsync([FromBody] AiChatInput input) + { + try + { + var result = await _aiChatService.ChatAsync(input); + return Success(result, "AI聊天成功"); + } + catch (BusinessException ex) + { + _logger.LogWarning(ex, "AI聊天业务异常: {Message}", ex.Message); + return BaseResponse.Fail(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, "AI聊天系统异常,参数:{Input}", input); + return BaseResponse.Fail("AI聊天失败,请稍后重试"); + } + } +} diff --git a/QYZH.InteractiveMagazine.WebApi/appsettings.json b/QYZH.InteractiveMagazine.WebApi/appsettings.json index c2f66a5..d6d78f9 100644 --- a/QYZH.InteractiveMagazine.WebApi/appsettings.json +++ b/QYZH.InteractiveMagazine.WebApi/appsettings.json @@ -47,6 +47,14 @@ ] }, "AllowedHosts": "*", + "AiChat": { + "ApiKey": "Ollama", + "BaseUrl": "http://172.16.10.130:11434/v1/", + "Model": "qwen2.5vl:7b", + "TimeoutSeconds": 300, + "MaxTokens": 2000, + "Temperature": 0.5 + }, "AliyunOSSConfigs": { "AccessKeyID": "LTAI5tEBXGewpHSLiSxyx6Bf", "AccessKeySecret": "w29b8wkw6XQVL8GWXgp3ZesgYeDKvf",