1 line
21 KiB
JSON
1 line
21 KiB
JSON
{"repo": "alpaert/imagemanager2", "files": {"src/ImageManager.Infrastructure/Services/DeepSeekRecommendService.cs": {"5a244d079fbe69f852aca988f8cf47788351616e": {"t": 1785746200.5486302, "n": 4301, "h": "515df3b71e471a80", "c": "using System.Text;\nusing System.Text.Json;\nusing ImageManager.Core.Models;\nusing ImageManager.Core.Services;\n\nnamespace ImageManager.Infrastructure.Services;\n\npublic class DeepSeekRecommendService : IAiRecommendService\n{\n private const string ApiEndpoint = \"https://api.deepseek.com/chat/completions\";\n private const string Model = \"deepseek-chat\";\n private const double Temperature = 0.4;\n\n private static readonly HttpClient _http = new();\n private string _apiKey = string.Empty;\n\n public bool IsAvailable => !string.IsNullOrEmpty(_apiKey);\n\n public void SetApiKey(string key) => _apiKey = key;\n\n public async Task<string> RecommendAsync(string userInput, List<TagMapping> tagMappings, CancellationToken ct = default)\n {\n if (string.IsNullOrEmpty(_apiKey)) return \"错误:未设置 API Key,请在内存与缓存设置中配置 DeepSeek API Key。\";\n if (tagMappings.Count == 0) return \"错误:本地标签库为空。\";\n\n try\n {\n var systemPrompt = BuildSystemPrompt();\n var userPrompt = BuildUserPrompt(userInput, tagMappings);\n\n var requestBody = new\n {\n model = Model,\n messages = new[]\n {\n new { role = \"system\", content = systemPrompt },\n new { role = \"user\", content = userPrompt }\n },\n temperature = Temperature,\n max_tokens = 1000,\n stream = false\n };\n\n var json = JsonSerializer.Serialize(requestBody);\n var content = new StringContent(json, Encoding.UTF8, \"application/json\");\n using var request = new HttpRequestMessage(HttpMethod.Post, ApiEndpoint) { Content = content };\n request.Headers.Add(\"Authorization\", $\"Bearer {_apiKey}\");\n\n using var response = await _http.SendAsync(request);\n\n if (!response.IsSuccessStatusCode)\n {\n var errBody = await response.Content.ReadAsStringAsync();\n return $\"API 请求失败 (HTTP {(int)response.StatusCode}): {errBody.Truncate(300)}\";\n }\n\n var responseBody = await response.Content.ReadAsStringAsync();\n using var doc = JsonDocument.Parse(responseBody);\n var reply = doc.RootElement\n .GetProperty(\"choices\")[0]\n .GetProperty(\"message\")\n .GetProperty(\"content\")\n .GetString() ?? \"(AI 返回为空)\";\n\n return reply.Trim();\n }\n catch (Exception ex)\n {\n return $\"请求异常: {ex.Message}\";\n }\n }\n\n private static string BuildSystemPrompt()\n {\n return \"\"\"\n 你是一个 AI 绘画标签搜索专家。用户会描述想要的图片类型,你需要从可用标签库中挑选最匹配的标签,组合成搜索字符串。\n\n 搜索语法规则:\n - 空格表示 AND(同时满足):girl outdoor → 搜索同时包含 girl 和 outdoor 的图片\n - 小写字母 o 表示 OR(满足其一):smile o laugh → 搜索包含 smile 或 laugh 的图片\n - 减号 - 表示 NOT(排除):-sketch → 排除包含 sketch 标签的图片\n - 可以组合使用:girl outdoor -sketch o smile → 同时满足 girl + outdoor,且不包含 sketch,或包含 smile\n\n 输出要求:\n - 每行输出一个推荐组合,不要编号\n - 每行格式:先用英文标签 + 搜索符号构成可搜索的字符串,然后用 \" → \" 分隔,后面跟对应的中文标签名\n - 示例格式:girl outdoor → 女孩 户外\n - 示例格式(带排除):girl outdoor -sketch → 女孩 户外 排除草图\n - 推荐的组合应该多样化,覆盖不同的构图角度、画风方向、场景搭配\n - 最多输出 10 个推荐组合\n - 每个组合中标签数量建议 2-6 个\n\n 重要:你必须严格使用可用标签列表中的英文标签名来构成搜索字符串,中文标签名必须与列表中给出的中文名一致,不要自行编造或翻译。\n \"\"\";\n }\n\n private static string BuildUserPrompt(string userInput, List<TagMapping> tagMappings)\n {\n var sb = new StringBuilder();\n sb.AppendLine(\"用户需求:\");\n sb.AppendLine(userInput.Trim());\n sb.AppendLine();\n sb.AppendLine(\"可用标签列表(格式:英文名 → 中文名):\");\n\n foreach (var m in tagMappings)\n {\n if (string.IsNullOrEmpty(m.ChineseName))\n sb.AppendLine($\" {m.EnglishName}\");\n else\n sb.AppendLine($\" {m.EnglishName} → {m.ChineseName}\");\n }\n\n sb.AppendLine();\n sb.AppendLine(\"请根据用户需求,从上述标签中挑选并组合出搜索字符串。\");\n\n return sb.ToString();\n }\n}\n\ninternal static class StringExtensions\n{\n public static string Truncate(this string value, int maxLength)\n => value.Length <= maxLength ? value : value[..maxLength] + \"...\";\n}\n"}, "4b8b96324da8da32050254b091176bfc435815d3": {"t": 1785760549.856879, "n": 4301, "h": "515df3b71e471a80", "c": "using System.Text;\nusing System.Text.Json;\nusing ImageManager.Core.Models;\nusing ImageManager.Core.Services;\n\nnamespace ImageManager.Infrastructure.Services;\n\npublic class DeepSeekRecommendService : IAiRecommendService\n{\n private const string ApiEndpoint = \"https://api.deepseek.com/chat/completions\";\n private const string Model = \"deepseek-chat\";\n private const double Temperature = 0.4;\n\n private static readonly HttpClient _http = new();\n private string _apiKey = string.Empty;\n\n public bool IsAvailable => !string.IsNullOrEmpty(_apiKey);\n\n public void SetApiKey(string key) => _apiKey = key;\n\n public async Task<string> RecommendAsync(string userInput, List<TagMapping> tagMappings, CancellationToken ct = default)\n {\n if (string.IsNullOrEmpty(_apiKey)) return \"错误:未设置 API Key,请在内存与缓存设置中配置 DeepSeek API Key。\";\n if (tagMappings.Count == 0) return \"错误:本地标签库为空。\";\n\n try\n {\n var systemPrompt = BuildSystemPrompt();\n var userPrompt = BuildUserPrompt(userInput, tagMappings);\n\n var requestBody = new\n {\n model = Model,\n messages = new[]\n {\n new { role = \"system\", content = systemPrompt },\n new { role = \"user\", content = userPrompt }\n },\n temperature = Temperature,\n max_tokens = 1000,\n stream = false\n };\n\n var json = JsonSerializer.Serialize(requestBody);\n var content = new StringContent(json, Encoding.UTF8, \"application/json\");\n using var request = new HttpRequestMessage(HttpMethod.Post, ApiEndpoint) { Content = content };\n request.Headers.Add(\"Authorization\", $\"Bearer {_apiKey}\");\n\n using var response = await _http.SendAsync(request);\n\n if (!response.IsSuccessStatusCode)\n {\n var errBody = await response.Content.ReadAsStringAsync();\n return $\"API 请求失败 (HTTP {(int)response.StatusCode}): {errBody.Truncate(300)}\";\n }\n\n var responseBody = await response.Content.ReadAsStringAsync();\n using var doc = JsonDocument.Parse(responseBody);\n var reply = doc.RootElement\n .GetProperty(\"choices\")[0]\n .GetProperty(\"message\")\n .GetProperty(\"content\")\n .GetString() ?? \"(AI 返回为空)\";\n\n return reply.Trim();\n }\n catch (Exception ex)\n {\n return $\"请求异常: {ex.Message}\";\n }\n }\n\n private static string BuildSystemPrompt()\n {\n return \"\"\"\n 你是一个 AI 绘画标签搜索专家。用户会描述想要的图片类型,你需要从可用标签库中挑选最匹配的标签,组合成搜索字符串。\n\n 搜索语法规则:\n - 空格表示 AND(同时满足):girl outdoor → 搜索同时包含 girl 和 outdoor 的图片\n - 小写字母 o 表示 OR(满足其一):smile o laugh → 搜索包含 smile 或 laugh 的图片\n - 减号 - 表示 NOT(排除):-sketch → 排除包含 sketch 标签的图片\n - 可以组合使用:girl outdoor -sketch o smile → 同时满足 girl + outdoor,且不包含 sketch,或包含 smile\n\n 输出要求:\n - 每行输出一个推荐组合,不要编号\n - 每行格式:先用英文标签 + 搜索符号构成可搜索的字符串,然后用 \" → \" 分隔,后面跟对应的中文标签名\n - 示例格式:girl outdoor → 女孩 户外\n - 示例格式(带排除):girl outdoor -sketch → 女孩 户外 排除草图\n - 推荐的组合应该多样化,覆盖不同的构图角度、画风方向、场景搭配\n - 最多输出 10 个推荐组合\n - 每个组合中标签数量建议 2-6 个\n\n 重要:你必须严格使用可用标签列表中的英文标签名来构成搜索字符串,中文标签名必须与列表中给出的中文名一致,不要自行编造或翻译。\n \"\"\";\n }\n\n private static string BuildUserPrompt(string userInput, List<TagMapping> tagMappings)\n {\n var sb = new StringBuilder();\n sb.AppendLine(\"用户需求:\");\n sb.AppendLine(userInput.Trim());\n sb.AppendLine();\n sb.AppendLine(\"可用标签列表(格式:英文名 → 中文名):\");\n\n foreach (var m in tagMappings)\n {\n if (string.IsNullOrEmpty(m.ChineseName))\n sb.AppendLine($\" {m.EnglishName}\");\n else\n sb.AppendLine($\" {m.EnglishName} → {m.ChineseName}\");\n }\n\n sb.AppendLine();\n sb.AppendLine(\"请根据用户需求,从上述标签中挑选并组合出搜索字符串。\");\n\n return sb.ToString();\n }\n}\n\ninternal static class StringExtensions\n{\n public static string Truncate(this string value, int maxLength)\n => value.Length <= maxLength ? value : value[..maxLength] + \"...\";\n}\n"}, "5566da9a69006000af4724e30d4957d02246ae5c": {"t": 1785760551.3498719, "n": 4269, "h": "90d03cfc3d7331f0", "c": "using System.Text;\nusing System.Text.Json;\nusing ImageManager.Core.Models;\nusing ImageManager.Core.Services;\n\nnamespace ImageManager.Infrastructure.Services;\n\npublic class DeepSeekRecommendService : IAiRecommendService\n{\n private const string ApiEndpoint = \"https://api.deepseek.com/chat/completions\";\n private const string Model = \"deepseek-chat\";\n private const double Temperature = 0.4;\n\n private static readonly HttpClient _http = new();\n private string _apiKey = string.Empty;\n\n public bool IsAvailable => !string.IsNullOrEmpty(_apiKey);\n\n public void SetApiKey(string key) => _apiKey = key;\n\n public async Task<string> RecommendAsync(string userInput, List<TagMapping> tagMappings)\n {\n if (string.IsNullOrEmpty(_apiKey)) return \"错误:未设置 API Key,请在内存与缓存设置中配置 DeepSeek API Key。\";\n if (tagMappings.Count == 0) return \"错误:本地标签库为空。\";\n\n try\n {\n var systemPrompt = BuildSystemPrompt();\n var userPrompt = BuildUserPrompt(userInput, tagMappings);\n\n var requestBody = new\n {\n model = Model,\n messages = new[]\n {\n new { role = \"system\", content = systemPrompt },\n new { role = \"user\", content = userPrompt }\n },\n temperature = Temperature,\n max_tokens = 1000,\n stream = false\n };\n\n var json = JsonSerializer.Serialize(requestBody);\n var content = new StringContent(json, Encoding.UTF8, \"application/json\");\n using var request = new HttpRequestMessage(HttpMethod.Post, ApiEndpoint) { Content = content };\n request.Headers.Add(\"Authorization\", $\"Bearer {_apiKey}\");\n\n using var response = await _http.SendAsync(request);\n\n if (!response.IsSuccessStatusCode)\n {\n var errBody = await response.Content.ReadAsStringAsync();\n return $\"API 请求失败 (HTTP {(int)response.StatusCode}): {errBody.Truncate(300)}\";\n }\n\n var responseBody = await response.Content.ReadAsStringAsync();\n using var doc = JsonDocument.Parse(responseBody);\n var reply = doc.RootElement\n .GetProperty(\"choices\")[0]\n .GetProperty(\"message\")\n .GetProperty(\"content\")\n .GetString() ?? \"(AI 返回为空)\";\n\n return reply.Trim();\n }\n catch (Exception ex)\n {\n return $\"请求异常: {ex.Message}\";\n }\n }\n\n private static string BuildSystemPrompt()\n {\n return \"\"\"\n 你是一个 AI 绘画标签搜索专家。用户会描述想要的图片类型,你需要从可用标签库中挑选最匹配的标签,组合成搜索字符串。\n\n 搜索语法规则:\n - 空格表示 AND(同时满足):girl outdoor → 搜索同时包含 girl 和 outdoor 的图片\n - 小写字母 o 表示 OR(满足其一):smile o laugh → 搜索包含 smile 或 laugh 的图片\n - 减号 - 表示 NOT(排除):-sketch → 排除包含 sketch 标签的图片\n - 可以组合使用:girl outdoor -sketch o smile → 同时满足 girl + outdoor,且不包含 sketch,或包含 smile\n\n 输出要求:\n - 每行输出一个推荐组合,不要编号\n - 每行格式:先用英文标签 + 搜索符号构成可搜索的字符串,然后用 \" → \" 分隔,后面跟对应的中文标签名\n - 示例格式:girl outdoor → 女孩 户外\n - 示例格式(带排除):girl outdoor -sketch → 女孩 户外 排除草图\n - 推荐的组合应该多样化,覆盖不同的构图角度、画风方向、场景搭配\n - 最多输出 10 个推荐组合\n - 每个组合中标签数量建议 2-6 个\n\n 重要:你必须严格使用可用标签列表中的英文标签名来构成搜索字符串,中文标签名必须与列表中给出的中文名一致,不要自行编造或翻译。\n \"\"\";\n }\n\n private static string BuildUserPrompt(string userInput, List<TagMapping> tagMappings)\n {\n var sb = new StringBuilder();\n sb.AppendLine(\"用户需求:\");\n sb.AppendLine(userInput.Trim());\n sb.AppendLine();\n sb.AppendLine(\"可用标签列表(格式:英文名 → 中文名):\");\n\n foreach (var m in tagMappings)\n {\n if (string.IsNullOrEmpty(m.ChineseName))\n sb.AppendLine($\" {m.EnglishName}\");\n else\n sb.AppendLine($\" {m.EnglishName} → {m.ChineseName}\");\n }\n\n sb.AppendLine();\n sb.AppendLine(\"请根据用户需求,从上述标签中挑选并组合出搜索字符串。\");\n\n return sb.ToString();\n }\n}\n\ninternal static class StringExtensions\n{\n public static string Truncate(this string value, int maxLength)\n => value.Length <= maxLength ? value : value[..maxLength] + \"...\";\n}\n"}, "627f9e4b6f2854e144303ced9a9b7e4028513085": {"t": 1785760553.885251, "n": 4262, "h": "6f90178ec60ec933", "c": "using System.Text;\nusing System.Text.Json;\nusing ImageManager.Core.Models;\nusing ImageManager.Core.Services;\n\nnamespace ImageManager.Infrastructure.Services;\n\npublic class DeepSeekRecommendService : IAiRecommendService\n{\n private const string ApiEndpoint = \"https://api.deepseek.com/chat/completions\";\n private const string Model = \"deepseek-chat\";\n private const double Temperature = 0.4;\n\n private readonly HttpClient _http = new();\n private string _apiKey = string.Empty;\n\n public bool IsAvailable => !string.IsNullOrEmpty(_apiKey);\n\n public void SetApiKey(string key) => _apiKey = key;\n\n public async Task<string> RecommendAsync(string userInput, List<TagMapping> tagMappings)\n {\n if (string.IsNullOrEmpty(_apiKey)) return \"错误:未设置 API Key,请在内存与缓存设置中配置 DeepSeek API Key。\";\n if (tagMappings.Count == 0) return \"错误:本地标签库为空。\";\n\n try\n {\n var systemPrompt = BuildSystemPrompt();\n var userPrompt = BuildUserPrompt(userInput, tagMappings);\n\n var requestBody = new\n {\n model = Model,\n messages = new[]\n {\n new { role = \"system\", content = systemPrompt },\n new { role = \"user\", content = userPrompt }\n },\n temperature = Temperature,\n max_tokens = 1000,\n stream = false\n };\n\n var json = JsonSerializer.Serialize(requestBody);\n var content = new StringContent(json, Encoding.UTF8, \"application/json\");\n using var request = new HttpRequestMessage(HttpMethod.Post, ApiEndpoint) { Content = content };\n request.Headers.Add(\"Authorization\", $\"Bearer {_apiKey}\");\n\n using var response = await _http.SendAsync(request);\n\n if (!response.IsSuccessStatusCode)\n {\n var errBody = await response.Content.ReadAsStringAsync();\n return $\"API 请求失败 (HTTP {(int)response.StatusCode}): {errBody.Truncate(300)}\";\n }\n\n var responseBody = await response.Content.ReadAsStringAsync();\n using var doc = JsonDocument.Parse(responseBody);\n var reply = doc.RootElement\n .GetProperty(\"choices\")[0]\n .GetProperty(\"message\")\n .GetProperty(\"content\")\n .GetString() ?? \"(AI 返回为空)\";\n\n return reply.Trim();\n }\n catch (Exception ex)\n {\n return $\"请求异常: {ex.Message}\";\n }\n }\n\n private static string BuildSystemPrompt()\n {\n return \"\"\"\n 你是一个 AI 绘画标签搜索专家。用户会描述想要的图片类型,你需要从可用标签库中挑选最匹配的标签,组合成搜索字符串。\n\n 搜索语法规则:\n - 空格表示 AND(同时满足):girl outdoor → 搜索同时包含 girl 和 outdoor 的图片\n - 小写字母 o 表示 OR(满足其一):smile o laugh → 搜索包含 smile 或 laugh 的图片\n - 减号 - 表示 NOT(排除):-sketch → 排除包含 sketch 标签的图片\n - 可以组合使用:girl outdoor -sketch o smile → 同时满足 girl + outdoor,且不包含 sketch,或包含 smile\n\n 输出要求:\n - 每行输出一个推荐组合,不要编号\n - 每行格式:先用英文标签 + 搜索符号构成可搜索的字符串,然后用 \" → \" 分隔,后面跟对应的中文标签名\n - 示例格式:girl outdoor → 女孩 户外\n - 示例格式(带排除):girl outdoor -sketch → 女孩 户外 排除草图\n - 推荐的组合应该多样化,覆盖不同的构图角度、画风方向、场景搭配\n - 最多输出 10 个推荐组合\n - 每个组合中标签数量建议 2-6 个\n\n 重要:你必须严格使用可用标签列表中的英文标签名来构成搜索字符串,中文标签名必须与列表中给出的中文名一致,不要自行编造或翻译。\n \"\"\";\n }\n\n private static string BuildUserPrompt(string userInput, List<TagMapping> tagMappings)\n {\n var sb = new StringBuilder();\n sb.AppendLine(\"用户需求:\");\n sb.AppendLine(userInput.Trim());\n sb.AppendLine();\n sb.AppendLine(\"可用标签列表(格式:英文名 → 中文名):\");\n\n foreach (var m in tagMappings)\n {\n if (string.IsNullOrEmpty(m.ChineseName))\n sb.AppendLine($\" {m.EnglishName}\");\n else\n sb.AppendLine($\" {m.EnglishName} → {m.ChineseName}\");\n }\n\n sb.AppendLine();\n sb.AppendLine(\"请根据用户需求,从上述标签中挑选并组合出搜索字符串。\");\n\n return sb.ToString();\n }\n}\n\ninternal static class StringExtensions\n{\n public static string Truncate(this string value, int maxLength)\n => value.Length <= maxLength ? value : value[..maxLength] + \"...\";\n}\n"}}}} |