Skip to content

Commit de24d46

Browse files
authored
Merge pull request #1002 from alphagov/472-use-claude-as-default
[CHAT-472] Use Claude as default LLM provider for answer composition
2 parents 9a85e17 + e778262 commit de24d46

11 files changed

Lines changed: 61 additions & 56 deletions

lib/answer_composition/pipeline/jailbreak_guardrails.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module AnswerComposition
22
module Pipeline
33
class JailbreakGuardrails
4-
def initialize(llm_provider: :openai)
4+
def initialize(llm_provider: :claude)
55
@llm_provider = llm_provider
66
end
77

lib/answer_composition/pipeline/output_guardrails.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module AnswerComposition
22
module Pipeline
33
class OutputGuardrails
4-
def initialize(llm_provider: :openai)
4+
def initialize(llm_provider: :claude)
55
@llm_provider = llm_provider
66
end
77

lib/guardrails/jailbreak_checker.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def self.guardrails_llm_prompts
5050

5151
def self.call(...) = new(...).call
5252

53-
def initialize(input, llm_provider = :openai)
53+
def initialize(input, llm_provider = :claude)
5454
@input = input
5555
@llm_provider = llm_provider
5656
end

spec/factories/output_guardrail_result_factory.rb

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,29 @@
55
llm_prompt_tokens { 13 }
66
llm_completion_tokens { 7 }
77
llm_cached_tokens { 10 }
8-
model { "gpt-4o-mini-2024-07-18" }
8+
model { BedrockModels.model_id(Guardrails::Claude::MultipleChecker::DEFAULT_MODEL) }
99

1010
llm_response do
11-
{
12-
"message": {
13-
"role": "assistant",
14-
"content": llm_guardrail_result,
15-
},
16-
"finish_reason": "stop",
17-
}
11+
content = Anthropic::Models::TextBlock.new(
12+
type: :text,
13+
text: llm_guardrail_result,
14+
)
15+
16+
usage = Anthropic::Models::Usage.new(
17+
input_tokens: llm_prompt_tokens,
18+
output_tokens: llm_completion_tokens,
19+
cache_read_input_tokens: llm_cached_tokens,
20+
)
21+
22+
Anthropic::Models::Message.new(
23+
id: "msg-id",
24+
model:,
25+
role: :assistant,
26+
content:,
27+
stop_reason: :end_turn,
28+
usage:,
29+
type: :message,
30+
).to_h
1831
end
1932

2033
trait :pass do

spec/lib/answer_composition/composer_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def stub_pipeline_initialize(klass, *args, **kwargs)
106106
end
107107

108108
context "when an error is returned during answer generation" do
109-
let(:question) { create :question, answer_strategy: :openai_structured_answer }
109+
let(:question) { create :question, answer_strategy: :claude_structured_answer }
110110
let(:result) { described_class.call(question) }
111111

112112
before do

spec/lib/answer_composition/pipeline/answer_guardrails_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
it_behaves_like "a passing guardrail pipeline step", "answer_guardrails"
3434

3535
it "does not abort the pipeline" do
36-
described_class.new(llm_provider: :openai).call(context)
36+
described_class.new(llm_provider: :claude).call(context)
3737
expect(context.aborted?).to be false
3838
end
3939
end
@@ -43,7 +43,7 @@
4343

4444
it "aborts the pipeline and updates the answer's status and message attributes" do
4545
expect {
46-
described_class.new(llm_provider: :openai).call(context)
46+
described_class.new(llm_provider: :claude).call(context)
4747
}.to throw_symbol(:abort)
4848

4949
expect(context.answer).to have_attributes(
@@ -55,21 +55,21 @@
5555
end
5656

5757
it "assigns the llm response to the answer" do
58-
expect { described_class.new(llm_provider: :openai).call(context) }.to throw_symbol(:abort)
58+
expect { described_class.new(llm_provider: :claude).call(context) }.to throw_symbol(:abort)
5959
expect(context.answer.llm_responses["answer_guardrails"]).to eq(guardrail_response.llm_response)
6060
end
6161

6262
it "assigns metrics to the answer" do
6363
allow(Clock).to receive(:monotonic_time).and_return(100.0, 101.5)
6464

65-
expect { described_class.new(llm_provider: :openai).call(context) }.to throw_symbol(:abort)
65+
expect { described_class.new(llm_provider: :claude).call(context) }.to throw_symbol(:abort)
6666

6767
expect(context.answer.metrics["answer_guardrails"]).to eq({
6868
duration: 1.5,
6969
llm_prompt_tokens: 13,
7070
llm_completion_tokens: 7,
7171
llm_cached_tokens: 10,
72-
model: "gpt-4o-mini-2024-07-18",
72+
model: BedrockModels.model_id(Guardrails::Claude::MultipleChecker::DEFAULT_MODEL),
7373
})
7474
end
7575
end

spec/lib/answer_composition/pipeline/jailbreak_guardrails_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
RSpec.describe AnswerComposition::Pipeline::JailbreakGuardrails do
22
let(:context) { build(:answer_pipeline_context) }
3-
let(:default_provider) { :openai }
3+
let(:default_provider) { :claude }
44

55
let(:llm_response) do
66
{
@@ -17,7 +17,7 @@
1717
let(:llm_prompt_tokens) { 10 }
1818
let(:llm_completion_tokens) { 5 }
1919
let(:llm_cached_tokens) { 0 }
20-
let(:model) { Guardrails::OpenAI::JailbreakChecker::OPENAI_MODEL }
20+
let(:model) { Guardrails::Claude::MultipleChecker.bedrock_model }
2121

2222
context "when the guardrails are not triggered" do
2323
before do

spec/lib/answer_composition/pipeline/question_routing_guardrails_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737

3838
context.answer.question_routing_label = "genuine_rag"
3939

40-
described_class.new(llm_provider: :openai).call(context)
40+
described_class.new(llm_provider: :claude).call(context)
4141
end
4242

4343
it "aborts the pipeline" do
44-
described_class.new(llm_provider: :openai).call(context)
44+
described_class.new(llm_provider: :claude).call(context)
4545
expect(context.aborted?).to be true
4646
end
4747
end
@@ -50,7 +50,7 @@
5050
let(:guardrail_response) { build(:guardrails_multiple_checker_result, :fail) }
5151

5252
it "sets the attributes on the answer" do
53-
described_class.new(llm_provider: :openai).call(context)
53+
described_class.new(llm_provider: :claude).call(context)
5454

5555
expect(context.answer).to have_attributes({
5656
message: Answer::CannedResponses::QUESTION_ROUTING_GUARDRAILS_FAILED_MESSAGE,
@@ -60,7 +60,7 @@
6060
end
6161

6262
it "aborts the pipeline and assigns the right attributes" do
63-
described_class.new(llm_provider: :openai).call(context)
63+
described_class.new(llm_provider: :claude).call(context)
6464

6565
expect(context.aborted?).to be true
6666
expect(context.answer.question_routing_guardrails_status).to eq("fail")

spec/lib/guardrails/jailbreak_checker_spec.rb

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
RSpec.describe Guardrails::JailbreakChecker do
1+
RSpec.describe Guardrails::JailbreakChecker, :aws_credentials_stubbed do
22
let(:input) { "User question" }
33
let(:pass_value) { "PassValue" }
44

55
before do
66
allow(described_class).to receive_messages(pass_value:)
77
end
88

9-
it "calls the OpenAI jailbreak checker by default" do
9+
it "calls the Claude jailbreak checker by default" do
1010
result = {
1111
llm_guardrail_result: pass_value,
1212
llm_response: {
@@ -21,12 +21,12 @@
2121
},
2222
}
2323

24-
allow(Guardrails::OpenAI::JailbreakChecker).to receive(:call).and_return(result)
24+
allow(Guardrails::Claude::JailbreakChecker).to receive(:call).and_return(result)
2525
described_class.call(input)
26-
expect(Guardrails::OpenAI::JailbreakChecker).to have_received(:call).with(input)
26+
expect(Guardrails::Claude::JailbreakChecker).to have_received(:call).with(input)
2727
end
2828

29-
it "calls the Claude jailbreak checker when the provider is specified as :claude" do
29+
it "calls the OpenAI jailbreak checker when the provider is specified as :openai" do
3030
result = {
3131
llm_guardrail_result: pass_value,
3232
llm_response: {
@@ -41,31 +41,33 @@
4141
},
4242
}
4343

44-
allow(Guardrails::Claude::JailbreakChecker).to receive(:call).and_return(result)
45-
described_class.call(input, :claude)
46-
expect(Guardrails::Claude::JailbreakChecker).to have_received(:call).with(input)
44+
allow(Guardrails::OpenAI::JailbreakChecker).to receive(:call).and_return(result)
45+
described_class.call(input, :openai)
46+
expect(Guardrails::OpenAI::JailbreakChecker).to have_received(:call).with(input)
4747
end
4848

4949
it "returns a result object" do
50-
stub_openai_jailbreak_guardrails(input)
50+
stub_claude_jailbreak_guardrails(input)
5151

5252
result = described_class.call(input)
53+
5354
expect(result)
5455
.to be_an_instance_of(described_class::Result)
5556
.and have_attributes(
5657
triggered: boolean,
57-
llm_response: hash_including("message", "finish_reason", "index"),
58+
llm_response: hash_including(:content, :stop_reason),
5859
llm_prompt_tokens: be_a(Integer),
5960
llm_completion_tokens: be_a(Integer),
6061
llm_cached_tokens: be_a(Integer).or(be_nil),
62+
model: be_a(String),
6163
)
6264
end
6365

6466
it "returns a result object with triggered true when guardrails fail" do
65-
allow(Guardrails::OpenAI::JailbreakChecker).to receive(:call).with(input).and_call_original
66-
stub_openai_jailbreak_guardrails(input, triggered: true)
67+
allow(Guardrails::Claude::JailbreakChecker).to receive(:call).with(input).and_call_original
68+
stub_claude_jailbreak_guardrails(input, triggered: true)
6769
second_input = "Second user question"
68-
allow(Guardrails::OpenAI::JailbreakChecker)
70+
allow(Guardrails::Claude::JailbreakChecker)
6971
.to receive(:call)
7072
.with(second_input)
7173
.and_return({
@@ -88,7 +90,7 @@
8890
end
8991

9092
it "returns a result object with triggered false when guardrails pass" do
91-
stub_openai_jailbreak_guardrails(input, triggered: false)
93+
stub_claude_jailbreak_guardrails(input, triggered: false)
9294
expect(described_class.call(input)).to have_attributes(triggered: false)
9395
end
9496
end

spec/lib/guardrails/multiple_checker_spec.rb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,12 @@
77
let(:llm_prompt_name) { :answer_guardrails }
88
let(:guardrail_response_hash) do
99
{
10-
llm_response: {
11-
message: {
12-
role: "assistant",
13-
content: "False | None",
14-
},
15-
finish_reason: "stop",
16-
},
10+
llm_response: guardrail_result.llm_response,
1711
llm_guardrail_result: "False | None",
1812
llm_prompt_tokens: 13,
1913
llm_completion_tokens: 7,
2014
llm_cached_tokens: 10,
21-
model: "gpt-4o-mini-2024-07-18",
15+
model: BedrockModels.model_id(Guardrails::Claude::MultipleChecker::DEFAULT_MODEL),
2216
}
2317
end
2418
let(:guardrail_result) { build(:guardrails_multiple_checker_result, :pass) }

0 commit comments

Comments
 (0)