Skip to content

Commit d5daa92

Browse files
authored
Merge pull request #596 from iceljc/bugfix/refine-knowledge-base
unite knowledge search model
2 parents f6eb4bd + d99d897 commit d5daa92

File tree

15 files changed

+116
-128
lines changed

15 files changed

+116
-128
lines changed

src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ namespace BotSharp.Abstraction.Knowledges;
33
public interface IKnowledgeService
44
{
55
Task<IEnumerable<string>> GetKnowledgeCollections();
6-
Task<IEnumerable<KnowledgeRetrievalResult>> SearchKnowledge(string collectionName, KnowledgeRetrievalOptions options);
6+
Task<IEnumerable<KnowledgeSearchResult>> SearchKnowledge(string collectionName, KnowledgeSearchOptions options);
77
Task FeedKnowledge(string collectionName, KnowledgeCreationModel model);
8-
Task<StringIdPagedItems<KnowledgeCollectionData>> GetKnowledgeCollectionData(string collectionName, KnowledgeFilter filter);
8+
Task<StringIdPagedItems<KnowledgeSearchResult>> GetKnowledgeCollectionData(string collectionName, KnowledgeFilter filter);
99
Task<bool> DeleteKnowledgeCollectionData(string collectionName, string id);
1010
}

src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/KnowledgeCollectionData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace BotSharp.Abstraction.Knowledges.Models;
33
public class KnowledgeCollectionData
44
{
55
public string Id { get; set; }
6-
public string Question { get; set; }
7-
public string Answer { get; set; }
6+
public Dictionary<string, string> Data { get; set; } = new();
7+
public double? Score { get; set; }
88
public float[]? Vector { get; set; }
9-
}
9+
}

src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/KnowledgeRetrievalOptions.cs renamed to src/Infrastructure/BotSharp.Abstraction/Knowledges/Models/KnowledgeSearchOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace BotSharp.Abstraction.Knowledges.Models;
44

5-
public class KnowledgeRetrievalOptions
5+
public class KnowledgeSearchOptions
66
{
77
public string Text { get; set; } = string.Empty;
88
public IEnumerable<string>? Fields { get; set; } = new List<string> { KnowledgePayloadName.Text, KnowledgePayloadName.Answer };
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
namespace BotSharp.Abstraction.Knowledges.Models;
22

3-
public class KnowledgeSearchResult
3+
public class KnowledgeSearchResult : KnowledgeCollectionData
44
{
5-
public Dictionary<string, string> Data { get; set; } = new();
6-
public double Score { get; set; }
7-
public float[]? Vector { get; set; }
8-
}
5+
public KnowledgeSearchResult()
6+
{
7+
8+
}
99

10-
public class KnowledgeRetrievalResult : KnowledgeSearchResult
11-
{
10+
public static KnowledgeSearchResult CopyFrom(KnowledgeCollectionData data)
11+
{
12+
return new KnowledgeSearchResult
13+
{
14+
Id = data.Id,
15+
Data = data.Data,
16+
Score = data.Score,
17+
Vector = data.Vector
18+
};
19+
}
1220
}

src/Infrastructure/BotSharp.Abstraction/VectorStorage/IVectorDb.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ namespace BotSharp.Abstraction.VectorStorage;
33
public interface IVectorDb
44
{
55
string Name { get; }
6-
6+
77
Task<IEnumerable<string>> GetCollections();
88
Task<StringIdPagedItems<KnowledgeCollectionData>> GetCollectionData(string collectionName, KnowledgeFilter filter);
99
Task CreateCollection(string collectionName, int dim);
1010
Task<bool> Upsert(string collectionName, string id, float[] vector, string text, Dictionary<string, string>? payload = null);
11-
Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionName, float[] vector, IEnumerable<string> fields, int limit = 5, float confidence = 0.5f, bool withVector = false);
11+
Task<IEnumerable<KnowledgeCollectionData>> Search(string collectionName, float[] vector, IEnumerable<string>? fields, int limit = 5, float confidence = 0.5f, bool withVector = false);
1212
Task<bool> DeleteCollectionData(string collectionName, string id);
1313
}

src/Infrastructure/BotSharp.OpenAPI/Controllers/KnowledgeBaseController.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ public async Task<IEnumerable<string>> GetKnowledgeCollections()
2323
}
2424

2525
[HttpPost("/knowledge/{collection}/search")]
26-
public async Task<IEnumerable<KnowledgeRetrivalViewModel>> SearchKnowledge([FromRoute] string collection, [FromBody] SearchKnowledgeModel model)
26+
public async Task<IEnumerable<KnowledgeSearchResultViewModel>> SearchKnowledge([FromRoute] string collection, [FromBody] SearchKnowledgeRequest request)
2727
{
28-
var options = new KnowledgeRetrievalOptions
28+
var options = new KnowledgeSearchOptions
2929
{
30-
Text = model.Text,
31-
Fields = model.Fields,
32-
Limit = model.Limit ?? 5,
33-
Confidence = model.Confidence ?? 0.5f,
34-
WithVector = model.WithVector
30+
Text = request.Text,
31+
Fields = request.Fields,
32+
Limit = request.Limit ?? 5,
33+
Confidence = request.Confidence ?? 0.5f,
34+
WithVector = request.WithVector
3535
};
3636

3737
var results = await _knowledgeService.SearchKnowledge(collection, options);
38-
return results.Select(x => KnowledgeRetrivalViewModel.From(x)).ToList();
38+
return results.Select(x => KnowledgeSearchResultViewModel.From(x)).ToList();
3939
}
4040

4141
[HttpPost("/knowledge/{collection}/data")]
42-
public async Task<StringIdPagedItems<KnowledgeCollectionDataViewModel>> GetKnowledgeCollectionData([FromRoute] string collection, [FromBody] KnowledgeFilter filter)
42+
public async Task<StringIdPagedItems<KnowledgeSearchResultViewModel>> GetKnowledgeCollectionData([FromRoute] string collection, [FromBody] KnowledgeFilter filter)
4343
{
4444
var data = await _knowledgeService.GetKnowledgeCollectionData(collection, filter);
45-
var items = data.Items?.Select(x => KnowledgeCollectionDataViewModel.From(x))?
46-
.ToList() ?? new List<KnowledgeCollectionDataViewModel>();
45+
var items = data.Items?.Select(x => KnowledgeSearchResultViewModel.From(x))?
46+
.ToList() ?? new List<KnowledgeSearchResultViewModel>();
4747

48-
return new StringIdPagedItems<KnowledgeCollectionDataViewModel>
48+
return new StringIdPagedItems<KnowledgeSearchResultViewModel>
4949
{
5050
Count = data.Count,
5151
NextId = data.NextId,

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Knowledges/KnowledgeCollectionDataViewModel.cs

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Knowledges/KnowledgeRetrivalViewModel.cs

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using BotSharp.Abstraction.Knowledges.Models;
2+
using System.Text.Json.Serialization;
3+
4+
namespace BotSharp.OpenAPI.ViewModels.Knowledges;
5+
6+
public class KnowledgeSearchResultViewModel
7+
{
8+
[JsonPropertyName("id")]
9+
public string Id { get; set; }
10+
11+
[JsonPropertyName("data")]
12+
public IDictionary<string, string> Data { get; set; }
13+
14+
[JsonPropertyName("score")]
15+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
16+
public double? Score { get; set; }
17+
18+
[JsonPropertyName("vector")]
19+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
20+
public float[]? Vector { get; set; }
21+
22+
23+
public static KnowledgeSearchResultViewModel From(KnowledgeSearchResult result)
24+
{
25+
return new KnowledgeSearchResultViewModel
26+
{
27+
Id = result.Id,
28+
Data = result.Data,
29+
Score = result.Score,
30+
Vector = result.Vector
31+
};
32+
}
33+
}

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Knowledges/SearchKnowledgeModel.cs renamed to src/Infrastructure/BotSharp.OpenAPI/ViewModels/Knowledges/SearchKnowledgeRequest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace BotSharp.OpenAPI.ViewModels.Knowledges;
55

6-
public class SearchKnowledgeModel
6+
public class SearchKnowledgeRequest
77
{
88
[JsonPropertyName("text")]
99
public string Text { get; set; } = string.Empty;

src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemoryVectorDb.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ public Task<StringIdPagedItems<KnowledgeCollectionData>> GetCollectionData(strin
2727
throw new NotImplementedException();
2828
}
2929

30-
public async Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionName, float[] vector,
31-
IEnumerable<string> fields, int limit = 5, float confidence = 0.5f, bool withVector = false)
30+
public async Task<IEnumerable<KnowledgeCollectionData>> Search(string collectionName, float[] vector,
31+
IEnumerable<string>? fields, int limit = 5, float confidence = 0.5f, bool withVector = false)
3232
{
3333
if (!_vectors.ContainsKey(collectionName))
3434
{
35-
return new List<KnowledgeSearchResult>();
35+
return new List<KnowledgeCollectionData>();
3636
}
3737

3838
var similarities = VectorUtility.CalCosineSimilarity(vector, _vectors[collectionName]);
@@ -41,7 +41,7 @@ public async Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionNa
4141
var results = np.argsort(similarities).ToArray<int>()
4242
.Reverse()
4343
.Take(limit)
44-
.Select(i => new KnowledgeSearchResult
44+
.Select(i => new KnowledgeCollectionData
4545
{
4646
Data = new Dictionary<string, string> { { "text", _vectors[collectionName][i].Text } },
4747
Score = similarities[i],
@@ -64,8 +64,8 @@ public async Task<bool> Upsert(string collectionName, string id, float[] vector,
6464
return true;
6565
}
6666

67-
public Task<bool> DeleteCollectionData(string collectionName, string id)
67+
public async Task<bool> DeleteCollectionData(string collectionName, string id)
6868
{
69-
throw new NotImplementedException();
69+
return await Task.FromResult(false);
7070
}
7171
}

src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Get.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,27 @@ public async Task<IEnumerable<string>> GetKnowledgeCollections()
1616
}
1717
}
1818

19-
public async Task<StringIdPagedItems<KnowledgeCollectionData>> GetKnowledgeCollectionData(string collectionName, KnowledgeFilter filter)
19+
public async Task<StringIdPagedItems<KnowledgeSearchResult>> GetKnowledgeCollectionData(string collectionName, KnowledgeFilter filter)
2020
{
2121
try
2222
{
2323
var db = GetVectorDb();
24-
return await db.GetCollectionData(collectionName, filter);
24+
var pagedResult = await db.GetCollectionData(collectionName, filter);
25+
return new StringIdPagedItems<KnowledgeSearchResult>
26+
{
27+
Count = pagedResult.Count,
28+
Items = pagedResult.Items.Select(x => KnowledgeSearchResult.CopyFrom(x)),
29+
NextId = pagedResult.NextId,
30+
};
2531
}
2632
catch (Exception ex)
2733
{
2834
_logger.LogWarning($"Error when getting knowledge collection data ({collectionName}). {ex.Message}\r\n{ex.InnerException}");
29-
return new StringIdPagedItems<KnowledgeCollectionData>();
35+
return new StringIdPagedItems<KnowledgeSearchResult>();
3036
}
3137
}
3238

33-
public async Task<IEnumerable<KnowledgeRetrievalResult>> SearchKnowledge(string collectionName, KnowledgeRetrievalOptions options)
39+
public async Task<IEnumerable<KnowledgeSearchResult>> SearchKnowledge(string collectionName, KnowledgeSearchOptions options)
3440
{
3541
try
3642
{
@@ -39,21 +45,15 @@ public async Task<IEnumerable<KnowledgeRetrievalResult>> SearchKnowledge(string
3945

4046
// Vector search
4147
var db = GetVectorDb();
42-
var fields = !options.Fields.IsNullOrEmpty() ? options.Fields : new List<string> { KnowledgePayloadName.Text, KnowledgePayloadName.Answer };
43-
var found = await db.Search(collectionName, vector, fields, limit: options.Limit ?? 5, confidence: options.Confidence ?? 0.5f, withVector: options.WithVector);
48+
var found = await db.Search(collectionName, vector, options.Fields, limit: options.Limit ?? 5, confidence: options.Confidence ?? 0.5f, withVector: options.WithVector);
4449

45-
var results = found.Select(x => new KnowledgeRetrievalResult
46-
{
47-
Data = x.Data,
48-
Score = x.Score,
49-
Vector = x.Vector
50-
}).ToList();
50+
var results = found.Select(x => KnowledgeSearchResult.CopyFrom(x)).ToList();
5151
return results;
5252
}
5353
catch (Exception ex)
5454
{
5555
_logger.LogWarning($"Error when searching knowledge ({collectionName}). {ex.Message}\r\n{ex.InnerException}");
56-
return new List<KnowledgeRetrievalResult>();
56+
return new List<KnowledgeSearchResult>();
5757
}
5858
}
5959
}

src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public Task<IEnumerable<string>> GetCollections()
2626
throw new NotImplementedException();
2727
}
2828

29-
public Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionName, float[] vector,
30-
IEnumerable<string> fields, int limit = 10, float confidence = 0.5f, bool withVector = false)
29+
public Task<IEnumerable<KnowledgeCollectionData>> Search(string collectionName, float[] vector,
30+
IEnumerable<string>? fields, int limit = 10, float confidence = 0.5f, bool withVector = false)
3131
{
3232
throw new NotImplementedException();
3333
}

src/Plugins/BotSharp.Plugin.Qdrant/QdrantDb.cs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ public async Task<StringIdPagedItems<KnowledgeCollectionData>> GetCollectionData
5757
var points = response?.Result?.Select(x => new KnowledgeCollectionData
5858
{
5959
Id = x.Id?.Uuid ?? string.Empty,
60-
Question = x.Payload.ContainsKey(KnowledgePayloadName.Text) ? x.Payload[KnowledgePayloadName.Text].StringValue : string.Empty,
61-
Answer = x.Payload.ContainsKey(KnowledgePayloadName.Answer) ? x.Payload[KnowledgePayloadName.Answer].StringValue : string.Empty,
60+
Data = x.Payload.ToDictionary(x => x.Key, x => x.Value.StringValue),
6261
Vector = filter.WithVector ? x.Vectors?.Vector?.Data?.ToArray() : null
6362
})?.ToList() ?? new List<KnowledgeCollectionData>();
6463

@@ -125,10 +124,10 @@ public async Task<bool> Upsert(string collectionName, string id, float[] vector,
125124
return result.Status == UpdateStatus.Completed;
126125
}
127126

128-
public async Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionName, float[] vector,
129-
IEnumerable<string> fields, int limit = 5, float confidence = 0.5f, bool withVector = false)
127+
public async Task<IEnumerable<KnowledgeCollectionData>> Search(string collectionName, float[] vector,
128+
IEnumerable<string>? fields, int limit = 5, float confidence = 0.5f, bool withVector = false)
130129
{
131-
var results = new List<KnowledgeSearchResult>();
130+
var results = new List<KnowledgeCollectionData>();
132131

133132
var client = GetClient();
134133
var exist = await DoesCollectionExist(client, collectionName);
@@ -138,24 +137,33 @@ public async Task<IEnumerable<KnowledgeSearchResult>> Search(string collectionNa
138137
}
139138

140139
var points = await client.SearchAsync(collectionName, vector, limit: (ulong)limit, scoreThreshold: confidence);
141-
140+
141+
var pickFields = fields != null;
142142
foreach (var point in points)
143143
{
144144
var data = new Dictionary<string, string>();
145-
foreach (var field in fields)
145+
if (pickFields)
146146
{
147-
if (point.Payload.ContainsKey(field))
148-
{
149-
data[field] = point.Payload[field].StringValue;
150-
}
151-
else
147+
foreach (var field in fields)
152148
{
153-
data[field] = "";
149+
if (point.Payload.ContainsKey(field))
150+
{
151+
data[field] = point.Payload[field].StringValue;
152+
}
153+
else
154+
{
155+
data[field] = "";
156+
}
154157
}
155158
}
159+
else
160+
{
161+
data = point.Payload.ToDictionary(k => k.Key, v => v.Value.StringValue);
162+
}
156163

157-
results.Add(new KnowledgeSearchResult
164+
results.Add(new KnowledgeCollectionData
158165
{
166+
Id = point.Id.Uuid,
159167
Data = data,
160168
Score = point.Score,
161169
Vector = withVector ? point.Vectors?.Vector?.Data?.ToArray() : null

0 commit comments

Comments
 (0)