| | | 1 | | using Intentum.Core.Behavior; |
| | | 2 | | using Intentum.Core.Contracts; |
| | | 3 | | using Intentum.Core.Intents; |
| | | 4 | | |
| | | 5 | | namespace Intentum.AI.FewShot; |
| | | 6 | | |
| | | 7 | | public sealed class FewShotIntentModel : IIntentModel |
| | | 8 | | { |
| | | 9 | | private readonly IFewShotStore _store; |
| | | 10 | | private readonly double _similarityThreshold; |
| | | 11 | | |
| | 3 | 12 | | public FewShotIntentModel(IFewShotStore store, double similarityThreshold = 0.3) |
| | 3 | 13 | | { |
| | 3 | 14 | | _store = store; |
| | 3 | 15 | | _similarityThreshold = similarityThreshold; |
| | 3 | 16 | | } |
| | | 17 | | |
| | | 18 | | public Intent Infer(BehaviorSpace behaviorSpace, BehaviorVector? precomputedVector = null) |
| | 3 | 19 | | { |
| | 3 | 20 | | var keys = behaviorSpace.Events |
| | 4 | 21 | | .Select(e => e.Action) |
| | 3 | 22 | | .Distinct() |
| | 3 | 23 | | .ToArray(); |
| | | 24 | | |
| | 3 | 25 | | var matches = _store.FindSimilar(keys, topK: 1); |
| | | 26 | | |
| | 3 | 27 | | if (matches.Count == 0) |
| | 2 | 28 | | return new Intent("Unknown", [], new IntentConfidence(0, "Low")); |
| | | 29 | | |
| | 1 | 30 | | var best = matches[0]; |
| | 1 | 31 | | var overlap = best.BehaviorKeys.Intersect(keys).Count(); |
| | 1 | 32 | | var maxPossible = Math.Max(best.BehaviorKeys.Count, keys.Length); |
| | 1 | 33 | | var similarity = maxPossible > 0 ? (double)overlap / maxPossible : 0; |
| | | 34 | | |
| | 1 | 35 | | var score = similarity * best.Confidence; |
| | | 36 | | |
| | 1 | 37 | | if (score < _similarityThreshold) |
| | 0 | 38 | | return new Intent("Unknown", [], new IntentConfidence(score, "Low")); |
| | | 39 | | |
| | 1 | 40 | | return new Intent(best.IntentName, [], new IntentConfidence(score, |
| | 1 | 41 | | IntentConfidence.FromScore(score).Level)); |
| | 3 | 42 | | } |
| | | 43 | | } |