Skip to content

Commit 682935a

Browse files
committed
spike always sending question to rephraser
1 parent 5410b49 commit 682935a

5 files changed

Lines changed: 83 additions & 98 deletions

File tree

lib/answer_composition/pipeline/question_rephraser.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ def initialize(context)
1818
end
1919

2020
def call
21-
return if message_records.blank?
22-
2321
start_time = Clock.monotonic_time
2422
response = anthropic_bedrock_client.messages.create(
2523
system: [{ type: "text", text: config[:system_prompt] }],

spec/lib/answer_composition/pipeline/question_rephraser_spec.rb

Lines changed: 62 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -30,95 +30,82 @@
3030
end
3131
end
3232

33-
context "when the question is the beginning of the conversation" do
34-
let(:context) { build(:answer_pipeline_context) }
35-
36-
it "returns nil" do
37-
expect(described_class.call(context)).to be_nil
38-
end
33+
it "includes the current question in the user prompt" do
34+
described_class.call(context)
35+
expect(stub).to have_been_requested
3936
end
4037

41-
context "when all other recent answers have statuses in Answer::STATUSES_EXCLUDED_FROM_REPHRASING" do
42-
it "returns nil" do
43-
conversation = create(:conversation)
44-
create(:question, conversation:)
45-
Answer::STATUSES_EXCLUDED_FROM_REPHRASING.sample(4) do |status|
46-
question = create(:question, conversation:)
47-
create(:answer, question:, status:)
48-
end
49-
latest_question = create(:question, conversation:)
50-
context = build(:answer_pipeline_context, question: latest_question)
38+
it "includes the message_history in the user prompt" do
39+
message_history = <<~HISTORY.strip
40+
user:
41+
"""
42+
How do I pay my tax
43+
"""
44+
assistant:
45+
"""
46+
What type of tax
47+
"""
48+
user:
49+
"""
50+
What types are there
51+
"""
52+
assistant:
53+
"""
54+
Self-assessment, PAYE, Corporation tax
55+
"""
56+
HISTORY
57+
58+
anthropic_request = stub_claude_question_rephrasing(
59+
Regexp.new(message_history),
60+
rephrased,
61+
)
62+
63+
described_class.call(context)
64+
65+
expect(anthropic_request).to have_been_made
66+
end
5167

52-
expect(described_class.call(context)).to be_nil
53-
end
68+
it "updates the context's question_message with the rephrased question" do
69+
described_class.call(context)
70+
expect(context.question_message).to eq(rephrased)
5471
end
5572

56-
context "when the question is part of an ongoing chat" do
57-
it "includes the current question in the user prompt" do
58-
described_class.call(context)
59-
expect(stub).to have_been_requested
60-
end
73+
it "assigns metrics to the answer" do
74+
allow(Clock).to receive(:monotonic_time).and_return(100.0, 101.5)
6175

62-
it "includes the message_history in the user prompt" do
63-
message_history = <<~HISTORY.strip
64-
user:
65-
"""
66-
How do I pay my tax
67-
"""
68-
assistant:
69-
"""
70-
What type of tax
71-
"""
72-
user:
73-
"""
74-
What types are there
75-
"""
76-
assistant:
77-
"""
78-
Self-assessment, PAYE, Corporation tax
79-
"""
80-
HISTORY
81-
82-
anthropic_request = stub_claude_question_rephrasing(
83-
Regexp.new(message_history),
84-
rephrased,
85-
)
76+
described_class.call(context)
8677

87-
described_class.call(context)
78+
expect(context.answer.metrics["question_rephrasing"])
79+
.to eq({
80+
duration: 1.5,
81+
llm_prompt_tokens: 10,
82+
llm_completion_tokens: 20,
83+
llm_cached_tokens: nil,
84+
model: BedrockModels.model_id(:claude_sonnet_4_0),
85+
})
86+
end
8887

89-
expect(anthropic_request).to have_been_made
90-
end
88+
it "assigns the llm response to the answer" do
89+
described_class.call(context)
9190

92-
it "updates the context's question_message with the rephrased question" do
93-
described_class.call(context)
94-
expect(context.question_message).to eq(rephrased)
95-
end
91+
expected_llm_response = claude_messages_response(
92+
content: [claude_messages_text_block(rephrased)],
93+
usage: claude_messages_usage_block(input_tokens: 10, output_tokens: 20),
94+
).to_h
9695

97-
it "assigns metrics to the answer" do
98-
allow(Clock).to receive(:monotonic_time).and_return(100.0, 101.5)
96+
expect(context.answer.llm_responses["question_rephrasing"])
97+
.to eq(expected_llm_response)
98+
end
9999

100-
described_class.call(context)
100+
context "when the question is the first in the conversation" do
101+
let(:question) { create(:question) }
102+
let(:context) { build(:answer_pipeline_context, question:) }
103+
let!(:stub) { stub_claude_question_rephrasing(question.message, rephrased) }
101104

102-
expect(context.answer.metrics["question_rephrasing"])
103-
.to eq({
104-
duration: 1.5,
105-
llm_prompt_tokens: 10,
106-
llm_completion_tokens: 20,
107-
llm_cached_tokens: nil,
108-
model: BedrockModels.model_id(:claude_sonnet_4_0),
109-
})
110-
end
111105

112-
it "assigns the llm response to the answer" do
106+
it "calls the llm and rephrases the question" do
113107
described_class.call(context)
114-
115-
expected_llm_response = claude_messages_response(
116-
content: [claude_messages_text_block(rephrased)],
117-
usage: claude_messages_usage_block(input_tokens: 10, output_tokens: 20),
118-
).to_h
119-
120-
expect(context.answer.llm_responses["question_rephrasing"])
121-
.to eq(expected_llm_response)
108+
expect(stub).to have_been_requested
122109
end
123110
end
124111

spec/system/conversation_js_features_spec.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ def when_the_second_answer_is_generated
182182

183183
stubs_for_mock_answer(@second_question,
184184
@second_answer,
185-
rephrase_question: true,
186185
sources_used: %w[link_1],
187186
create_content_chunk: false)
188187

@@ -236,18 +235,15 @@ def then_i_see_a_character_count_error
236235

237236
def stubs_for_mock_answer(question,
238237
answer,
239-
rephrase_question: false,
240238
sources_used: [],
241239
create_content_chunk: true)
242240
stub_claude_jailbreak_guardrails(question)
243241

244-
if rephrase_question
245-
rephrased_question = "Rephrased #{question}"
242+
rephrased_question = "Rephrased #{question}"
246243

247-
stub_claude_question_rephrasing(question, rephrased_question)
244+
stub_claude_question_rephrasing(question, rephrased_question)
248245

249-
question = rephrased_question
250-
end
246+
question = rephrased_question
251247

252248
stub_bedrock_titan_embedding(question)
253249

spec/system/conversation_with_claude_structured_answer_spec.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ def then_i_see_the_answer_is_pending
3535
end
3636

3737
def when_the_first_answer_is_generated
38-
titan_embedding = mock_titan_embedding(@first_question)
38+
rephrased_question = "Rephrased #{@first_question}"
39+
titan_embedding = mock_titan_embedding(rephrased_question)
3940
allow(Search::TextToEmbedding)
4041
.to receive(:call)
4142
.and_return(titan_embedding)
@@ -47,24 +48,25 @@ def when_the_first_answer_is_generated
4748
@first_answer = "Lots of tax."
4849

4950
stub_claude_jailbreak_guardrails(@first_question)
50-
stub_claude_question_routing(@first_question)
51-
stub_claude_structured_answer(@first_question, @first_answer)
51+
stub_claude_question_rephrasing(@first_question, rephrased_question)
52+
stub_claude_question_routing(rephrased_question)
53+
stub_claude_structured_answer(rephrased_question, @first_answer)
5254
stub_claude_output_guardrails(@first_answer)
53-
stub_bedrock_invoke_model_openai_oss_topic_tagger(@first_question)
55+
stub_bedrock_invoke_model_openai_oss_topic_tagger(rephrased_question)
5456
stub_bedrock_invoke_model_openai_oss_answer_relevancy(
55-
question_message: @first_question,
57+
question_message: rephrased_question,
5658
answer_message: @first_answer,
5759
)
5860
stub_bedrock_invoke_model_openai_oss_faithfulness(
5961
retrieval_context: "Some content",
6062
answer_message: @first_answer,
6163
)
6264
stub_bedrock_invoke_model_openai_oss_coherence(
63-
question_message: @first_question,
65+
question_message: rephrased_question,
6466
answer_message: @first_answer,
6567
)
6668
stub_bedrock_invoke_model_openai_oss_context_relevancy(
67-
question_message: @first_question,
69+
question_message: rephrased_question,
6870
)
6971

7072
execute_queued_sidekiq_jobs

spec/system/user_conversation_activity_is_shown_in_admin_spec.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def and_i_enter_a_question
3434
end
3535

3636
def and_the_answer_is_generated
37-
titan_embedding = mock_titan_embedding(@question)
37+
rephrased_question = "Rephrased #{@question}"
38+
titan_embedding = mock_titan_embedding(rephrased_question)
3839
allow(Search::TextToEmbedding)
3940
.to receive(:call)
4041
.and_return(titan_embedding)
@@ -46,24 +47,25 @@ def and_the_answer_is_generated
4647
@answer = "Maybe. You could get some benefits."
4748

4849
stub_claude_jailbreak_guardrails(@question)
49-
stub_claude_question_routing(@question)
50-
stub_claude_structured_answer(@question, @answer)
50+
stub_claude_question_rephrasing(@question, rephrased_question)
51+
stub_claude_question_routing(rephrased_question)
52+
stub_claude_structured_answer(rephrased_question, @answer)
5153
stub_claude_output_guardrails(@answer)
52-
stub_bedrock_invoke_model_openai_oss_topic_tagger(@question)
54+
stub_bedrock_invoke_model_openai_oss_topic_tagger(rephrased_question)
5355
stub_bedrock_invoke_model_openai_oss_answer_relevancy(
54-
question_message: @question,
56+
question_message: rephrased_question,
5557
answer_message: @answer,
5658
)
5759
stub_bedrock_invoke_model_openai_oss_faithfulness(
5860
retrieval_context: "Some content",
5961
answer_message: @answer,
6062
)
6163
stub_bedrock_invoke_model_openai_oss_coherence(
62-
question_message: @question,
64+
question_message: rephrased_question,
6365
answer_message: @answer,
6466
)
6567
stub_bedrock_invoke_model_openai_oss_context_relevancy(
66-
question_message: @question,
68+
question_message: rephrased_question,
6769
)
6870

6971
execute_queued_sidekiq_jobs

0 commit comments

Comments
 (0)