# `LangChain.ChatModels.ChatGoogleAI`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L1)

Parses and validates inputs for making a request for the Google AI  Chat API.

Converts response into more specialized `LangChain` data structures.

**NOTE:** The GoogleAI service is unique in how it reports TokenUsage
information. So far, it's the only API that returns TokenUsage for each
returned delta, where the generated token count is incremented with one. Other
services return the total TokenUsage data at the end. This Chat model fires
the callback each time it is received.

**Google Search Integration**

Starting with Gemini 2.0, this module supports Google Search as a native tool,
allowing the model to automatically search the web for recent information to ground
its responses and improve factuality. Check out the [Google AI Documentation](https://ai.google.dev/gemini-api/docs/grounding?lang=rest)
for more information.

Example Usage:

```elixir
alias LangChain.Chains.LLMChain
alias LangChain.Message
alias LangChain.NativeTool

model = ChatGoogleAI.new!(%{temperature: 0, stream: false, model: "gemini-2.0-flash"})

{:ok, updated_chain} =
   %{llm: model, verbose: false, stream: false}
   |> LLMChain.new!()
   |> LLMChain.add_message(
     Message.new_user!("What is the current Google stock price?")
   )
   |> LLMChain.add_tools(NativeTool.new!(%{name: "google_search", configuration: %{}}))
   |> LLMChain.run()
```

The above call will return the current Google stock price.

When `google_search` is used, the model will also return grounding information in the metadata attribute of the assistant message.

**Tool Schemas**

Google's function declarations accept a
[select subset](https://ai.google.dev/api/caching#Schema) of an OpenAPI 3.0
schema object rather than full JSON Schema. Keywords outside that subset are
rejected by the API with `Unknown name "<keyword>" ... Cannot find field`,
which fails the entire request rather than the single tool. Tool parameters
and the JSON response schema are therefore passed through
`LangChain.Utils.GoogleSchema.sanitize/1` before being sent.

One removal changes what the API enforces: `additionalProperties` is not
supported, so an object schema that sets `additionalProperties: false` is
still sent, but without it. Gemini does not reject unexpected properties, and
a tool call's arguments may contain fields the schema did not declare. Where
that matters, validate the arguments inside the tool's own function. See
`LangChain.Utils.GoogleSchema` for the full list of removed keywords.

**Structured Output**

Google's Gemini models can return
[structured JSON output](https://ai.google.dev/gemini-api/docs/structured-output)
that conforms to a schema you supply. Set `json_response: true` to request a
JSON response, and optionally provide a `json_schema` describing the shape you
want. These map to the API's `generationConfig.response_mime_type` and
`generationConfig.response_schema`.

```elixir
alias LangChain.Chains.LLMChain
alias LangChain.Message
alias LangChain.Message.ContentPart
alias LangChain.ChatModels.ChatGoogleAI

# A response_schema in the Google/OpenAPI schema format.
json_schema = %{
  "type" => "array",
  "items" => %{
    "type" => "object",
    "properties" => %{
      "recipe_name" => %{"type" => "string"}
    }
  }
}

model =
  ChatGoogleAI.new!(%{
    model: "gemini-2.5-flash",
    json_response: true,
    json_schema: json_schema
  })

{:ok, updated_chain} =
  %{llm: model, verbose: false, stream: false}
  |> LLMChain.new!()
  |> LLMChain.add_message(Message.new_user!("List 5 popular cookie recipes"))
  |> LLMChain.run()

{:ok, recipes} =
  updated_chain.last_message.content
  |> ContentPart.content_to_string()
  |> Jason.decode()
```

The assistant message's content is a list of `LangChain.Message.ContentPart`
structs rather than a string, so flatten it with
`LangChain.Message.ContentPart.content_to_string/1` before decoding the JSON.

`json_response: true` may be used on its own (without a `json_schema`) to ask
for a JSON response without constraining its shape.

A `json_schema` is sanitized before it is sent, in the same way tool
parameters are, so keywords Google's `Schema` type has no field for are
dropped rather than rejected. Schemas generated by tooling commonly use
`$defs` and `$ref`; inline them first. See **Tool Schemas** above and
`LangChain.Utils.GoogleSchema` for the full list.

# `t`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L214)

```elixir
@type t() :: %LangChain.ChatModels.ChatGoogleAI{
  api_key: term(),
  api_version: term(),
  callbacks: term(),
  endpoint: term(),
  json_response: term(),
  json_schema: term(),
  model: term(),
  receive_timeout: term(),
  req_config: term(),
  safety_settings: term(),
  stream: term(),
  temperature: term(),
  thinking_config: term(),
  top_k: term(),
  top_p: term(),
  verbose_api: term()
}
```

# `call`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L584)

Calls the Google AI API passing the ChatGoogleAI struct with configuration, plus
either a simple message or the list of messages to act as the prompt.

Optionally pass in a list of tools available to the LLM for requesting
execution in response.

Optionally pass in a callback function that can be executed as data is
received from the API.

**NOTE:** This function *can* be used directly, but the primary interface
should be through `LangChain.Chains.LLMChain`. The `ChatGoogleAI` module is more focused on
translating the `LangChain` data structures to and from the Google AI API.

Another benefit of using `LangChain.Chains.LLMChain` is that it combines the
storage of messages, adding tools, adding custom context that should be
passed to tools, and automatically applying `LangChain.MessageDelta`
structs as they are are received, then converting those to the full
`LangChain.Message` once fully complete.

# `do_process_response`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L853)

# `for_api`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L275)

# `get_message_contents`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L1046)

```elixir
@spec get_message_contents(LangChain.MessageDelta.t() | LangChain.Message.t()) ::
  [%{required(String.t()) =&gt; any()}] | nil
```

Return the content parts for the message.

# `new`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L249)

```elixir
@spec new(attrs :: map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
```

Setup a ChatGoogleAI client configuration.

# `new!`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L260)

```elixir
@spec new!(attrs :: map()) :: t() | no_return()
```

Setup a ChatGoogleAI client configuration and return it or raise an error if invalid.

# `restore_from_map`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L1117)

Restores the model from the config.

# `retry_on_fallback?`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L1081)

```elixir
@spec retry_on_fallback?(LangChain.LangChainError.t()) :: boolean()
```

Determine if an error should be retried. If `true`, a fallback LLM may be
used. If `false`, the error is understood to be more fundamental with the
request rather than a service issue and it should not be retried or fallback
to another service.

# `serialize_config`
[🔗](https://github.com/brainlid/langchain/blob/v0.15.3/lib/chat_models/chat_google_ai.ex#L1092)

```elixir
@spec serialize_config(t()) :: %{required(String.t()) =&gt; any()}
```

Generate a config map that can later restore the model's configuration.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
