sampler/claude_sampler.py (68 lines of code) (raw):

import time import anthropic from ..types import MessageList, SamplerBase CLAUDE_SYSTEM_MESSAGE_LMSYS = ( "The assistant is Claude, created by Anthropic. The current date is " "{currentDateTime}. Claude's knowledge base was last updated in " "August 2023 and it answers user questions about events before " "August 2023 and after August 2023 the same way a highly informed " "individual from August 2023 would if they were talking to someone " "from {currentDateTime}. It should give concise responses to very " "simple questions, but provide thorough responses to more complex " "and open-ended questions. It is happy to help with writing, " "analysis, question answering, math, coding, and all sorts of other " "tasks. It uses markdown for coding. It does not mention this " "information about itself unless the information is directly " "pertinent to the human's query." ).format(currentDateTime="2024-04-01") # reference: https://github.com/lm-sys/FastChat/blob/7899355ebe32117fdae83985cf8ee476d2f4243f/fastchat/conversation.py#L894 class ClaudeCompletionSampler(SamplerBase): """ Sample from Claude API """ def __init__( self, model: str = "claude-3-opus-20240229", system_message: str | None = None, temperature: float = 0.0, # default in Anthropic example max_tokens: int = 1024, ): self.api_key_name = "ANTHROPIC_API_KEY" self.client = anthropic.Anthropic() # using api_key=os.environ.get("ANTHROPIC_API_KEY") # please set your API_KEY self.model = model self.system_message = system_message self.temperature = temperature self.max_tokens = max_tokens self.image_format = "base64" def _handle_image( self, image: str, encoding: str = "base64", format: str = "png", fovea: int = 768 ): new_image = { "type": "image", "source": { "type": encoding, "media_type": f"image/{format}", "data": image, }, } return new_image def _handle_text(self, text): return {"type": "text", "text": text} def _pack_message(self, role, content): return {"role": str(role), "content": content} def __call__(self, message_list: MessageList) -> str: trial = 0 while True: try: message = self.client.messages.create( model=self.model, system=self.system_message, max_tokens=self.max_tokens, temperature=self.temperature, messages=message_list, ) return message.content[0].text except anthropic.RateLimitError as e: exception_backoff = 2**trial # expontial back off print( f"Rate limit exception so wait and retry {trial} after {exception_backoff} sec", e, ) time.sleep(exception_backoff) trial += 1 # unknown error shall throw exception