@@ -9,6 +9,10 @@ def triggered_guardrails
99 end
1010 end
1111
12+ MAX_TOKENS = 100
13+ SUPPORTED_MODELS = %i[ claude_sonnet_4_0 claude_haiku_4_5 ] . freeze
14+ DEFAULT_MODEL = :claude_sonnet_4_0
15+
1216 class ResponseError < StandardError
1317 attr_reader :llm_response , :llm_guardrail_result , :llm_prompt_tokens ,
1418 :llm_completion_tokens , :llm_cached_tokens , :model
@@ -35,12 +39,10 @@ class Prompt
3539
3640 Guardrail = Data . define ( :key , :name , :content )
3741
38- def initialize ( prompt_name , llm_provider = :claude )
39- prompts = if llm_provider == :claude
40- AnswerComposition ::Pipeline ::Prompts . config ( prompt_name , Claude ::MultipleChecker . bedrock_model )
41- else
42- Rails . configuration . govuk_chat_private . llm_prompts [ llm_provider ] [ prompt_name ]
43- end
42+ def initialize ( prompt_name )
43+ prompts = AnswerComposition ::Pipeline ::Prompts . config (
44+ prompt_name , Guardrails ::MultipleChecker . bedrock_model
45+ )
4446
4547 raise "No LLM prompts found for #{ prompt_name } " unless prompts
4648
@@ -72,8 +74,12 @@ def guardrails
7274
7375 def self . call ( ...) = new ( ...) . call
7476
75- def self . collated_prompts ( llm_prompt_name , llm_provider )
76- prompt = Prompt . new ( llm_prompt_name , llm_provider )
77+ def self . bedrock_model
78+ BedrockModels . determine_model ( ENV [ "BEDROCK_CLAUDE_GUARDRAILS_MODEL" ] , DEFAULT_MODEL , SUPPORTED_MODELS ) . last
79+ end
80+
81+ def self . collated_prompts ( llm_prompt_name )
82+ prompt = Prompt . new ( llm_prompt_name )
7783
7884 <<~PROMPT
7985 # System prompt
@@ -85,38 +91,46 @@ def self.collated_prompts(llm_prompt_name, llm_provider)
8591 PROMPT
8692 end
8793
88- def initialize ( input , llm_prompt_name , llm_provider )
94+ def initialize ( input , llm_prompt_name )
8995 @input = input
9096 @llm_prompt_name = llm_prompt_name
91- @llm_provider = llm_provider
9297 end
9398
9499 def call
95- case llm_provider
96- when :claude
97- response = Claude ::MultipleChecker . call ( input , prompt )
98- else
99- raise "Unexpected provider #{ llm_provider } "
100- end
101- parse_response ( **response )
100+ response = anthropic_bedrock_client . messages . create (
101+ system : [ { type : "text" , text : prompt . system_prompt , cache_control : { type : "ephemeral" } } ] ,
102+ model : BedrockModels . model_id ( self . class . bedrock_model ) ,
103+ messages : [ { role : "user" , content : prompt . user_prompt ( input ) } ] ,
104+ max_tokens : MAX_TOKENS ,
105+ )
106+
107+ parse_response ( response )
102108 end
103109
104110 private
105111
106- def parse_response ( llm_response :,
107- llm_guardrail_result :,
108- llm_prompt_tokens :,
109- llm_completion_tokens :,
110- llm_cached_tokens :,
111- model :)
112+ def anthropic_bedrock_client
113+ @anthropic_bedrock_client ||= Anthropic ::BedrockClient . new (
114+ aws_region : ENV [ "CLAUDE_AWS_REGION" ] ,
115+ )
116+ end
117+
118+ def parse_response ( response )
119+ llm_response = response . to_h
120+ llm_guardrail_result = response [ :content ] [ 0 ] [ :text ]
121+ input_tokens = response [ :usage ] [ :input_tokens ]
122+ output_tokens = response [ :usage ] [ :output_tokens ]
123+ cache_read_input_tokens = response [ :usage ] [ :cache_read_input_tokens ]
124+ model = response [ :model ]
125+
112126 unless response_pattern =~ llm_guardrail_result
113127 raise ResponseError . new (
114128 "Error parsing guardrail response" ,
115129 llm_response ,
116130 llm_guardrail_result ,
117- llm_prompt_tokens ,
118- llm_completion_tokens ,
119- llm_cached_tokens ,
131+ input_tokens ,
132+ output_tokens ,
133+ cache_read_input_tokens ,
120134 model ,
121135 )
122136 end
@@ -126,19 +140,19 @@ def parse_response(llm_response:,
126140 guardrails = to_guardrail_hash ( parts . second )
127141
128142 Result . new (
129- llm_response : llm_response ,
130- llm_guardrail_result : llm_guardrail_result ,
131- triggered : triggered ,
132- guardrails : guardrails ,
133- llm_prompt_tokens : llm_prompt_tokens ,
134- llm_completion_tokens : llm_completion_tokens ,
135- llm_cached_tokens : llm_cached_tokens ,
143+ llm_response :,
144+ llm_guardrail_result :,
145+ triggered :,
146+ guardrails :,
147+ llm_prompt_tokens : input_tokens ,
148+ llm_completion_tokens : output_tokens ,
149+ llm_cached_tokens : cache_read_input_tokens ,
136150 model :,
137151 )
138152 end
139153
140154 def prompt
141- @prompt ||= Prompt . new ( llm_prompt_name , llm_provider )
155+ @prompt ||= Prompt . new ( llm_prompt_name )
142156 end
143157
144158 def guardrail_numbers
0 commit comments