| | | 1 | | using Intentum.Core.Behavior; |
| | | 2 | | using Intentum.Core.Contracts; |
| | | 3 | | using Intentum.Core.Intents; |
| | | 4 | | |
| | | 5 | | namespace Intentum.Core.Models; |
| | | 6 | | |
| | | 7 | | /// <summary> |
| | | 8 | | /// Multi-stage intent model: runs a sequence of models; first result with confidence above threshold wins. |
| | | 9 | | /// E.g. Stage1 = rules, Stage2 = clustering-based, Stage3 = LLM for ambiguous cases only. |
| | | 10 | | /// </summary> |
| | | 11 | | public sealed class MultiStageIntentModel : IIntentModel |
| | | 12 | | { |
| | | 13 | | private readonly IReadOnlyList<(IIntentModel Model, double ConfidenceThreshold)> _stages; |
| | | 14 | | |
| | | 15 | | /// <summary> |
| | | 16 | | /// Creates a multi-stage intent model. Each stage is (model, threshold). First stage whose result has confidence >= |
| | | 17 | | /// </summary> |
| | | 18 | | /// <param name="stages">Ordered list of (model, confidence threshold). Typical: (RuleBasedIntentModel, 0.85), (Clus |
| | 6 | 19 | | public MultiStageIntentModel(IEnumerable<(IIntentModel Model, double ConfidenceThreshold)>? stages) |
| | 6 | 20 | | { |
| | 6 | 21 | | var list = stages?.ToList() ?? throw new ArgumentNullException(nameof(stages)); |
| | 5 | 22 | | if (list.Count == 0) |
| | 1 | 23 | | throw new ArgumentException("At least one stage required.", nameof(stages)); |
| | 11 | 24 | | _stages = list.Select(s => (s.Model, Math.Clamp(s.ConfidenceThreshold, 0, 1))).ToList(); |
| | 4 | 25 | | } |
| | | 26 | | |
| | | 27 | | /// <inheritdoc /> |
| | | 28 | | public Intent Infer(BehaviorSpace behaviorSpace, BehaviorVector? precomputedVector = null) |
| | 4 | 29 | | { |
| | 4 | 30 | | Intent? lastIntent = null; |
| | 22 | 31 | | foreach (var (model, threshold) in _stages) |
| | 6 | 32 | | { |
| | 6 | 33 | | var intent = model.Infer(behaviorSpace, precomputedVector); |
| | 6 | 34 | | lastIntent = intent; |
| | 6 | 35 | | if (intent.Confidence.Score >= threshold) |
| | 2 | 36 | | { |
| | 2 | 37 | | var reasoning = intent.Reasoning != null |
| | 2 | 38 | | ? intent.Reasoning |
| | 2 | 39 | | : $"Stage confidence {intent.Confidence.Score:F2} >= {threshold}"; |
| | 2 | 40 | | return intent with { Reasoning = reasoning }; |
| | | 41 | | } |
| | 4 | 42 | | } |
| | 2 | 43 | | var fallback = lastIntent!; |
| | 2 | 44 | | return fallback with { Reasoning = fallback.Reasoning ?? "Multi-stage: last stage (no threshold met)" }; |
| | 4 | 45 | | } |
| | | 46 | | } |