using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
namespace AI.KnowledgeBase
{
///
/// 简单知识库实现
///
public class SimpleKnowledgeBase : IKnowledgeBase
{
private static readonly Dictionary QueryAliasToTopic = new(StringComparer.OrdinalIgnoreCase)
{
// 常用中文/英文说法归一到知识条目 key
{ "网格化", "成图" },
{ "网格化流程", "成图" },
{ "成图流程", "成图" },
{ "gridding", "成图" },
{ "grid", "成图" },
{ "gridding workflow", "成图" },
};
///
/// 每个主题对应的知识条目 Id 与版本号,便于在会话存储或日志中引用和比对。
///
private static readonly Dictionary TopicMeta = new(StringComparer.OrdinalIgnoreCase)
{
{ "open file", (Id: "open-file", Version: "1") },
{ "close file", (Id: "close-file", Version: "1") },
{ "validate excel", (Id: "validate-excel", Version: "1") },
{ "成图", (Id: "gridding-flow", Version: "3") },
};
private readonly Dictionary knowledge = new()
{
{ "open file", "Use the OpenFile tool to open a file." },
{ "close file", "Use the CloseFile tool to close a file." },
{ "validate excel", "Use the ValidExcelFile tool to validate an Excel file." },
{ "成图", @"
你是一名智能的网格化助手,负责引导用户完成以下两步流程:
1. 散点文件加载卡片:调用 ShowForm(""gridding-load-xyz""),界面会弹出「加载散点文件」综合卡片。
该卡片自动完成:选择文件 → 数据预览 → 列头匹配,无需你介入。
用户点击「确认匹配」后,系统会向你发送包含文件信息与列头匹配结果的摘要消息。
2. 成图参数卡片:调用 ShowForm(""gridding-parameters""),界面会弹出「网格化参数设置」综合卡片。
卡片会自动加载当前参数,用户可在卡片中查看、编辑参数,点击「生成」按钮后由卡片内部完成参数设置与成图,无需你再调用获取/设置参数或成图函数。
调用后只需一句话告知用户参数卡片已展示、可在卡片中修改并点击生成即可。"
},
};
///
public Task SearchKnowledgeAsync(string query)
{
if (string.IsNullOrWhiteSpace(query))
{
return Task.FromResult(BuildNotFoundMessage());
}
var normalized = query.Trim().ToLowerInvariant();
// 先做别名归一(精确)
if (QueryAliasToTopic.TryGetValue(normalized, out var topic))
{
normalized = topic.ToLowerInvariant();
}
// 精确命中
if (knowledge.TryGetValue(normalized, out var result))
{
return Task.FromResult(FormatResult(normalized, result));
}
// 别名归一(包含匹配):比如"我要进行网格化"也能映射到"成图"
foreach (var kv in QueryAliasToTopic)
{
if (normalized.Contains(kv.Key.ToLowerInvariant()))
{
var key = kv.Value.ToLowerInvariant();
if (knowledge.TryGetValue(key, out result))
{
return Task.FromResult(FormatResult(key, result));
}
}
}
// 兜底:包含匹配(选最长 key,避免过于宽泛)
string? bestKey = null;
foreach (var key in knowledge.Keys)
{
var k = key.ToLowerInvariant();
if (normalized.Contains(k) || k.Contains(normalized))
{
if (bestKey == null || k.Length > bestKey.Length)
{
bestKey = key;
}
}
}
if (bestKey != null && knowledge.TryGetValue(bestKey, out result))
{
return Task.FromResult(FormatResult(bestKey, result));
}
return Task.FromResult(BuildNotFoundMessage(query));
}
///
/// 按主题 key 为知识正文加上 [KB-ID; Version] 头部,便于回放与引用。
///
private static string FormatResult(string topicKey, string content)
{
if (!TopicMeta.TryGetValue(topicKey, out var meta))
{
return content;
}
return $"[KB-ID: {meta.Id}; Version: {meta.Version}]{System.Environment.NewLine}{content}";
}
private string BuildNotFoundMessage(string? query = null)
{
var topics = string.Join("、", knowledge.Keys);
if (string.IsNullOrWhiteSpace(query))
return $"未找到相关知识。可用主题:{topics}";
return $"未找到与「{query}」相关的知识。可用主题:{topics}";
}
}
}