|
|
@@ -2267,10 +2267,10 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
[ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
|
|
|
public async Task<IActionResult> InvitationAIInit()
|
|
|
{
|
|
|
- var itemNames = await GeneralMethod.InvitationAIInvName();
|
|
|
- var unitNames = await GeneralMethod.InvitationAIClientName();
|
|
|
- var countries = await GeneralMethod.InvitationAICountryName();
|
|
|
- var industryNodes = IndustryNode.BuildInitialData().Select(x => x.NameCn).ToList();
|
|
|
+ var itemNames = await InvitationAIInvName();
|
|
|
+ var unitNames = await InvitationAIClientName();
|
|
|
+ var countries = await InvitationAICountryName();
|
|
|
+ var industryNodes = IndustryTree.Build().Select(x => x.NameCn).ToList();
|
|
|
var orgScales = OrgScale.BuildInitialData().Select(x => x.Name).ToList();
|
|
|
|
|
|
return Ok(JsonView(true, $"查询成功!", new
|
|
|
@@ -2358,260 +2358,6 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 商邀资料AI 混元AI查询资料
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- [HttpPost]
|
|
|
- [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
|
|
|
- public async Task<IActionResult> InvitationAISearch(InvitationAISearchDto dto)
|
|
|
- {
|
|
|
- var invAiInfo = await _sqlSugar.Queryable<Res_InvitationAI>().Where(x => x.Id == dto.Id).FirstAsync();
|
|
|
-
|
|
|
- if (invAiInfo == null || invAiInfo?.EntryInfo == null)
|
|
|
- {
|
|
|
- return Ok(JsonView(false, "请先设置关键字信息!"));
|
|
|
- }
|
|
|
-
|
|
|
- var entryInfo = invAiInfo.EntryInfo;
|
|
|
-
|
|
|
- // 当前企业领域
|
|
|
- string industryFocus = string.Empty;
|
|
|
-
|
|
|
- // 动态计算 AI 需求缺口
|
|
|
- int totalTarget = entryInfo.NeedCount;
|
|
|
-
|
|
|
- // 词条
|
|
|
- string question = string.Empty;
|
|
|
-
|
|
|
- string operatorName = await _sqlSugar.Queryable<Sys_Users>().Where(x => x.IsDel == 0 && x.Id == dto.CurrUserId).Select(x => x.CnName).FirstAsync() ?? "-";
|
|
|
-
|
|
|
- var localInvDatas = new List<InvitationAIInfo>(); // 本地数据源(商邀资料)
|
|
|
- var aiTasks = new List<CountryAIPormptInfo>(); // 记录:国家 -> 需要补齐的数量
|
|
|
-
|
|
|
- #region 本地数据源(商邀资料)
|
|
|
-
|
|
|
- var datas = await _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
|
|
|
- .Where(x => x.IsDel == 0)
|
|
|
- .Select(x => new {
|
|
|
- x.Id,
|
|
|
- x.Country
|
|
|
- })
|
|
|
- .ToListAsync();
|
|
|
-
|
|
|
- var decryptDatas = new List<Res_InvitationOfficialActivityData>();
|
|
|
- foreach (var item in datas)
|
|
|
- {
|
|
|
- decryptDatas.Add(new() {
|
|
|
- Id = item.Id,
|
|
|
- Country = AesEncryptionHelper.Decrypt(item.Country)
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- var localDatas = decryptDatas.Where(x=> !string.IsNullOrEmpty(x.Country) && entryInfo.TargetCountry.Contains(x.Country)).ToList();
|
|
|
-
|
|
|
- var localDataIds = localDatas.Select(x => x.Id).ToList();
|
|
|
-
|
|
|
- var rawData = await _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
|
|
|
- .Where(x => localDataIds.Contains(x.Id))
|
|
|
- .ToListAsync();
|
|
|
-
|
|
|
- // 解密
|
|
|
- var localInvDecryptDatas = rawData.AsParallel().AsOrdered().Select(item => new InvitationAIInfo
|
|
|
- {
|
|
|
- Guid = Guid.NewGuid().ToString("N"),
|
|
|
- Source = 0, // 明确来源标识
|
|
|
- Region = AesEncryptionHelper.Decrypt(item.Country),
|
|
|
- NameCn = AesEncryptionHelper.Decrypt(item.UnitName),
|
|
|
- Address = AesEncryptionHelper.Decrypt(item.Address),
|
|
|
- Scope = AesEncryptionHelper.Decrypt(item.Field),
|
|
|
- Contact = AesEncryptionHelper.Decrypt(item.Contact),
|
|
|
- Phone = AesEncryptionHelper.Decrypt(item.Tel),
|
|
|
- Email = AesEncryptionHelper.Decrypt(item.Email),
|
|
|
- OperatedAt = DateTime.Now,
|
|
|
- Operator = operatorName,
|
|
|
- }).ToList();
|
|
|
-
|
|
|
- // 国家数据条数
|
|
|
- int targetPerCountry = invAiInfo.EntryInfo?.NeedCount ?? 10;
|
|
|
- foreach (var countryName in invAiInfo.EntryInfo.TargetCountry)
|
|
|
- {
|
|
|
- var countryDatas = localInvDecryptDatas.Where(x => x.Region == countryName).Take(targetPerCountry).ToList();
|
|
|
- if (countryDatas.Any())
|
|
|
- {
|
|
|
- localInvDatas.AddRange(countryDatas);
|
|
|
- int gap = targetPerCountry - countryDatas.Count;
|
|
|
- if (gap > 0) aiTasks.Add(new() { Country = countryName, Count = gap });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region 混元AI 获取商邀资料
|
|
|
-
|
|
|
- var hunyuanAIInvDatas = new List<InvitationAIInfo>();
|
|
|
-
|
|
|
- if (aiTasks != null && aiTasks.Count > 0)
|
|
|
- {
|
|
|
- question = @$"# [SYSTEM_CONTEXT]
|
|
|
-- Role: Senior Business Consultant (Global Supply Chain & Cross-border Trade Expert)
|
|
|
-- Framework: S.P.A.R. (Situation-Problem-Action-Result)
|
|
|
-- Target Architecture: .NET 6 DTO Compatible Interface
|
|
|
-
|
|
|
-# [INPUT_CONFIG]
|
|
|
-- Tasks: {{{JsonConvert.SerializeObject(aiTasks)}}}
|
|
|
-- OriginUnit: {{{entryInfo.OriginUnit}}}
|
|
|
-- Objective: {{{entryInfo.Objective}}}
|
|
|
-- OtherConstraints: {{{entryInfo.OtherConstraints}}}
|
|
|
-# [ROLE_DEFINITION]
|
|
|
-你是一位精通全球跨境经贸、海外园区政策及 Tasks 中的国家本地准入法规的【顶级商务咨询顾问】。你擅长通过“产业链对等原则(Chain-Parity Principle)”为跨国企业精准匹配具备落地价值的合作伙伴。
|
|
|
-
|
|
|
-# [BUSINESS_LOGIC_CoT]
|
|
|
-在生成结果前,请严格执行以下思维链拆解:
|
|
|
-1. **ScopePartitioning**: 遍历 Tasks 中的每个国家。
|
|
|
-1. **EntityProfiling**: 识别 {{OriginUnit}} 的核心生态位(如:Supply/Demand/Capital/Logistics)。
|
|
|
-2. **ParityMatching**: 针对每个国家,检索境内业务闭环对等机构。(例如:若 Origin 为分销,则 Target 为源头工厂/种植园)。
|
|
|
-3. **RegulatoryCheck**: 验证目标机构的合规性(如:GACC 备案、SPS 协议、或当地政府特许经营权)。
|
|
|
-4. **DataSynthesis**: 必须严格根据每个国家对应的 Count 生成数据条数。针对无法直接获取的动态(如 PostUrl),优先检索其官网 News 频道或 LinkedIn 企业号。
|
|
|
-
|
|
|
-# [CONSTRAINTS_&_STANDARDS]
|
|
|
-- **NamingConvention**: 所有 JSON Key 必须严格遵循 **PascalCase**(例如:`UnitNameCn` 而非 `unit_name_cn`)。
|
|
|
-- **DataIntegrity**:
|
|
|
- - 总条数必须等于 Tasks 中所有 Count 的总和。
|
|
|
- - 优先级:Core (核心机构) > Backup (关联替代机构)。
|
|
|
-- **ValidationRules**:
|
|
|
- - `Phone`: 必须包含 Tasks 中的国家国际区号(如 +856, +66 等)。
|
|
|
- - `IntgAdvice`: 必须包含“对等性分析”,解释该机构如何与 {{OriginUnit}} 形成业务闭环(50-100字)。
|
|
|
- - `Status`: 若字段确实无法获取,统一填充 'N/A',禁止编造。
|
|
|
-- **Safety**: 确保推荐机构不涉及敏感黑名单或已破产企业。
|
|
|
-
|
|
|
-# [INFORMATION_SCHEMA]
|
|
|
-请将结果填充至以下结构的 JSON 数组中:
|
|
|
-- Region:国家(必须与 Tasks 中的 Country 完全匹配)
|
|
|
-- NameCn: 单位名称(中文)
|
|
|
-- NameEn: 单位名称(英文)
|
|
|
-- Address: 详细地理位置(含省市区街道)
|
|
|
-- Scope: 经营范围(需强调其出口配额、生产能力或行业地位)
|
|
|
-- Contact: 联系人姓名及职务
|
|
|
-- Phone: 拨打全号(含区号)
|
|
|
-- Email: 商务联络邮箱
|
|
|
-- SiteUrl: 官方网站或权威社媒主页
|
|
|
-- PostUrl: 近一年内的商务动态/新闻链接
|
|
|
-- RecLevel: 推荐等级(枚举值:Core, Backup)
|
|
|
-- IntgAdvice: 对接深度建议(基于产业链交合、互补逻辑)
|
|
|
-
|
|
|
-# [OUTPUT_PROTOCOL]
|
|
|
-- 仅输出一个标准的 JSON Array 字符串。
|
|
|
-- 严禁任何 Markdown 说明文字、代码块之外的解释或开场白。
|
|
|
-- 确保 JSON 语法在 .NET `JsonSerializer.Deserialize` 下可直接解析。
|
|
|
-
|
|
|
-# [EXECUTION]
|
|
|
-根据以上配置,开始生成。";
|
|
|
-
|
|
|
- string response = string.Empty;
|
|
|
- try
|
|
|
- {
|
|
|
- response = await _hunyuanService.ChatCompletionsHunyuan_t1_latestAsync(question);
|
|
|
- }
|
|
|
- catch (HttpRequestException ex)
|
|
|
- {
|
|
|
- _logger.LogError(ex, "网络连接失败,无法调用混元API");
|
|
|
- return Ok(JsonView(false, $"网络连接异常,请检查网络后重试!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
- catch (TaskCanceledException ex)
|
|
|
- {
|
|
|
- _logger.LogError(ex, "请求超时");
|
|
|
- return Ok(JsonView(false, $"AI 响应超时,请稍后再试!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
- catch (TencentCloudSDKException ex)
|
|
|
- {
|
|
|
- // 记录完整日志
|
|
|
- _logger.LogError(ex, "腾讯云API调用失败 | 错误码: {ErrorCode} | 请求ID: {RequestId}", ex.ErrorCode, ex.RequestId);
|
|
|
-
|
|
|
- // 根据错误码做差异化处理
|
|
|
- if (ex.ErrorCode != null && ex.ErrorCode == "AuthFailure.SignatureExpire")
|
|
|
- {
|
|
|
- return Ok(JsonView(false, $"系统时间异常,请同步时间后重试!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
- else if (ex.ErrorCode != null && ex.ErrorCode.StartsWith("Unauthorized"))
|
|
|
- {
|
|
|
- return Ok(JsonView(false, $"当前账号无权限访问该服务!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return Ok(JsonView(false, $"腾讯云服务调用失败,请稍后重试!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- _logger.LogError(ex, "未知错误,调用混元API失败");
|
|
|
- return Ok(JsonView(false, $"未知错误,调用混元API失败!Ex:{ex.Message}"));
|
|
|
- }
|
|
|
-
|
|
|
- if (!string.IsNullOrWhiteSpace(response))
|
|
|
- {
|
|
|
- // 预处理:过滤 AI 可能返回的 Markdown 标记
|
|
|
- string cleanJson = response.Trim();
|
|
|
- if (cleanJson.StartsWith("```json"))
|
|
|
- cleanJson = cleanJson.Substring(7, cleanJson.Length - 10).Trim();
|
|
|
- else if (cleanJson.StartsWith("```"))
|
|
|
- cleanJson = cleanJson.Substring(3, cleanJson.Length - 6).Trim();
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- // 解析并注入 Source 标识
|
|
|
- hunyuanAIInvDatas = JsonConvert.DeserializeObject<List<InvitationAIInfo>>(cleanJson);
|
|
|
-
|
|
|
- if (hunyuanAIInvDatas != null)
|
|
|
- {
|
|
|
- hunyuanAIInvDatas = hunyuanAIInvDatas.Select(x =>
|
|
|
- {
|
|
|
- x.Guid = Guid.NewGuid().ToString("N");
|
|
|
- x.Source = 1;
|
|
|
- //x.Region = entryInfo.TargetCountry;
|
|
|
- x.Operator = operatorName;
|
|
|
- x.OperatedAt = DateTime.Now;
|
|
|
- return x;
|
|
|
- }).ToList();
|
|
|
- }
|
|
|
- }
|
|
|
- catch (JsonException ex)
|
|
|
- {
|
|
|
- // 记录日志并考虑 fallback 策略
|
|
|
- _logger.LogError(ex, "Hunyuan AI 响应解析失败。原始数据:{Response}", response);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region 数据库操作
|
|
|
-
|
|
|
- // 数据整合 (高效合并)
|
|
|
- var finalResult = localInvDatas.Concat(hunyuanAIInvDatas).ToList();
|
|
|
-
|
|
|
- string invName = $"{entryInfo.OriginUnit}拜访{entryInfo.TargetCountry}";
|
|
|
-
|
|
|
- invAiInfo.AiCrawledDetails = finalResult;
|
|
|
-
|
|
|
- var update = await _sqlSugar.Updateable(invAiInfo).ExecuteCommandAsync();
|
|
|
- if (update < 1)
|
|
|
- {
|
|
|
- return Ok(JsonView(false, $"数据更新失败!"));
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- return Ok(JsonView(true, $"查询成功!", new
|
|
|
- {
|
|
|
- invAiInfo.Id,
|
|
|
- invAiInfo.InvName,
|
|
|
- invAiInfo.GroupId,
|
|
|
- AiCrawledDetails = invAiInfo.AiCrawledDetails.OrderByDescending(x => x.OperatedAt).ToList(),
|
|
|
- Entry = invAiInfo.EntryInfo
|
|
|
- }));
|
|
|
- }
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 商邀资料AI 混元AI查询资料(SSE流式推送)
|
|
|
/// </summary>
|
|
|
@@ -2645,7 +2391,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
#region 2. 内存计算优化
|
|
|
// 仅查询必要字段,减少 DataReader 压力
|
|
|
var rawLocalDatas = await _sqlSugar.Queryable<Res_InvitationOfficialActivityData>()
|
|
|
- .Where(x => x.IsDel == 0)
|
|
|
+ .Where(x => x.IsDel == 0 && !string.IsNullOrEmpty(x.UnitName))
|
|
|
.Select(x => new { x.Country, x.UnitName, x.Address, x.Field, x.Contact, x.Tel, x.Email })
|
|
|
.ToListAsync();
|
|
|
|
|
|
@@ -2667,6 +2413,8 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
|
|
|
// 筛选符合国家的本地数据
|
|
|
var matchedCountries = allDecrypted.Where(x => targetCountrySet.Contains(x.Region)).ToList();
|
|
|
+ //var matchedCountries = new List<InvitationAIInfo>();
|
|
|
+
|
|
|
#endregion
|
|
|
|
|
|
#region 3. 混元 AI 协同炼金 (双阶段)
|
|
|
@@ -2681,7 +2429,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
var industryMatches = CleanAndParseJson<List<IndustryMatchResult>>(industryRaw) ?? new();
|
|
|
var matchedNames = new HashSet<string>(industryMatches.Select(x => x.TargetUnitName));
|
|
|
// 重新过滤:仅保留 AI 认为匹配的本地数据
|
|
|
- matchedCountries = matchedCountries.Where(x => matchedNames.Contains(x.NameCn)).Distinct().ToList();
|
|
|
+ matchedCountries = matchedCountries.Where(x => !string.IsNullOrEmpty(x.NameCn) && matchedNames.Contains(x.NameCn)).Distinct().ToList();
|
|
|
}
|
|
|
|
|
|
// --- 阶段 B: 差额补全 (Gap Filling) ---
|
|
|
@@ -2703,9 +2451,17 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
// 强制冷却(应对 QPS 限制)
|
|
|
// 混元免费版或低阶版本通常有 1s/1次 的频率限制
|
|
|
await Task.Delay(1000);
|
|
|
+ // 任务配置计算
|
|
|
+ var countryTasks = QuotaScheduler.GenerateTasks(aiTasks, entryInfo.Industries, entryInfo.ScaleTypes);
|
|
|
|
|
|
- await HttpContext.SendSseStepAsync(60, $"AI 正在跨境检索缺失的 {aiTasks.Sum(x => x.Count)} 条单位资料...");
|
|
|
- string searchQuestion = BuildHunyuanPrompt(aiTasks, entryInfo);
|
|
|
+ var countryTasksGroupBy = countryTasks.GroupBy(x => x.Region).Select(g => new
|
|
|
+ {
|
|
|
+ Region = g.Key,
|
|
|
+ Counrt = g.Count()
|
|
|
+ }).ToList();
|
|
|
+
|
|
|
+ await HttpContext.SendSseStepAsync(60, $"AI 正在跨境检索缺失的 {string.Join(", ", countryTasksGroupBy.Select(x => $"{x.Region}({x.Counrt}条)"))} 单位资料...");
|
|
|
+ string searchQuestion = BuildHunyuanPrompt(aiTasks, countryTasks, entryInfo);
|
|
|
string searchRaw = await _hunyuanService.ChatCompletionsHunyuan_t1_latestAsync(searchQuestion);
|
|
|
|
|
|
var aiParsed = CleanAndParseJson<List<InvitationAIInfo>>(searchRaw);
|
|
|
@@ -2713,7 +2469,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
{
|
|
|
hunyuanAIInvDatas = aiParsed.Select(x => {
|
|
|
x.Guid = Guid.NewGuid().ToString("N");
|
|
|
- x.Source = 1; // 标识来源:AI 炼金
|
|
|
+ x.Source = 1;
|
|
|
x.Operator = operatorName;
|
|
|
x.OperatedAt = DateTime.Now;
|
|
|
return x;
|
|
|
@@ -2789,7 +2545,7 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
.ToList();
|
|
|
|
|
|
// 序列化数据
|
|
|
- var industryStandard = IndustryNode.BuildInitialData().Select(x => x.NameCn).ToList();
|
|
|
+ var industryStandard = IndustryTree.Build().Select(x => x.NameCn).ToList();
|
|
|
string industryStandardStr = string.Join("、", industryStandard);
|
|
|
string countriesStr = string.Join(", ", entryInfo.TargetCountry);
|
|
|
string jsonData = JsonConvert.SerializeObject(filteredData);
|
|
|
@@ -2847,88 +2603,465 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ #region 国家配额计算(根据 行业、规模)
|
|
|
+
|
|
|
+ public class TaskCoverageReport
|
|
|
+ {
|
|
|
+ public bool IsValid { get; set; }
|
|
|
+
|
|
|
+ public List<string> MissingRegions { get; set; } = new();
|
|
|
+ public List<string> MissingIndustries { get; set; } = new();
|
|
|
+ public List<string> MissingScales { get; set; } = new();
|
|
|
+
|
|
|
+ public string Summary =>
|
|
|
+ $"Valid={IsValid}, " +
|
|
|
+ $"MissingRegions={string.Join(",", MissingRegions)}, " +
|
|
|
+ $"MissingIndustries={string.Join(",", MissingIndustries)}, " +
|
|
|
+ $"MissingScales={string.Join(",", MissingScales)}";
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class CountryToRegionMapper
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 直接返回中文国家名作为 Region
|
|
|
+ /// </summary>
|
|
|
+ public static string GetRegion(string country)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(country))
|
|
|
+ return "Other";
|
|
|
+
|
|
|
+ return country;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public record IndustryNode(
|
|
|
+ string Code,
|
|
|
+ string NameCn,
|
|
|
+ string NameEn,
|
|
|
+ double Weight = 1.0, // 1.0 代表主行业
|
|
|
+ List<IndustryNode>? Children = null
|
|
|
+ );
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 行业结构
|
|
|
+ /// </summary>
|
|
|
+ public static class IndustryTree
|
|
|
+ {
|
|
|
+ public static List<IndustryNode> Build() => new()
|
|
|
+ {
|
|
|
+ // 1. 工业与制造业
|
|
|
+ new("IND_MANU", "工业与制造业领域", "Industry & Manufacturing", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("MANU_MACH", "机械制造", "Machinery Manufacturing", 0.9),
|
|
|
+ new("MANU_AUTO", "汽车制造", "Automotive Manufacturing", 0.9,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("AUTO_NEV", "新能源汽车", "New Energy Vehicles", 0.9),
|
|
|
+ new("AUTO_AD", "自动驾驶", "Autonomous Driving", 0.85),
|
|
|
+ new("AUTO_PARTS", "汽车零部件", "Auto Parts", 0.7)
|
|
|
+ }),
|
|
|
+ new("MANU_SMART", "智能制造", "Smart Manufacturing", 0.85)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 2. 能源与资源
|
|
|
+ new("ENERGY_RES", "能源与资源领域", "Energy & Resources", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("ENERGY_NE", "新能源", "New Energy", 0.9),
|
|
|
+ new("ENERGY_STORAGE", "储能技术", "Energy Storage", 0.85),
|
|
|
+ new("ENERGY_GRID", "智慧电网", "Smart Grid", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 3. 交通运输与物流
|
|
|
+ new("TRANS_LOG", "交通运输与物流领域", "Transportation & Logistics", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("LOG_SMART", "智慧物流", "Smart Logistics", 0.9),
|
|
|
+ new("TRANS_PORT", "港口自动化", "Port Automation", 0.85),
|
|
|
+ new("LOG_COLD", "冷链物流", "Cold Chain Logistics", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 4. 城乡建设与规划
|
|
|
+ new("URBAN_RURAL", "城乡建设与规划领域", "Urban & Rural Construction", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("URBAN_SMART", "智慧城市", "Smart City", 0.9),
|
|
|
+ new("URBAN_GREEN", "绿色建筑", "Green Building", 0.85),
|
|
|
+ new("URBAN_UPDATE", "城市更新", "Urban Renewal", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 5. 生态环境与水务
|
|
|
+ new("ECO_ENV", "生态环境与水务领域", "Ecology & Water Affairs", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("ENV_WATER", "水处理", "Water Treatment", 0.9),
|
|
|
+ new("ENV_SOLID", "固废处理", "Solid Waste Treatment", 0.85),
|
|
|
+ new("ENV_MONITOR", "环境监测", "Environmental Monitoring", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 6. 农业与食品
|
|
|
+ new("AGRI_FOOD", "农业与食品领域", "Agriculture & Food", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("AGRI_SMART", "智慧农业", "Smart Agriculture", 0.9),
|
|
|
+ new("FOOD_PROC", "农产品加工", "Food Processing", 0.85),
|
|
|
+ new("AGRI_SEED", "种业技术", "Seed Technology", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 7. 金融与商贸
|
|
|
+ new("FIN_TRADE", "金融与商贸领域", "Finance & Commerce", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("FIN_TECH", "金融科技", "FinTech", 0.9),
|
|
|
+ new("TRADE_E", "跨境电商", "Cross-border E-commerce", 0.85),
|
|
|
+ new("FIN_SUPPLY", "供应链金融", "Supply Chain Finance", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 8. 医药健康与康养
|
|
|
+ new("MED_HEALTH", "医药健康与康养领域", "Medicine & Health", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("MED_BIO", "生物医药", "Biopharma", 0.9),
|
|
|
+ new("MED_DEVICE", "医疗器械", "Medical Devices", 0.85),
|
|
|
+ new("HEALTH_CARE", "康复养老", "Rehabilitation & Elderly Care", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 9. 文化旅游与体育
|
|
|
+ new("CULT_TOUR", "文化旅游与体育领域", "Culture, Tourism & Sports", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("TOUR_DIGITAL", "数字文旅", "Digital Culture & Tourism", 0.9),
|
|
|
+ new("SPORT_EVENT", "体育赛事运营", "Sports Event Management", 0.85),
|
|
|
+ new("CULT_CREATIVE", "文创设计", "Cultural Creativity", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 10. 信息科技与数字经济
|
|
|
+ new("IT_DIGITAL", "信息科技与数字经济领域", "IT & Digital Economy", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("IT_SOFT", "软件", "Software", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("SOFT_SAAS", "SaaS", "SaaS", 0.9),
|
|
|
+ new("IT_AI", "AI", "Artificial Intelligence", 0.9),
|
|
|
+ new("IT_BIGDATA", "大数据", "Big Data", 0.85),
|
|
|
+ new("IT_CLOUD", "云计算", "Cloud Computing", 0.6)
|
|
|
+ }),
|
|
|
+ new("IT_IOT", "工业互联网", "Industrial Internet", 0.85)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 11. 教育与科技
|
|
|
+ new("EDU_TECH", "教育与科技领域", "Education & Technology", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("EDU_ONLINE", "在线教育", "Online Education", 0.9),
|
|
|
+ new("EDU_VOC", "职业教育", "Vocational Education", 0.85),
|
|
|
+ new("EDU_INFO", "教育信息化", "Education Informatization", 0.8)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 12. 社会服务与公共管理
|
|
|
+ new("SOC_SERVICE", "社会服务与公共管理领域", "Social Services", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("GOV_SMART", "智慧政务", "Smart Government", 0.9),
|
|
|
+ new("COMMUNITY", "社区治理", "Community Governance", 0.85),
|
|
|
+ new("NGO", "公益慈善", "Charity & NGO", 0.7)
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 13. 其他重点领域
|
|
|
+ new("OTHER_KEY", "其他重点领域", "Other Key Fields", 1.0,
|
|
|
+ Children: new()
|
|
|
+ {
|
|
|
+ new("EMERGENCY", "应急管理", "Emergency Management", 0.9),
|
|
|
+ new("GEO_SURVEY", "地质勘察", "Geological Survey", 0.85),
|
|
|
+ new("IP_SERVICE", "知识产权服务", "IP Services", 0.8)
|
|
|
+ })
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class IndustryExpander
|
|
|
+ {
|
|
|
+ public static List<string> Expand(
|
|
|
+ List<string> baseIndustries,
|
|
|
+ List<IndustryNode> tree)
|
|
|
+ {
|
|
|
+ var result = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
|
+
|
|
|
+ foreach (var baseIndName in baseIndustries)
|
|
|
+ {
|
|
|
+ var node = tree.FirstOrDefault(n =>
|
|
|
+ n.NameCn.Equals(baseIndName, StringComparison.OrdinalIgnoreCase));
|
|
|
+
|
|
|
+ if (node == null) continue;
|
|
|
+
|
|
|
+ // 添加主行业
|
|
|
+ result.Add(node.NameCn);
|
|
|
+
|
|
|
+ // 递归添加子行业(按权重降序)
|
|
|
+ if (node.Children != null)
|
|
|
+ {
|
|
|
+ AddChildrenRecursive(node.Children, result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result.ToList();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void AddChildrenRecursive(
|
|
|
+ List<IndustryNode> nodes,
|
|
|
+ HashSet<string> result)
|
|
|
+ {
|
|
|
+ foreach (var child in nodes.OrderByDescending(n => n.Weight))
|
|
|
+ {
|
|
|
+ result.Add(child.NameCn);
|
|
|
+ if (child.Children != null)
|
|
|
+ {
|
|
|
+ AddChildrenRecursive(child.Children, result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static class QuotaScheduler
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 国家配额计算(根据 行业、规模)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="countryTasks"></param>
|
|
|
+ /// <param name="industries"></param>
|
|
|
+ /// <param name="scales"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<AITaskItem> GenerateTasks(
|
|
|
+ List<CountryAIPormptInfo> countryTasks,
|
|
|
+ List<string> industries,
|
|
|
+ List<string> scales)
|
|
|
+ {
|
|
|
+ if (!countryTasks.Any() || !industries.Any() || !scales.Any())
|
|
|
+ return new List<AITaskItem>();
|
|
|
+
|
|
|
+ var rnd = new Random();
|
|
|
+
|
|
|
+ // 1. 行业延伸
|
|
|
+ var expandedIndustries = IndustryExpander.Expand(
|
|
|
+ industries,
|
|
|
+ IndustryTree.Build()
|
|
|
+ );
|
|
|
+
|
|
|
+ // 2. Country -> Region (中文)
|
|
|
+ var regionGroups = countryTasks
|
|
|
+ .Select(ct => new
|
|
|
+ {
|
|
|
+ Region = CountryToRegionMapper.GetRegion(ct.Country),
|
|
|
+ ct.Count
|
|
|
+ })
|
|
|
+ .GroupBy(x => x.Region)
|
|
|
+ .ToList();
|
|
|
+
|
|
|
+ int totalRequested = regionGroups.Sum(g => g.Sum(x => x.Count));
|
|
|
+
|
|
|
+ var tasks = new List<AITaskItem>();
|
|
|
+
|
|
|
+ int totalTaskCount = countryTasks.Sum(x => x.Count);
|
|
|
+
|
|
|
+ // 3. 按权重生成(Region 30%)
|
|
|
+ foreach (var group in regionGroups)
|
|
|
+ {
|
|
|
+ double weight = (double)group.Sum(x => x.Count) / totalRequested;
|
|
|
+ int quota = (int)Math.Round(weight * totalTaskCount * 0.3);
|
|
|
+
|
|
|
+ for (int i = 0; i < quota; i++)
|
|
|
+ {
|
|
|
+ tasks.Add(new AITaskItem
|
|
|
+ {
|
|
|
+ Region = group.Key, // 中文国家名
|
|
|
+ Industry = expandedIndustries[rnd.Next(expandedIndustries.Count)],
|
|
|
+ Scale = scales[rnd.Next(scales.Count)]
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tasks
|
|
|
+ .OrderBy(_ => rnd.Next())
|
|
|
+ .ToList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 混元提示词构建(高度定制化,适配商邀资料场景)
|
|
|
/// </summary>
|
|
|
/// <param name="tasks">包含国家及 Count 数量的任务列表</param>
|
|
|
/// <param name="entryInfo">包含规则基础信息</param>
|
|
|
/// <returns>最终构建的 System Prompt 字符串</returns>
|
|
|
- private static string BuildHunyuanPrompt(List<CountryAIPormptInfo> tasks, EntryInfo entryInfo)
|
|
|
+ private static string BuildHunyuanPrompt(List<CountryAIPormptInfo> tasks, List<AITaskItem> countryTasks, EntryInfo entryInfo)
|
|
|
{
|
|
|
// 行业信息,用于提示词硬约束
|
|
|
- string industryEnum = string.Join("、", IndustryNode.Roots.Select(x => x.NameCn));
|
|
|
+ string industryEnum = string.Join("、", IndustryTree.Build().Select(x => x.NameCn).ToList());
|
|
|
|
|
|
- //构建其他约束条件字符串
|
|
|
- var otherConstraintsStr = new StringBuilder();
|
|
|
- if (entryInfo.Industries.Any()) otherConstraintsStr.Append($"- 行业信息: {string.Join("、", entryInfo.Industries)};");
|
|
|
- if (entryInfo.ScaleTypes.Any()) otherConstraintsStr.Append($"- 单位规模: {string.Join("、", entryInfo.ScaleTypes)};");
|
|
|
- if (entryInfo.IsBackground) otherConstraintsStr.Append($"- 单位是否包含华人背景: 是;");
|
|
|
- if (!string.IsNullOrEmpty(entryInfo.OtherConstraints)) otherConstraintsStr.Append($"- 其他规则: {entryInfo.OtherConstraints};");
|
|
|
+ var businessConstraints = new StringBuilder();
|
|
|
+ if (entryInfo.Industries.Any()) businessConstraints.AppendLine($" - 行业信息: {string.Join("、", entryInfo.Industries)}");
|
|
|
+ if (entryInfo.ScaleTypes.Any()) businessConstraints.AppendLine($" - 单位规模: {string.Join("、", entryInfo.ScaleTypes)}");
|
|
|
+ if (entryInfo.IsBackground) businessConstraints.AppendLine($" - 单位是否包含华人背景: 是");
|
|
|
+ if (!string.IsNullOrEmpty(entryInfo.OtherConstraints)) businessConstraints.AppendLine($" - 其他规则: {entryInfo.OtherConstraints}");
|
|
|
+ if (businessConstraints == null || businessConstraints.Length == 0) businessConstraints.AppendLine("无");
|
|
|
|
|
|
- return @$"
|
|
|
+ return $@"
|
|
|
# [SYSTEM_ROLE]
|
|
|
-你是一位精通全球跨境经贸、海外园区政策及准入法规的【顶级商务咨询顾问】。同时,你具备资深的 .NET 6 软件架构思维,擅长生成高精度、符合强类型反序列化要求的结构化 JSON 数据。
|
|
|
+你是精通全球实时经贸情报与海外准入法规的【顶级商务咨询顾问】。
|
|
|
+你具备实时全网检索、多源交叉核验、AI幻觉零容忍能力,严格遵循“无检索不输出、无验证不回填、搜不到即熔断”原则。
|
|
|
+你具备资深.NET 6架构思维,输出JSON 100%符合强类型反序列化、零异常,可直接被 JsonConvert.DeserializeObject<List<T>> 解析。
|
|
|
|
|
|
# [CONTEXT_ANALYSIS]
|
|
|
-- **发起单位 (OriginUnit)**: {entryInfo.OriginUnit}
|
|
|
-- **核心目标 (Objective)**: {entryInfo.Objective}
|
|
|
-- **行业归口枚举**: [{industryEnum}]
|
|
|
-- **业务约束条件**: {otherConstraintsStr}
|
|
|
-
|
|
|
-# [THOUGHT_PROCESS_LOGIC (CoT)]
|
|
|
-在构建每一条匹配数据前,请严格执行以下逻辑拆解,严禁盲目生成:
|
|
|
-1. **产业链定位分析 (Parity Logic)**: 深度分析 {entryInfo.OriginUnit} 在产业链中的位置。若其为制造方,则必须匹配具备当地分销能力的“贸易商”或“工程承包商”;若其为下游单位,则匹配上游“工厂”。严禁匹配直接竞争对手。
|
|
|
-2. **地域合规性校验**: 确保匹配的单位在指定任务国家(Tasks)真实存在,并具备当地市场准入资质。
|
|
|
-3. **时效性过滤**: 检索目标单位在 **2023-2026** 年间的动态。若无公开新闻,必须确保其官方网站(SiteUrl)具有真实度。
|
|
|
-4. **数据量校验**: 严格执行 Tasks 中的 `Count` 数量要求,总生成条数必须精准等于所有任务 Count 之和。
|
|
|
+• 当前核查时间 (CurrentDate): {DateTime.Now:yyyy-MM-dd}
|
|
|
+• 发起单位 (OriginUnit): {entryInfo.OriginUnit}
|
|
|
+• 核心目标 (Objective): {entryInfo.Objective}
|
|
|
+
|
|
|
+• 业务硬性约束 (BusinessConstraints):
|
|
|
+{businessConstraints}
|
|
|
+
|
|
|
+• 国家任务配置 (CountryTasks):
|
|
|
+{JsonConvert.SerializeObject(countryTasks)}
|
|
|
+
|
|
|
+• 任务配额 (Multi-Tasking):
|
|
|
+{JsonConvert.SerializeObject(tasks)}
|
|
|
+
|
|
|
+# [BUSINESS_CONSTRAINTS_SCHEMA - 业务硬性约束解析规则]
|
|
|
+BusinessConstraints 参数为结构化文本,解析规则如下:
|
|
|
+1. “行业信息”:允许检索的行业集合,多个用顿号分隔
|
|
|
+2. “单位规模”:允许检索的企业规模集合,多个用顿号分隔
|
|
|
+3. “单位是否包含华人背景”:是/否开关
|
|
|
+4. “其他规则”:自由文本补充说明
|
|
|
+5. 若内容为“无”,表示无额外业务约束
|
|
|
+
|
|
|
+⚠️ 重要绑定:
|
|
|
+• 所有 Task 的 Scale 必须来自“单位规模”
|
|
|
+
|
|
|
+# [INDUSTRY_ONTOLOGY_RULES - 行业本体与延伸规则]
|
|
|
+
|
|
|
+1. 行业结构定义:
|
|
|
+ • 每个行业包含:
|
|
|
+ - 主行业(NameCn)
|
|
|
+ - 子行业(Children)
|
|
|
+ - 权重(Weight,0.0–1.0)
|
|
|
+
|
|
|
+2. 延伸原则:
|
|
|
+ • 允许在主行业基础上延伸至其子行业
|
|
|
+ • 权重 ≥ 0.8 的子行业:优先使用
|
|
|
+ • 权重 < 0.8 的子行业:仅在配额不足时补充
|
|
|
+ • 严禁跨越大类(如:软件 ≠ 汽车制造)
|
|
|
+
|
|
|
+3. 示例(仅作参考):
|
|
|
+ • 软件
|
|
|
+ - SaaS (0.9)
|
|
|
+ - AI (0.9)
|
|
|
+ - 大数据 (0.85)
|
|
|
+ - 云计算 (0.6)
|
|
|
+
|
|
|
+4. 输出约束:
|
|
|
+ • Task 中的 Industry 字段
|
|
|
+ • 必须来源于同一主行业下的 NameCn
|
|
|
+
|
|
|
+# [REGION_MAPPING_RULE - 中文国家直连模式]
|
|
|
+• 映射规则:
|
|
|
+ - CountryTasks 中的 Country 字段(中文国家名)
|
|
|
+ - 将直接作为 Region 字段的值使用
|
|
|
+ - 不进行区域聚合(如:美国 ≠ North America)
|
|
|
+• 示例:
|
|
|
+ - Country = ""美国"" → Region = ""美国""
|
|
|
+ - Country = ""德国"" → Region = ""德国""
|
|
|
+• 兜底规则:
|
|
|
+ - 空值或无法识别 → Region = ""Other""
|
|
|
+
|
|
|
+# [REGION_QUOTA_PARSING_RULES]
|
|
|
+1. CountryTasks 结构:
|
|
|
+ {{
|
|
|
+ ""Country"": ""string"", // 中文国家名
|
|
|
+ ""Count"": int
|
|
|
+ }}
|
|
|
+2. 映射规则:严格遵循 REGION_MAPPING_RULE
|
|
|
+3. [EXTREME_FALLBACK_RULES - 极端异常兜底]
|
|
|
+ • CountryTasks 为空数组或未提供 → 直接返回 []
|
|
|
+ • 配额调度出现除零/空引用风险 → 立即熔断,输出 []
|
|
|
+
|
|
|
+# [REALITY_CHECK_RULES - 分层验证标准]
|
|
|
+1. 强制全网检索({DateTime.Now.AddYears(-3).Year}-{DateTime.Now.Year}):对每个Region+NameEn执行多语言检索。若完全检索不到任何可交叉验证的信息,该企业条目将被剔除,不进入输出列表。
|
|
|
+2. 企业真实性“双轨制”核验:
|
|
|
+ • 轨道A(权威信源):目标国官方投资促进局、当地证券交易所、中国驻外使领馆经商处、邓白氏编码。
|
|
|
+ • 轨道B(主流可信商业信源):Crunchbase、LinkedIn Company Page、PitchBook、行业权威媒体、知名风投Portfolio、公司IR页面。
|
|
|
+3. 官网有效性“核心指标”校验(非404/5xx,36个月内有更新,否则 SiteUrl = ""INVALID_URL_REALITY_CHECK_FAILED"")。
|
|
|
+4. 新闻动态(PostUrl)“双要素”校验(近三年 + URL可访问)。
|
|
|
+5. 邮箱(Email)有效性校验(官方域名 + 收件能力验证,否则 Email = ""INVALID_EMAIL_REALITY_CHECK_FAILED"")。
|
|
|
+6. 搜不到即熔断:完全无轨道A/B信源 → 不输出该企业。
|
|
|
+
|
|
|
+# [DATA_SOURCE_INTEGRITY - 分层策略]
|
|
|
+• Core:通过轨道A且官网有效
|
|
|
+• Backup:未通过轨道A,但通过轨道B且官网基本有效
|
|
|
+• 无效:轨道A/B均未通过 → 不输出
|
|
|
+
|
|
|
+# [QUOTA_SCHEDULING - 配额调度算法(浮动上限版)]
|
|
|
+• 数据来源说明:
|
|
|
+ - Region 权重来自 CountryTasks(直接使用中文国家名)
|
|
|
+ - Industry 来自 BusinessConstraints(行业信息 + 延伸)
|
|
|
+ - Scale 来自 BusinessConstraints(单位规模)
|
|
|
+• 基础权重分配:Region 30% + Industry 40% + Scale 30%
|
|
|
+• 【浮动上限规则】:
|
|
|
+ - 严禁为了填满 Region 配额而编造数据。
|
|
|
+ - 如果某个国家(Region)在指定 Industry + Scale 下找不到足够的可验证企业,允许该 Region 的实际输出数量 < 理论配额。
|
|
|
+• 【名额再分配】:
|
|
|
+ - 空出的名额必须自动转移给同一 Industry / Scale 下数据质量更高的其他国家。
|
|
|
+
|
|
|
+# [THOUGHT_PROCESS_LOGIC]
|
|
|
+1. 解析 BusinessConstraints 获取 Industries / Scales
|
|
|
+2. 应用 Industry Extension Rules
|
|
|
+3. 解析 CountryTasks → Region 配额(理论值)
|
|
|
+4. 按 Region(中文国家) + Industry + Scale 实时检索
|
|
|
+5. 执行轨道A/B + 官网校验(遇空则跳过,不硬凑)
|
|
|
+6. PostUrl/Email 校验
|
|
|
+7. 触发浮动上限逻辑,进行名额再分配
|
|
|
+8. 输出纯净 JSON 数组
|
|
|
|
|
|
# [STRICT_DATA_CONTRACT]
|
|
|
-1. **命名规范 (Mandatory)**: 所有 JSON Key 必须严格遵循 **PascalCase**(大驼峰命名法)。
|
|
|
- - 正确示例: `NameCn`, `PostUrl`, `RecLevel`
|
|
|
- - 错误示例: `name_cn`, `nameCn`
|
|
|
-2. **字段取值约束**:
|
|
|
- - `Industry`: 必须且只能从枚举值 [{industryEnum}] 中选择其一,不得自行发明。
|
|
|
- - `RecLevel`: 仅限使用 `Core` 或 `Backup`。
|
|
|
-3. **空值与集合处理**:
|
|
|
- - 若某字符串字段缺失,填充 `""N/A""`。
|
|
|
- - 若 `PostUrl` 数组无动态,必须返回 `[]`,严禁返回 `null`。
|
|
|
-4. **格式规范**:
|
|
|
- - `Phone`: 必须包含国际区号(如 +86, +856)。
|
|
|
- - `Date`: 统一使用 `yyyy-MM-dd`。
|
|
|
-
|
|
|
-# [INFORMATION_SCHEMA]
|
|
|
-请将结果填充至以下结构的 JSON Array 中:
|
|
|
{{
|
|
|
- ""Region"": ""国家名称"",
|
|
|
- ""Industry"": ""所属行业(必须是指定的枚举值)"",
|
|
|
- ""NameCn"": ""单位名称(中文)"",
|
|
|
- ""NameEn"": ""单位名称(英文)"",
|
|
|
- ""Address"": ""详细地理位置/总部地址"",
|
|
|
- ""Scope"": ""经营范围(侧重描述其在当地的行业地位或配套能力)"",
|
|
|
- ""Contact"": ""联系人姓名及职务"",
|
|
|
- ""Phone"": ""含区号的联系电话"",
|
|
|
- ""Email"": ""商务联络邮箱"",
|
|
|
- ""SiteUrl"": ""官方网站或权威主页链接"",
|
|
|
- ""PostUrl"": [
|
|
|
- {{
|
|
|
- ""Date"": ""yyyy-MM-dd"",
|
|
|
- ""Description"": ""近三年企业动态简述 (15-30字)"",
|
|
|
- ""Url"": ""动态/新闻链接""
|
|
|
- }}
|
|
|
- ],
|
|
|
- ""RecLevel"": ""推荐等级枚举值"",
|
|
|
- ""IntgAdvice"": ""对接深度建议(50-100字,基于产业链对等逻辑分析匹配原因)""
|
|
|
+ ""Region"": ""string"",
|
|
|
+ ""Industry"": ""string"",
|
|
|
+ ""NameCn"": ""string"",
|
|
|
+ ""NameEn"": ""string"",
|
|
|
+ ""Address"": ""string"",
|
|
|
+ ""Scope"": ""string"",
|
|
|
+ ""Contact"": ""string"",
|
|
|
+ ""Phone"": ""string"",
|
|
|
+ ""Email"": ""string"",
|
|
|
+ ""SiteUrl"": ""string"",
|
|
|
+ ""PostUrl"": [ {{ ""Date"": ""yyyy-MM-dd"", ""Description"": ""string"", ""Url"": ""string"" }} ],
|
|
|
+ ""RecLevel"": ""Core|Backup"",
|
|
|
+ ""IntgAdvice"": ""string""
|
|
|
}}
|
|
|
|
|
|
-# [OUTPUT_PROTOCOL - CRITICAL]
|
|
|
-- **MODE**: RAW_TEXT_STREAM
|
|
|
-- **FORBIDDEN**: 严禁包含任何 Markdown 格式标识符(如 ```json )。
|
|
|
-- **FORBIDDEN**: 严禁输出任何开场白、中间解释、结尾客套话或补充说明。
|
|
|
-- **REQUIREMENT**: 只允许输出一个以 `[` 开头,以 `]` 结尾的纯 JSON 字符串,确保其可直接被 `JsonConvert.DeserializeObject<List<T>>` 解析。
|
|
|
+# [OUTPUT_PROTOCOL]
|
|
|
+• MODE: RAW_TEXT_STREAM
|
|
|
+• FORMAT: 纯JSON数组、无Markdown、无注释、无开场白、无结尾
|
|
|
+• EMPTY_HANDLING: 无有效数据 → 直接返回 []
|
|
|
+• FORBIDDEN: 严禁编造、推测、幻觉、占位对象
|
|
|
+
|
|
|
+# [HUNYUAN_OUTPUT_GUARDRAILS]
|
|
|
+你是一个严格的 JSON 生成器,不是对话助手。
|
|
|
+禁止输出 Markdown、代码块标记、解释性文字、思考过程。
|
|
|
+首字符必须是 `[` 或 `{{`,末字符必须是 `]` 或 `}}`。
|
|
|
+若结果为空,仅输出 `[]`。
|
|
|
+请立即执行。
|
|
|
|
|
|
# [EXECUTION]
|
|
|
-基于以上配置,立即处理以下任务列表:
|
|
|
-{JsonConvert.SerializeObject(tasks)}";
|
|
|
+立即执行:
|
|
|
+1. 按中文 CountryTasks 推导 Region 配额
|
|
|
+2. 应用行业延伸规则
|
|
|
+3. 按 Region(中文国家) + Industry + Scale 实时检索
|
|
|
+4. 执行轨道A/B + 官网校验(遇空则跳过)
|
|
|
+5. 对PostUrl/Email执行校验
|
|
|
+6. 执行名额再分配(浮动上限逻辑)
|
|
|
+7. 按配额输出真实企业
|
|
|
+8. 无真实数据 → 返回 []";
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -3491,7 +3624,9 @@ Inner Join Sys_Department as d With(Nolock) On u.DepId=d.Id Where m.Id={0} ", _m
|
|
|
entryInfo.OtherConstraints = promptOther; // 将去重提示注入 entryInfo,确保 Prompt 构建时包含该信息
|
|
|
|
|
|
// 构建 Question
|
|
|
- string question = BuildHunyuanPrompt(aiTasks, entryInfo);
|
|
|
+ // 任务配置计算
|
|
|
+ var countryTasks = QuotaScheduler.GenerateTasks(aiTasks, entryInfo.Industries, entryInfo.ScaleTypes);
|
|
|
+ string question = BuildHunyuanPrompt(aiTasks, countryTasks, entryInfo);
|
|
|
|
|
|
await HttpContext.SendSseStepAsync(30, "AI 正在深度检索跨境商邀数据,请稍候...");
|
|
|
|