21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/sentiment_insights/clients/sentiment/claude_client.rb', line 21
def analyze_entries(entries, question: nil, prompt: nil, batch_size: 50)
all_sentiments = []
entries.each_slice(batch_size) do |batch|
prompt_content = build_prompt_content(batch, question: question, prompt: prompt)
request_body = {
model: @model,
max_tokens: 1000,
messages: [
{ role: "user", content: prompt_content }
]
}
uri = URI("https://api.anthropic.com/v1/messages")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response_content = nil
attempt = 0
while attempt < @max_retries
attempt += 1
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["x-api-key"] = @api_key
request["anthropic-version"] = "2023-06-01"
request.body = JSON.generate(request_body)
begin
response = http.request(request)
rescue StandardError => e
@logger.error "Claude API request error: #{e.class} - #{e.message}"
raise
end
status = response.code.to_i
if status == 429
@logger.warn "Rate limit (HTTP 429) on attempt #{attempt}. Retrying..."
sleep(2 ** (attempt - 1))
next
elsif status != 200
@logger.error "Request failed (#{status}): #{response.body}"
raise "Claude API Error: #{status}"
else
data = JSON.parse(response.body)
response_content = data.dig("content", 0, "text")
break
end
end
sentiments = parse_sentiments(response_content, batch.size)
all_sentiments.concat(sentiments)
end
all_sentiments
end
|