Skip to content

Google Gemini: request fails with more than one tool call #993

@guilhermeteodoro

Description

@guilhermeteodoro

Hello guys,

I'm creating a BooksRecommendation assistant for a project that is based on Google Gemini's LLM (model gemini-1.5-pro) along with a tool that searches the Google Books API. The assistant receives an user input, categorize it and make tool calls to recommend books (there's an iteration happening).

I noticed that whenever the assistant decides to make more than one tool call to reply one request, it produces an invalid payload request to Gemini, throwing an API error:

app/agents/guidance/books_recommender_agent.rb:6:in 'Guidance::BooksRecommenderAgent#recommend': {"error" => {"code" => 400, "message" => "Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.", "status" => "INVALID_ARGUMENT"}} (StandardError)

Here's an payload example the assistant is currently producing:

{
  "tools": {
    "function_declarations": [
      {
        "name": "google_books__search",
        "description": "GoogleBooks Search:\n\nUtilize esta ferramenta para encontrar livros no Google Livros.\nA sua pesquisa deve ser clara e específica para que os resultados sejam relevantes e detalhados.\n",
        "parameters": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Termo/termos usados para a busca"
            }
          },
          "required": [
            "query"
          ]
        }
      }
    ]
  },
  "model": "gemini-1.5-pro",
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Tema ou temas informados pelo usuário: 'gostaria de aprender mais sobre casamento, férias e cozinhar'"
        }
      ]
    },
    {
      "role": "model",
      "parts": [
        {
          "functionCall": {
            "name": "google_books__search",
            "args": {
              "query": "casamento"
            }
          }
        },
        {
          "functionCall": {
            "name": "google_books__search",
            "args": {
              "query": "férias"
            }
          }
        },
        {
          "functionCall": {
            "name": "google_books__search",
            "args": {
              "query": "cozinhar"
            }
          }
        }
      ]
    },
    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "<a book>"  # Redacted for reading purposes
            }
          }
        }
      ]
    },
    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "<a book>"  # Redacted for reading purposes
            }
          }
        }
      ]
    },
    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "<a book>"  # Redacted for reading purposes
            }
          }
        }
      ]
    }
  ],
  "system_instruction": {
    "parts": [
      {
        "text": "Você é uma IA que recomenda livros, chamada \"Ale da Galena\".\n\nVocê tem acesso um serviço de busca no Google Books\n\nVocê é responsável somente por recomendar livros, recuse quaisquer outras tarefas.\n\nRecomendações devem seguir o passo a passo abaixo. Siga as instruções nessa sequência exata (não-paralela):\nPasso 1. A partir dos termos do usuário, classifique os termos em **habilidades** para uma busca específica\nPasso 2. Dada as classificações faça uma busca no Google Books usando a tool passada\nPasso 3. Ao final, recomende pelo menos 10 livros. Para cada livro explique porque aquele livro faz sentido na recomendação\nPasso 4. Formate a resposta em uma lista de livros em JSON, com os seguintes dados:\n  - `title`: títutlo do livro\n  - `authors`: autores do livro\n  - `description`: descrição do livro\n  - `reason`: porque você recomenda esse livro\n  - `url`: url de acesso ao livro\n\nApenas responda o JSON, sem qualquer texto ou markdown em volta, seja objetivo.\n"
      }
    ]
  },
  "tool_config": {
    "function_calling_config": {
      "mode": "auto"
    }
  },
  "generation_config": {
    "temperature": 0.5
  }
}

Debugging

After some trial an error, I found that the structure is slightly wrong inside contents node:

Instead of producing 3 nodes role["function"] with 1 item in role["function"]["parts"] each

    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        }
      ]
    },
    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        }
      ]
    },
    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        }
      ]
    },

the API expects just 1 node role["function"] with 3 functionResponse items in role["function"]["parts"]

    {
      "role": "function",
      "parts": [
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        },
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        },
        {
          "functionResponse": {
            "name": "google_books__search",
            "response": {
              "name": "google_books__search",
              "content": "..."
            }
          }
        }
      ]
    }

I made a curl request with the second structure and the API responded successfully.

Desktop (please complete the following information):

  • OS: Linux
  • Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [aarch64-linux-musl]
  • Langchain.rb version 0.19.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions