From eaf647677e524d4b55c6b5212ec1fe3446713190 Mon Sep 17 00:00:00 2001
From: Joanna Ren <101223@smsassist.com>
Date: Wed, 16 Oct 2024 17:05:59 -0500
Subject: [PATCH] Add knowledge generation refine
---
.../Knowledges/Models/GenerateKnowledge.cs | 19 ++++++++++++
.../BotSharp.Plugin.KnowledgeBase.csproj | 4 +++
.../Functions/GenerateKnowledgeFn.cs | 31 +++++++++++++++++--
.../templates/knowledge.generation.liquid | 2 +-
.../knowledge.generation.refine.liquid | 15 +++++++++
.../functions/sql_dictionary_lookup.json | 6 +++-
6 files changed, 72 insertions(+), 5 deletions(-)
create mode 100644 src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/GenerateKnowledge.cs
create mode 100644 src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.refine.liquid
diff --git a/src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/GenerateKnowledge.cs b/src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/GenerateKnowledge.cs
new file mode 100644
index 000000000..a5698dc0e
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/GenerateKnowledge.cs
@@ -0,0 +1,19 @@
+namespace BotSharp.Abstraction.Knowledges.Models;
+
+public class GenerateKnowledge
+{
+ [JsonPropertyName("question")]
+ public string Question { get; set; } = string.Empty;
+
+ [JsonPropertyName("answer")]
+ public string Answer { get; set; } = string.Empty;
+
+ [JsonPropertyName("refined_collection")]
+ public string RefinedCollection { get; set; } = string.Empty;
+
+ [JsonPropertyName("refine_answer")]
+ public Boolean RefineAnswer { get; set; } = false;
+
+ [JsonPropertyName("existing_answer")]
+ public string ExistingAnswer { get; set; } = string.Empty;
+}
diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj b/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj
index 1cd8144fe..3216564ed 100644
--- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj
+++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj
@@ -22,6 +22,7 @@
+
@@ -38,6 +39,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/GenerateKnowledgeFn.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/GenerateKnowledgeFn.cs
index cd43fca1d..114ce7e43 100644
--- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/GenerateKnowledgeFn.cs
+++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/Functions/GenerateKnowledgeFn.cs
@@ -1,5 +1,6 @@
using BotSharp.Abstraction.Templating;
using BotSharp.Core.Infrastructures;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace BotSharp.Plugin.KnowledgeBase.Functions;
@@ -20,14 +21,23 @@ public GenerateKnowledgeFn(IServiceProvider services, KnowledgeBaseSettings sett
public async Task Execute(RoleDialogModel message)
{
- var args = JsonSerializer.Deserialize(message.FunctionArgs ?? "{}");
+ var args = JsonSerializer.Deserialize(message.FunctionArgs ?? "{}");
var agentService = _services.GetRequiredService();
var llmAgent = await agentService.GetAgent(BuiltInAgentId.Planner);
- var generateKnowledgePrompt = await GetGenerateKnowledgePrompt(args.Question, args.Answer);
+ var refineKnowledge = args.RefinedCollection;
+ String generateKnowledgePrompt;
+ if (args.RefineAnswer == true)
+ {
+ generateKnowledgePrompt = await GetRefineKnowledgePrompt(args.Question, args.Answer, args.ExistingAnswer);
+ }
+ else
+ {
+ generateKnowledgePrompt = await GetGenerateKnowledgePrompt(args.Question, args.Answer);
+ }
var agent = new Agent
{
Id = message.CurrentAgentId ?? string.Empty,
- Name = "sqlDriver_DictionarySearch",
+ Name = "knowledge_generator",
Instruction = generateKnowledgePrompt,
LlmConfig = llmAgent.LlmConfig
};
@@ -51,6 +61,21 @@ private async Task GetGenerateKnowledgePrompt(string userQuestions, stri
{ "sql_answer", sqlAnswer },
});
}
+ private async Task GetRefineKnowledgePrompt(string userQuestion, string sqlAnswer, string existionAnswer)
+ {
+ var agentService = _services.GetRequiredService();
+ var render = _services.GetRequiredService();
+
+ var agent = await agentService.GetAgent(BuiltInAgentId.Learner);
+ var template = agent.Templates.FirstOrDefault(x => x.Name == "knowledge.generation.refine")?.Content ?? string.Empty;
+
+ return render.Render(template, new Dictionary
+ {
+ { "user_question", userQuestion },
+ { "new_answer", sqlAnswer },
+ { "existing_answer", existionAnswer}
+ });
+ }
private async Task GetAiResponse(Agent agent)
{
var text = "Generate question and answer pair";
diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.liquid b/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.liquid
index 49e374a1f..2792595a8 100644
--- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.liquid
+++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.liquid
@@ -1,4 +1,4 @@
-You are a knowledge generator for knowledge base. Extract the answer in "SQL Answer" to answer the User Questions.
+You are a knowledge extractor for knowledge base. Extract the answer in "SQL Answer" to answer the User Questions.
* Replace alias with the actual table name. Output json array only, formatting as [{"question":"string", "answer":""}].
* Skip the question/answer for tmp table.
* Don't include tmp table in the answer.
diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.refine.liquid b/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.refine.liquid
new file mode 100644
index 000000000..4a7af975b
--- /dev/null
+++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/data/agents/01acc3e5-0af7-49e6-ad7a-a760bd12dc40/templates/knowledge.generation.refine.liquid
@@ -0,0 +1,15 @@
+You are a knowledge extractor for knowledge base. Utilize the new answer and existing answer to generate the final integrated answer.
+Output json array only, formatting as [{"question":"", "answer":""}]. Replace the new line with \r\n.
+* Don't loss any knowledge in the existing answer.
+
+=====
+User Question:
+{{ user_question }}
+
+=====
+New Answer:
+{{ new_answer }}
+
+=====
+Existing Answer:
+{{ existing_answer }}
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_dictionary_lookup.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_dictionary_lookup.json
index 6ad2a9179..3dc21e013 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_dictionary_lookup.json
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_dictionary_lookup.json
@@ -1,6 +1,6 @@
{
"name": "verify_dictionary_term",
- "description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is True",
+ "description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true and is_insert is false",
"parameters": {
"type": "object",
"properties": {
@@ -12,6 +12,10 @@
"type": "string",
"description": "the reason why you need to call verify_dictionary_term"
},
+ "is_insert": {
+ "type": "boolean",
+ "description": "if SQL statement is inserting."
+ },
"tables": {
"type": "array",
"description": "all related tables",