取名小程序

This commit is contained in:
cjd
2025-11-06 19:23:42 +08:00
parent 68ae25fac2
commit 823dc8d37b
8 changed files with 490 additions and 17 deletions

View File

@@ -67,7 +67,31 @@ public class NamingService : INamingService
var suggestions = await TryGenerateViaDeepSeekAsync(request, baziProfile).ConfigureAwait(false);
if (!suggestions.Any())
{
_logger.LogWarning("DeepSeek returned no suggestions, falling back to local generator. Request={@Request}", new
{
request.Surname,
request.Gender,
request.NameLength,
request.BirthDate,
request.BirthTime
});
suggestions = _fallbackGenerator.Generate(request, baziProfile);
if (!suggestions.Any())
{
_logger.LogError("Fallback generator also returned empty results. Request={@Request}", new
{
request.Surname,
request.Gender,
request.NameLength,
request.BirthDate,
request.BirthTime
});
}
}
else
{
_logger.LogInformation("DeepSeek generated {Count} suggestions for {Surname}", suggestions.Count, request.Surname);
}
return new NamingResponse
@@ -141,6 +165,7 @@ public class NamingService : INamingService
{
if (IsDeepSeekConfigInvalid())
{
_logger.LogWarning("DeepSeek skipped: configuration missing.");
return Array.Empty<NamingSuggestion>();
}
@@ -162,6 +187,7 @@ public class NamingService : INamingService
return Array.Empty<NamingSuggestion>();
}
_logger.LogInformation("DeepSeek 调用成功,状态码:{StatusCode},响应长度:{Length}", (int)response.StatusCode, payload?.Length ?? 0);
return ParseDeepSeekResponse(payload, request);
}
catch (Exception ex)
@@ -204,35 +230,38 @@ public class NamingService : INamingService
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
var lengthDescriptor = string.Equals(request.NameLength, "single", StringComparison.OrdinalIgnoreCase) ? "单字" : "双字";
var lengthDescriptor = string.Equals(request.NameLength, "single", StringComparison.OrdinalIgnoreCase) ? 1 : 2;
var nameLength = request.Surname.Length + lengthDescriptor;
var genderLabel = string.Equals(request.Gender, "female", StringComparison.OrdinalIgnoreCase) ? "女孩" : "男孩";
var userPrompt = new StringBuilder();
userPrompt.AppendLine("请扮演专业的中华姓名学顾问,根据八字五行提出姓名建议。");
userPrompt.AppendLine($"需基于以下 JSON 数据为姓氏“{request.Surname}”的{genderLabel}提供 5 个{lengthDescriptor}中文名字:");
userPrompt.AppendLine($"需基于以下 JSON 数据为姓氏“{request.Surname}”的{genderLabel}提供 5 个{nameLength}字中文名字:");
userPrompt.AppendLine(contextJson);
userPrompt.AppendLine("要求:");
userPrompt.AppendLine("1. 每条建议输出对象包含 name、meaning、fiveElementReason 三个字段;");
userPrompt.AppendLine("2. 所有汉字需为生活常用的简体字,单字笔画尽量小于等于 12");
userPrompt.AppendLine("3. name 必须包含姓氏且满足给定的字数");
userPrompt.AppendLine("4. fiveElementReason 需指明所补足的五行依据。");
userPrompt.AppendLine("2. meaning为姓名的含义和出处");
userPrompt.AppendLine("3. 所有汉字需为生活常用的简体字,单字笔画尽量小于等于 12");
userPrompt.AppendLine("4. name 必须包含姓氏且满足给定的字数;");
userPrompt.AppendLine("5. fiveElementReason 需指明所补足的五行依据。");
userPrompt.AppendLine("请仅返回 JSON 数据,格式为 {\"suggestions\":[{...}]},不要附加额外说明。");
var requestBody = new
{
model = _deepSeekOptions.Model,
temperature = _deepSeekOptions.Temperature,
max_tokens = _deepSeekOptions.MaxTokens,
//max_tokens = _deepSeekOptions.MaxTokens,
response_format = new { type = _deepSeekOptions.ResponseFormat },
messages = new[]
{
new { role = "system", content = "你是一名资深的中文姓名学专家,擅长根据八字喜用神给出实用建议。" },
new { role = "system", content = "你是一名资深的中文姓名学专家,擅长古诗词,诗经,易经中国传统文化根据八字喜用神给出实用建议。" },
new { role = "user", content = userPrompt.ToString() }
}
};
var message = new HttpRequestMessage(HttpMethod.Post, endpoint)
{
Content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json")
Content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json"),
};
return message;
@@ -242,10 +271,17 @@ public class NamingService : INamingService
{
try
{
if (string.IsNullOrWhiteSpace(payload))
{
_logger.LogWarning("DeepSeek 响应为空字符串");
return Array.Empty<NamingSuggestion>();
}
using var document = JsonDocument.Parse(payload);
var choices = document.RootElement.GetProperty("choices");
if (choices.ValueKind != JsonValueKind.Array || choices.GetArrayLength() == 0)
{
_logger.LogWarning("DeepSeek 响应缺少 choices 数组payload={Payload}", payload);
return Array.Empty<NamingSuggestion>();
}
@@ -256,6 +292,7 @@ public class NamingService : INamingService
if (string.IsNullOrWhiteSpace(content))
{
_logger.LogWarning("DeepSeek 响应 message.content 为空");
return Array.Empty<NamingSuggestion>();
}
@@ -263,6 +300,7 @@ public class NamingService : INamingService
if (!suggestionsDoc.RootElement.TryGetProperty("suggestions", out var suggestionsElement) ||
suggestionsElement.ValueKind != JsonValueKind.Array)
{
_logger.LogWarning("DeepSeek 返回内容缺少 suggestions 数组content={Content}", content);
return Array.Empty<NamingSuggestion>();
}
@@ -277,6 +315,7 @@ public class NamingService : INamingService
if (string.IsNullOrWhiteSpace(name))
{
_logger.LogWarning("DeepSeek suggestion缺少 name 字段item={@Item}", item.ToString());
continue;
}
@@ -288,11 +327,22 @@ public class NamingService : INamingService
if (!ValidateNameLength(name, request))
{
_logger.LogWarning(
"DeepSeek 建议姓名长度与请求不符已丢弃。Name={Name}, Expect={Expect}, Request={@Request}",
name,
request.NameLength,
new
{
request.Surname,
request.Gender,
request.NameLength
});
continue;
}
if (!uniqueNames.Add(name))
{
_logger.LogInformation("DeepSeek 建议出现重复姓名已跳过。Name={Name}", name);
continue;
}
@@ -309,6 +359,11 @@ public class NamingService : INamingService
}
}
if (normalized.Count == 0)
{
_logger.LogWarning("DeepSeek suggestions 解析后为空,原始 content={Content}", content);
}
return normalized;
}
catch (Exception ex)