"""Wrapper around Cerebras' Chat Completions API."""fromtypingimportAny,Dict,List,Optionalimportopenaifromlangchain_core.language_models.chat_modelsimportLangSmithParamsfromlangchain_core.utilsimport(from_env,secret_from_env,)# We ignore the "unused imports" here since we want to reexport these from this package.fromlangchain_openai.chat_models.baseimport(BaseChatOpenAI,)frompydanticimportField,SecretStr,model_validatorfromtyping_extensionsimportSelfCEREBRAS_BASE_URL="https://api.cerebras.ai/v1/"
[docs]classChatCerebras(BaseChatOpenAI):r"""ChatCerebras chat model. Setup: Install ``langchain-cerebras`` and set environment variable ``CEREBRAS_API_KEY``. .. code-block:: bash pip install -U langchain-cerebras export CEREBRAS_API_KEY="your-api-key" Key init args — completion params: model: str Name of model to use. temperature: Optional[float] Sampling temperature. max_tokens: Optional[int] Max number of tokens to generate. Key init args — client params: timeout: Union[float, Tuple[float, float], Any, None] Timeout for requests. max_retries: Optional[int] Max number of retries. api_key: Optional[str] Cerebras API key. If not passed in will be read from env var CEREBRAS_API_KEY. Instantiate: .. code-block:: python from langchain_cerebras import ChatCerebras llm = ChatCerebras( model="llama-3.3-70b", temperature=0, max_tokens=None, timeout=None, max_retries=2, # api_key="...", # other params... ) Invoke: .. code-block:: python messages = [ ( "system", "You are a helpful translator. Translate the user sentence to French.", ), ("human", "I love programming."), ] llm.invoke(messages) .. code-block:: python AIMessage( content='The translation of "I love programming" to French is:\n\n"J\'adore programmer."', response_metadata={ 'token_usage': {'completion_tokens': 20, 'prompt_tokens': 32, 'total_tokens': 52}, 'model_name': 'llama-3.3-70b', 'system_fingerprint': 'fp_679dff74c0', 'finish_reason': 'stop', }, id='run-377c2887-30ef-417e-b0f5-83efc8844f12-0', usage_metadata={'input_tokens': 32, 'output_tokens': 20, 'total_tokens': 52}) Stream: .. code-block:: python for chunk in llm.stream(messages): print(chunk) .. code-block:: python content='' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='The' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' translation' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' of' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' "' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='I' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' love' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' programming' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='"' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' to' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' French' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' is' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=':\n\n' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='"' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='J' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content="'" id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='ad' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='ore' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content=' programmer' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='."' id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' content='' response_metadata={'finish_reason': 'stop', 'model_name': 'llama-3.3-70b', 'system_fingerprint': 'fp_679dff74c0'} id='run-3f9dc84e-208f-48da-b15d-e552b6759c24' Async: .. code-block:: python await llm.ainvoke(messages) # stream: # async for chunk in (await llm.astream(messages)) # batch: # await llm.abatch([messages]) .. code-block:: python AIMessage( content='The translation of "I love programming" to French is:\n\n"J\'adore programmer."', response_metadata={ 'token_usage': {'completion_tokens': 20, 'prompt_tokens': 32, 'total_tokens': 52}, 'model_name': 'llama-3.3-70b', 'system_fingerprint': 'fp_679dff74c0', 'finish_reason': 'stop', }, id='run-377c2887-30ef-417e-b0f5-83efc8844f12-0', usage_metadata={'input_tokens': 32, 'output_tokens': 20, 'total_tokens': 52}) Tool calling: .. code-block:: python from langchain_core.pydantic_v1 import BaseModel, Field llm = ChatCerebras(model="llama-3.3-70b") class GetWeather(BaseModel): '''Get the current weather in a given location''' location: str = Field( ..., description="The city and state, e.g. San Francisco, CA" ) class GetPopulation(BaseModel): '''Get the current population in a given location''' location: str = Field( ..., description="The city and state, e.g. San Francisco, CA" ) llm_with_tools = llm.bind_tools([GetWeather, GetPopulation]) ai_msg = llm_with_tools.invoke( "Which city is bigger: LA or NY?" ) ai_msg.tool_calls .. code-block:: python [ { 'name': 'GetPopulation', 'args': {'location': 'NY'}, 'id': 'call_m5tstyn2004pre9bfuxvom8x', 'type': 'tool_call' }, { 'name': 'GetPopulation', 'args': {'location': 'LA'}, 'id': 'call_0vjgq455gq1av5sp9eb1pw6a', 'type': 'tool_call' } ] Structured output: .. code-block:: python from typing import Optional from langchain_core.pydantic_v1 import BaseModel, Field class Joke(BaseModel): '''Joke to tell user.''' setup: str = Field(description="The setup of the joke") punchline: str = Field(description="The punchline to the joke") rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10") structured_llm = llm.with_structured_output(Joke) structured_llm.invoke("Tell me a joke about cats") .. code-block:: python Joke( setup='Why was the cat sitting on the computer?', punchline='To keep an eye on the mouse!', rating=7 ) JSON mode: .. code-block:: python json_llm = llm.bind(response_format={"type": "json_object"}) ai_msg = json_llm.invoke( "Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]" ) ai_msg.content .. code-block:: python ' {\\n"random_ints": [\\n13,\\n54,\\n78,\\n45,\\n67,\\n90,\\n11,\\n29,\\n84,\\n33\\n]\\n}' Token usage: .. code-block:: python ai_msg = llm.invoke(messages) ai_msg.usage_metadata .. code-block:: python {'input_tokens': 37, 'output_tokens': 6, 'total_tokens': 43} Response metadata .. code-block:: python ai_msg = llm.invoke(messages) ai_msg.response_metadata .. code-block:: python { 'token_usage': { 'completion_tokens': 4, 'prompt_tokens': 19, 'total_tokens': 23 }, 'model_name': 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'system_fingerprint': None, 'finish_reason': 'eos', 'logprobs': None } """# noqa: E501@propertydeflc_secrets(self)->Dict[str,str]:"""A map of constructor argument names to secret ids. For example, {"cerebras_api_key": "CEREBRAS_API_KEY"} """return{"cerebras_api_key":"CEREBRAS_API_KEY"}@classmethoddefget_lc_namespace(cls)->List[str]:"""Get the namespace of the langchain object."""return["langchain","chat_models","cerebras"]@propertydeflc_attributes(self)->Dict[str,Any]:"""List of attribute names that should be included in the serialized kwargs. These attributes must be accepted by the constructor. """attributes:Dict[str,Any]={}ifself.cerebras_api_base:attributes["cerebras_api_base"]=self.cerebras_api_baseifself.cerebras_proxy:attributes["cerebras_proxy"]=self.cerebras_proxyreturnattributes@propertydef_llm_type(self)->str:"""Return type of chat model."""return"cerebras-chat"def_get_ls_params(self,stop:Optional[List[str]]=None,**kwargs:Any)->LangSmithParams:"""Get the parameters used to invoke the model."""params=super()._get_ls_params(stop=stop,**kwargs)params["ls_provider"]="cerebras"returnparamsmodel_name:str=Field(alias="model")"""Model name to use."""cerebras_api_key:Optional[SecretStr]=Field(alias="api_key",default_factory=secret_from_env("CEREBRAS_API_KEY",default=None),)"""Automatically inferred from env are `CEREBRAS_API_KEY` if not provided."""cerebras_api_base:str=Field(default_factory=from_env("CEREBRAS_API_BASE",default=CEREBRAS_BASE_URL),alias="base_url",)cerebras_proxy:str=Field(default_factory=from_env("CEREBRAS_PROXY",default=""))@model_validator(mode="after")defvalidate_environment(self)->Self:"""Validate that api key and python package exists in environment."""ifself.nisnotNoneandself.n<1:raiseValueError("n must be at least 1.")ifself.nisnotNoneandself.n>1andself.streaming:raiseValueError("n must be 1 when streaming.")client_params={"api_key":(self.cerebras_api_key.get_secret_value()ifself.cerebras_api_keyelseNone),# Ensure we always fallback to the Cerebras API url."base_url":self.cerebras_api_base,"timeout":self.request_timeout,"default_headers":self.default_headers,"default_query":self.default_query,}ifself.max_retriesisnotNone:client_params["max_retries"]=self.max_retriesifself.cerebras_proxyand(self.http_clientorself.http_async_client):raiseValueError("Cannot specify 'cerebras_proxy' if one of ""'http_client'/'http_async_client' is already specified. Received:\n"f"{self.cerebras_proxy=}\n{self.http_client=}\n{self.http_async_client=}")ifnotself.client:ifself.cerebras_proxyandnotself.http_client:try:importhttpxexceptImportErrorase:raiseImportError("Could not import httpx python package. ""Please install it with `pip install httpx`.")fromeself.http_client=httpx.Client(proxy=self.cerebras_proxy)sync_specific={"http_client":self.http_client}self.root_client=openai.OpenAI(**client_params,**sync_specific)# type: ignoreself.client=self.root_client.chat.completionsifnotself.async_client:ifself.cerebras_proxyandnotself.http_async_client:try:importhttpxexceptImportErrorase:raiseImportError("Could not import httpx python package. ""Please install it with `pip install httpx`.")fromeself.http_async_client=httpx.AsyncClient(proxy=self.cerebras_proxy)async_specific={"http_client":self.http_async_client}self.root_async_client=openai.AsyncOpenAI(**client_params,# type: ignore**async_specific,# type: ignore)self.async_client=self.root_async_client.chat.completionsreturnself