refine knowledge searching

This commit is contained in:
Jicheng Lu 2024-09-03 12:52:33 -05:00
parent 1424e14de4
commit 949a2cce9f
10 changed files with 86 additions and 77 deletions

View file

@ -1,7 +1,6 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Messaging.Models.RichContent;
using BotSharp.Abstraction.MLTasks;
namespace BotSharp.Abstraction.Conversations.Models;

View file

@ -0,0 +1,29 @@
using BotSharp.Abstraction.Knowledges.Enums;
using BotSharp.Abstraction.VectorStorage.Models;
namespace BotSharp.Abstraction.VectorStorage.Helpers;
public static class VectorStorageHelper
{
public static string ToQuestionAnswer(this VectorSearchResult data)
{
if (data?.Data == null) return string.Empty;
return $"Question: {data.Data[KnowledgePayloadName.Text]}\r\nAnswer: {data.Data[KnowledgePayloadName.Answer]}";
}
public static string ToPayloadPair(this VectorSearchResult data, IList<string> payloads)
{
if (data?.Data == null || payloads.IsNullOrEmpty()) return string.Empty;
var results = data.Data.Where(x => payloads.Contains(x.Key))
.OrderBy(x => payloads.IndexOf(x.Key))
.Select(x =>
{
return $"{x.Key}: {x.Value}";
})
.ToList();
return string.Join("\r\n", results.Where(x => !string.IsNullOrWhiteSpace(x)));
}
}

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Knowledges.Enums;
namespace BotSharp.Abstraction.VectorStorage.Models;
public class VectorSearchResult : VectorCollectionData

View file

@ -1,9 +1,13 @@
using BotSharp.Abstraction.VectorStorage.Helpers;
namespace BotSharp.Plugin.KnowledgeBase.Functions;
public class KnowledgeRetrievalFn : IFunctionCallback
{
public string Name => "knowledge_retrieval";
public string Indication => "searching my brain";
private readonly IServiceProvider _services;
private readonly KnowledgeBaseSettings _settings;
@ -18,15 +22,16 @@ public class KnowledgeRetrievalFn : IFunctionCallback
var args = JsonSerializer.Deserialize<ExtractedKnowledge>(message.FunctionArgs ?? "{}");
var collectionName = _settings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp;
var embedding = KnowledgeSettingHelper.GetTextEmbeddingSetting(_services, collectionName);
var vector = await embedding.GetVectorAsync(args.Question);
var vectorDb = _services.GetServices<IVectorDb>().FirstOrDefault(x => x.Provider == _settings.VectorDb.Provider);
var knowledges = await vectorDb.Search(collectionName, vector, new List<string> { KnowledgePayloadName.Text, KnowledgePayloadName.Answer });
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
var knowledges = await knowledgeService.SearchVectorKnowledge(args.Question, collectionName, new VectorSearchOptions
{
Fields = new List<string> { KnowledgePayloadName.Text, KnowledgePayloadName.Answer },
Confidence = 0.2f
});
if (!knowledges.IsNullOrEmpty())
{
var answers = knowledges.Select(x => $"Question: {x.Data[KnowledgePayloadName.Text]}\r\nAnswer: {x.Data[KnowledgePayloadName.Answer]}").ToList();
var answers = knowledges.Select(x => x.ToQuestionAnswer()).ToList();
message.Content = string.Join("\r\n\r\n=====\r\n", answers);
}
else

View file

@ -4,6 +4,8 @@ public class MemorizeKnowledgeFn : IFunctionCallback
{
public string Name => "memorize_knowledge";
public string Indication => "remembering knowledge";
private readonly IServiceProvider _services;
private readonly KnowledgeBaseSettings _settings;
@ -18,23 +20,16 @@ public class MemorizeKnowledgeFn : IFunctionCallback
var args = JsonSerializer.Deserialize<ExtractedKnowledge>(message.FunctionArgs ?? "{}");
var collectionName = _settings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp;
var embedding = KnowledgeSettingHelper.GetTextEmbeddingSetting(_services, collectionName);
var vector = await embedding.GetVectorsAsync(new List<string>
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
var result = await knowledgeService.CreateVectorCollectionData(collectionName, new VectorCreateModel
{
args.Question
Text = args.Question,
Payload = new Dictionary<string, string>
{
{ KnowledgePayloadName.Answer, args.Answer }
}
});
var vectorDb = _services.GetServices<IVectorDb>().FirstOrDefault(x => x.Provider == _settings.VectorDb.Provider);
await vectorDb.CreateCollection(collectionName, vector[0].Length);
var result = await vectorDb.Upsert(collectionName, Guid.NewGuid(), vector[0],
args.Question,
new Dictionary<string, string>
{
{ KnowledgePayloadName.Answer, args.Answer }
});
message.Content = result ? "Saved to my brain" : "I forgot it";
return true;
}

View file

@ -1,12 +1,4 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Templating;
using System.Threading.Tasks;
using BotSharp.Abstraction.Routing;
using BotSharp.Core.Infrastructures;
using BotSharp.Plugin.Planner.TwoStaging.Models;
using Microsoft.Extensions.Logging;
using BotSharp.Abstraction.Knowledges.Models;
namespace BotSharp.Plugin.Planner.Functions;
@ -27,26 +19,20 @@ public class PrimaryStagePlanFn : IFunctionCallback
{
// Debug
var state = _services.GetRequiredService<IConversationStateService>();
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
var knowledgeSettings = _services.GetRequiredService<KnowledgeBaseSettings>();
var fn = _services.GetRequiredService<IRoutingService>();
state.SetState("max_tokens", "4096");
var task = JsonSerializer.Deserialize<PrimaryRequirementRequest>(message.FunctionArgs);
// Get knowledge from vectordb
var fn = _services.GetRequiredService<IRoutingService>();
var msg = new ExtractedKnowledge
// Get knowledge from vectordb
var collectionName = knowledgeSettings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp; ;
var knowledges = await knowledgeService.SearchVectorKnowledge(task.Question, collectionName, new VectorSearchOptions
{
Question = task.Question,
};
var retrievalMessage = new RoleDialogModel(AgentRole.User, task.Requirements)
{
FunctionArgs = JsonSerializer.Serialize(msg),
KnowledgeConfidence = 0.1f,
Content = string.Empty
};
await fn.InvokeFunction("knowledge_retrieval", retrievalMessage);
message.Content = retrievalMessage.Content;
Confidence = 0.1f
});
message.Content = string.Join("\r\n\r\n=====\r\n", knowledges.Select(x => x.ToQuestionAnswer()));
var agentService = _services.GetRequiredService<IAgentService>();
var currentAgent = await agentService.LoadAgent(message.CurrentAgentId);

View file

@ -1,12 +1,4 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Knowledges.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Templating;
using BotSharp.Core.Infrastructures;
using BotSharp.Plugin.Planner.TwoStaging.Models;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.Planner.Functions;
@ -26,6 +18,9 @@ public class SecondaryStagePlanFn : IFunctionCallback
public async Task<bool> Execute(RoleDialogModel message)
{
var fn = _services.GetRequiredService<IRoutingService>();
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
var knowledgeSettings = _services.GetRequiredService<KnowledgeBaseSettings>();
var collectionName = knowledgeSettings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp;
var msgSecondary = RoleDialogModel.From(message);
var taskPrimary = JsonSerializer.Deserialize<PrimaryRequirementRequest>(message.FunctionArgs);
@ -38,18 +33,15 @@ public class SecondaryStagePlanFn : IFunctionCallback
var taskSecondary = JsonSerializer.Deserialize<SecondaryBreakdownTask>(msgSecondary.FunctionArgs);
var items = msgSecondary.Content.JsonArrayContent<FirstStagePlan>();
msgSecondary.KnowledgeConfidence = 0.5f;
foreach (var item in items)
{
if (item.NeedAdditionalInformation)
if (!item.NeedAdditionalInformation) continue;
var knowledges = await knowledgeService.SearchVectorKnowledge(item.Task, collectionName, new VectorSearchOptions
{
msgSecondary.FunctionArgs = JsonSerializer.Serialize(new ExtractedKnowledge
{
Question = item.Task
});
await fn.InvokeFunction("knowledge_retrieval", msgSecondary);
message.Content += msgSecondary.Content;
}
Confidence = 0.5f
});
message.Content += string.Join("\r\n\r\n=====\r\n", knowledges.Select(x => x.ToQuestionAnswer()));
}
// load agent

View file

@ -1,10 +1,4 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Templating;
using System.Threading.Tasks;
using BotSharp.Core.Infrastructures;
using BotSharp.Plugin.Planner.TwoStaging.Models;
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.Planner.Functions;

View file

@ -1,13 +1,6 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Knowledges;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Planning;
using BotSharp.Abstraction.Templating;
using BotSharp.Core.Infrastructures;
using BotSharp.Core.Routing.Planning;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace BotSharp.Plugin.Planner.TwoStaging;

View file

@ -3,12 +3,13 @@ global using System.Text.Json;
global using System.Text.Json.Serialization;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Planning;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Agents.Enums;
global using BotSharp.Abstraction.Agents.Models;
@ -18,5 +19,18 @@ global using BotSharp.Abstraction.Functions.Models;
global using BotSharp.Abstraction.Repositories;
global using BotSharp.Abstraction.Utilities;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Functions;
global using BotSharp.Abstraction.Routing;
global using BotSharp.Abstraction.Templating;
global using BotSharp.Abstraction.Knowledges;
global using BotSharp.Abstraction.Knowledges.Settings;
global using BotSharp.Abstraction.Knowledges.Enums;
global using BotSharp.Abstraction.VectorStorage.Models;
global using BotSharp.Abstraction.VectorStorage.Helpers;
global using BotSharp.Plugin.Planner.Hooks;
global using BotSharp.Plugin.Planner.Enums;
global using BotSharp.Plugin.Planner.Enums;
global using BotSharp.Core.Infrastructures;