Files

1 line
21 KiB
JSON
Raw Permalink 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.
{"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"}}}}