langchain-xai
¶
LangChain integration with xAI.
Classes¶
ChatXAI ¶
Bases: BaseChatOpenAI
ChatXAI chat model.
Refer to xAI's documentation for more nuanced details on the API's behavior and supported parameters.
Setup
Install langchain-xai
and set environment variable XAI_API_KEY
.
Key init args — completion params: model: str Name of model to use. temperature: float Sampling temperature between 0
and 2
. Higher values mean more random completions, while lower values (like 0.2
) mean more focused and deterministic completions. (Default: 1
.) max_tokens: int | None Max number of tokens to generate. Refer to your model's documentation for the maximum number of tokens it can generate. logprobs: bool | None Whether to return logprobs.
Key init args — client params: timeout: Union[float, Tuple[float, float], Any, None] Timeout for requests. max_retries: int Max number of retries. api_key: str | None xAI API key. If not passed in will be read from env var XAI_API_KEY
.
Instantiate
Invoke
messages = [ ( "system", "You are a helpful translator. Translate the user sentence to French.", ), ("human", "I love programming."), ] model.invoke(messages)
AIMessage( content="J'adore la programmation.", response_metadata={ "token_usage": { "completion_tokens": 9, "prompt_tokens": 32, "total_tokens": 41, }, "model_name": "grok-4", "system_fingerprint": None, "finish_reason": "stop", "logprobs": None, }, id="run-168dceca-3b8b-4283-94e3-4c739dbc1525-0", usage_metadata={ "input_tokens": 32, "output_tokens": 9, "total_tokens": 41, }, )
Stream
content='J' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content="'" id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content='ad' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content='ore' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content=' la' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content=' programm' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content='ation' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content='.' id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9' content='' response_metadata={'finish_reason': 'stop', 'model_name': 'grok-4'} id='run-1bc996b5-293f-4114-96a1-e0f755c05eb9'
Async
await model.ainvoke(messages) # stream: # async for chunk in (await model.astream(messages)) # batch: # await model.abatch([messages])
AIMessage( content="J'adore la programmation.", response_metadata={ "token_usage": { "completion_tokens": 9, "prompt_tokens": 32, "total_tokens": 41, }, "model_name": "grok-4", "system_fingerprint": None, "finish_reason": "stop", "logprobs": None, }, id="run-09371a11-7f72-4c53-8e7c-9de5c238b34c-0", usage_metadata={ "input_tokens": 32, "output_tokens": 9, "total_tokens": 41, }, )
Reasoning
Certain xAI models support reasoning, which allows the model to provide reasoning content along with the response.
If provided, reasoning content is returned under the additional_kwargs
field of the AIMessage or AIMessageChunk.
If supported, reasoning effort can be specified in the model constructor's extra_body
argument, which will control the amount of reasoning the model does. The value can be one of 'low'
or 'high'
.
Note
As of 2025-07-10, reasoning_content
is only returned in Grok 3 models, such as Grok 3 Mini.
Note
Note that in Grok 4, as of 2025-07-10, reasoning is not exposed in reasoning_content
(other than initial 'Thinking...'
text), reasoning cannot be disabled, and the reasoning_effort
cannot be specified.
Tool calling / function calling:
from pydantic import BaseModel, Field model = ChatXAI(model="grok-4") 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") model_with_tools = model.bind_tools([GetWeather, GetPopulation]) ai_msg = model_with_tools.invoke("Which city is bigger: LA or NY?") ai_msg.tool_calls
```python [ { "name": "GetPopulation", "args": {"location": "NY"}, "id": "call_m5tstyn2004pre9bfuxvom8x", "type": "tool_call", }, { "name": "GetPopulation", "args": {"location": "LA"}, "id": "call_0vjgq455gq1av5sp9eb1pw6a", "type": "tool_call", }, ] ``` !!! note With stream response, the tool / function call will be returned in whole in a single chunk, instead of being streamed across chunks. Tool choice can be controlled by setting the `tool_choice` parameter in the model constructor's `extra_body` argument. For example, to disable tool / function calling: ```python model = ChatXAI(model="grok-4", extra_body={"tool_choice": "none"}) ``` To require that the model always calls a tool / function, set `tool_choice` to `'required'`: ```python model = ChatXAI(model="grok-4", extra_body={"tool_choice": "required"}) ``` To specify a tool / function to call, set `tool_choice` to the name of the tool / function: ```python from pydantic import BaseModel, Field model = ChatXAI( model="grok-4", extra_body={ "tool_choice": {"type": "function", "function": {"name": "GetWeather"}} }, ) 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') model_with_tools = model.bind_tools([GetWeather, GetPopulation]) ai_msg = model_with_tools.invoke( "Which city is bigger: LA or NY?", ) ai_msg.tool_calls ``` The resulting tool call would be: ```python [ { "name": "GetWeather", "args": {"location": "Los Angeles, CA"}, "id": "call_81668711", "type": "tool_call", } ] ```
Parallel tool calling / parallel function calling: By default, parallel tool / function calling is enabled, so you can process multiple function calls in one request/response cycle. When two or more tool calls are required, all of the tool call requests will be included in the response body.
Structured output
from typing import Optional from pydantic 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: int | None = Field(description="How funny the joke is, from 1 to 10") structured_model = model.with_structured_output(Joke) structured_model.invoke("Tell me a joke about cats")
Live Search
xAI supports a Live Search feature that enables Grok to ground its answers using results from web searches.
Token usage
Logprobs
Response metadata
```python { "token_usage": { "completion_tokens": 4, "prompt_tokens": 19, "total_tokens": 23, }, "model_name": "grok-4", "system_fingerprint": None, "finish_reason": "stop", "logprobs": None, } ```
METHOD | DESCRIPTION |
---|---|
get_lc_namespace | Get the namespace of the langchain object. |
is_lc_serializable | Return whether this model can be serialized by LangChain. |
validate_environment | Validate that api key and python package exists in environment. |
with_structured_output | Model wrapper that returns outputs formatted to match the given schema. |
Attributes¶
model_name class-attribute
instance-attribute
¶
model_name: str = Field(default='grok-4', alias='model')
Model name to use.
xai_api_key class-attribute
instance-attribute
¶
xai_api_key: SecretStr | None = Field( alias="api_key", default_factory=secret_from_env( "XAI_API_KEY", default=None ), )
xAI API key.
Automatically read from env variable XAI_API_KEY
if not provided.
xai_api_base class-attribute
instance-attribute
¶
xai_api_base: str = Field(default='https://api.x.ai/v1/')
Base URL path for API requests.
search_parameters class-attribute
instance-attribute
¶
Parameters for search requests. Example: {"mode": "auto"}
.
lc_secrets property
¶
A map of constructor argument names to secret ids.
For example, {"xai_api_key": "XAI_API_KEY"}
lc_attributes property
¶
List of attribute names that should be included in the serialized kwargs.
These attributes must be accepted by the constructor.
Functions¶
get_lc_namespace classmethod
¶
validate_environment ¶
Validate that api key and python package exists in environment.
Source code in .venv/lib/python3.13/site-packages/langchain_xai/chat_models.py
with_structured_output ¶
with_structured_output( schema: _DictOrPydanticClass | None = None, *, method: Literal[ "function_calling", "json_mode", "json_schema" ] = "function_calling", include_raw: bool = False, strict: bool | None = None, **kwargs: Any ) -> Runnable[LanguageModelInput, _DictOrPydantic]
Model wrapper that returns outputs formatted to match the given schema.
PARAMETER | DESCRIPTION |
---|---|
| The output schema. Can be passed in as:
If TYPE: |
| The method for steering model generation, one of:
TYPE: |
| If TYPE: |
|
TYPE: |
| Additional keyword args aren't supported. TYPE: |
RETURNS | DESCRIPTION |
---|---|
Runnable[LanguageModelInput, _DictOrPydantic] | A Runnable that takes same inputs as a |
Runnable[LanguageModelInput, _DictOrPydantic] | If |
Runnable[LanguageModelInput, _DictOrPydantic] | If |
Runnable[LanguageModelInput, _DictOrPydantic] |
|
Runnable[LanguageModelInput, _DictOrPydantic] |
|
Runnable[LanguageModelInput, _DictOrPydantic] |
|
Source code in .venv/lib/python3.13/site-packages/langchain_xai/chat_models.py
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
|