Class: Insika::Distill::Distiller
- Inherits:
-
Object
- Object
- Insika::Distill::Distiller
- Defined in:
- lib/insika/distill.rb
Overview
The model's answer, filtered into data the command then dedups and a human
then gates. Pure over an injected ask — the Refinement::Proposer shape:
unit-testable without a provider, and the real ask is a lambda built by
DistillerFactory (ruby_llm required lazily, load_guard stays green).
Defined Under Namespace
Classes: Unusable
Constant Summary collapse
- MAX_NAME_LENGTH =
120- MAX_VALUE_LENGTH =
500- MAX_TURNS =
20- ALLOWED_KEYS =
%w[name value confidence turns].freeze
- DROP_KEYS =
The E4 audit counters: schema (shape/type/confidence range), unknown_key (a model-authored key — the D1 escape), oversized (length caps), bad_turns (evidence indexes), duplicate (exact repeats), capped (a survivor over max_proposals).
%w[schema unknown_key oversized bad_turns duplicate capped].freeze
Instance Attribute Summary collapse
-
#model ⇒ Object
readonly
ask: ->(prompt) { "
" } | something answering #content (+ #input_tokens/#output_tokens/#cached_tokens for cost).
Instance Method Summary collapse
-
#distill(prompt:, message_count:, max_proposals: 10) ⇒ Object
-> { proposals: [{ "name", "value", "confidence"?, "turns"? }], dropped: { "schema" => N, "unknown_key" => N, "oversized" => N, "bad_turns" => N, "duplicate" => N }, cost: { "spent" => N, "cached" => N } | nil } prompt: the pack prompt or DEFAULT_PROMPT (the caller resolved it).
-
#initialize(ask:, model: "utility_model") ⇒ Distiller
constructor
A new instance of Distiller.
Constructor Details
#initialize(ask:, model: "utility_model") ⇒ Distiller
Returns a new instance of Distiller.
80 81 82 83 |
# File 'lib/insika/distill.rb', line 80 def initialize(ask:, model: "utility_model") @ask = ask @model = model.to_s end |
Instance Attribute Details
#model ⇒ Object (readonly)
ask: ->(prompt) { "
78 79 80 |
# File 'lib/insika/distill.rb', line 78 def model @model end |
Instance Method Details
#distill(prompt:, message_count:, max_proposals: 10) ⇒ Object
-> { proposals: [{ "name", "value", "confidence"?, "turns"? }], dropped: { "schema" => N, "unknown_key" => N, "oversized" => N, "bad_turns" => N, "duplicate" => N }, cost: { "spent" => N, "cached" => N } | nil } prompt: the pack prompt or DEFAULT_PROMPT (the caller resolved it). message_count: the session transcript size — turns are validated against it (an index >= message_count drops the proposal). max_proposals: cap on surviving proposals (the model may return more). Drops are counted, never fixed up.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/insika/distill.rb', line 94 def distill(prompt:, message_count:, max_proposals: 10) answer = @ask.call(prompt) raw = parse(text_of(answer)) proposals = [] dropped = DROP_KEYS.to_h { |k| [k, 0] } seen = {} raw.each do |item| verdict, reason = classify(item, ) case verdict when :keep tuple = [item["name"].to_s, item["value"].to_s] if seen[tuple] dropped["duplicate"] += 1 elsif proposals.size >= max_proposals dropped["capped"] += 1 else seen[tuple] = true proposals << normalize(item) end when :drop dropped[reason] += 1 end end { proposals: proposals, dropped: dropped, cost: cost_of(answer) } end |