-
-
Notifications
You must be signed in to change notification settings - Fork 258
Description
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