Class: Vangrail::Rails::Grounding
- Inherits:
-
Vangrail::Rail
- Object
- Vangrail::Rail
- Vangrail::Rails::Grounding
- Defined in:
- lib/vangrail/rails/grounding.rb
Overview
Does the answer say only what its passages support.
Safety classifiers score hazards. For a retrieval system the failure that matters is different and they cannot see it: an invented partition name, a quota that appears nowhere, a citation pointing at a passage that does not support the sentence in front of it. Those read exactly like real answers to the person asking, which is the whole problem.
Output side only, and never memoized: the verdict depends on the passage set as well as the draft, so a changed retrieval must be judged again.
Constant Summary
Constants inherited from Vangrail::Rail
Vangrail::Rail::DEFAULT_SIDES, Vangrail::Rail::SIDES
Instance Attribute Summary collapse
-
#chat ⇒ Object
readonly
Returns the value of attribute chat.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#policy ⇒ Object
readonly
Returns the value of attribute policy.
Attributes inherited from Vangrail::Rail
Instance Method Summary collapse
-
#cache_key(_text, _context) ⇒ Object
Not memoizable.
- #decide(text, context) ⇒ Object
-
#initialize(provider: nil, model: nil, chat: nil, policy: nil, name: 'grounding', max_tokens: 256, **chat_options) ⇒ Grounding
constructor
A new instance of Grounding.
- #offline? ⇒ Boolean
Methods inherited from Vangrail::Rail
#applies_to?, #call, #language_agnostic?, #placeholder?, #posture?, #quantifies?, #to_s, usable
Constructor Details
#initialize(provider: nil, model: nil, chat: nil, policy: nil, name: 'grounding', max_tokens: 256, **chat_options) ⇒ Grounding
Returns a new instance of Grounding.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/vangrail/rails/grounding.rb', line 23 def initialize(provider: nil, model: nil, chat: nil, policy: nil, name: 'grounding', max_tokens: 256, **) super(name: name, sides: [:output]) @model = model || provider&.model(:judge) @policy = policy || Policies.grounding_policy @chat = chat || begin raise ArgumentError, 'a grounding rail needs a provider or a chat client' unless provider Chat.new(model: @model, base_url: provider.base_url, api_key: provider.api_key, max_tokens: max_tokens, **) end end |
Instance Attribute Details
#chat ⇒ Object (readonly)
Returns the value of attribute chat.
21 22 23 |
# File 'lib/vangrail/rails/grounding.rb', line 21 def chat @chat end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
21 22 23 |
# File 'lib/vangrail/rails/grounding.rb', line 21 def model @model end |
#policy ⇒ Object (readonly)
Returns the value of attribute policy.
21 22 23 |
# File 'lib/vangrail/rails/grounding.rb', line 21 def policy @policy end |
Instance Method Details
#cache_key(_text, _context) ⇒ Object
Not memoizable. Stated rather than left to a default so the reason is visible where the decision is.
42 43 44 |
# File 'lib/vangrail/rails/grounding.rb', line 42 def cache_key(_text, _context) nil end |
#decide(text, context) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/vangrail/rails/grounding.rb', line 46 def decide(text, context) passages = Array(context[:passages]) return unchecked('no passages supplied') if passages.empty? answer = chat.ask([ { 'role' => 'system', 'content' => policy }, { 'role' => 'user', 'content' => Policies.grounding_prompt(text, passages) }, ]) parsed = Parsers.policy(answer.text) unless parsed[:decided] return unchecked("unparsed judge response: #{parsed[:reason]}", model: model, latency_ms: answer.latency_ms, raw: answer.raw) end return pass(model: model, latency_ms: answer.latency_ms, raw: answer.raw) unless parsed[:violated] block(reason: parsed[:reason], categories: parsed[:categories], model: model, latency_ms: answer.latency_ms, raw: answer.raw) end |
#offline? ⇒ Boolean
36 37 38 |
# File 'lib/vangrail/rails/grounding.rb', line 36 def offline? false end |