Function call string property is double escaped

Why characters like " or ' or \n are getting double escaped in value of string properties of function call args?

I’m getting such response from Gemini Flash:

'\\"\\"\\"\\n#include <iostream>\\n\\nint main() {\\n  std::cout << \\"Hello, world!\\" << std::endl;\\n  return 0;\\n}\\n\\"\\"\\"'

Gemini Pro answer is:

'// Your First C++ Program\\n\\n#include <iostream>\\n\\nint main() {\\n  std::cout << "Hello World!";\\n  return 0;\\n}'

(so slightly better, because it is not wrapped with """ but still the \n is double escaped)

while I would expect:

'"""\n#include <iostream>\n\nint main() {\n  std::cout << "Hello, world!" << std::endl;\n  return 0;\n}n"""'

The workaround is to do such find/replace: .replace(/\\n/g, '\n').replace(/\\'/g, "'") but unfortunately it is flaky. Sometimes a \\n is valid (inside string literal).

This problem can be reproduced with this node.js script:

// Derived from: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/main/generative-ai/snippets/function-calling/functionCallingBasic.js

const { VertexAI, FunctionDeclarationSchemaType } = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'saveSourceCode',
        description: 'save source code to a file',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            path: { type: FunctionDeclarationSchemaType.STRING },
            content: {
              type: FunctionDeclarationSchemaType.STRING,
            },
          },
          required: ['path', 'content'],
        },
      },
    ],
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingBasic(
  projectId = process.env.GOOGLE_CLOUD_PROJECT,
  location = 'us-central1',
  model = 'gemini-1.5-flash-001',
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({ project: projectId, location: location });

  // Instantiate the model
  const generativeModel = vertexAI.preview.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [{ role: 'user', parts: [{ text: 'Generate a c++ hello world' }] }],
    tools: functionDeclarations,
    toolConfig: {
      functionCallingConfig: {
        allowedFunctionNames: ['saveSourceCode'],
        mode: 'ANY',
      },
    },
  };
  const result = await generativeModel.generateContent(request);
  console.log(result.response.candidates[0].content.parts[0].functionCall);
}
// [END generativeaionvertexai_function_calling_basic]

functionCallingBasic(...process.argv.slice(2)).catch((err) => {
  console.error(err.message);
  process.exitCode = 1;
});

I will appreciate help with this :slight_smile:

ps. This problem does not happen on other ai service providers as I checked

1 Like

The problem becomes more apparent for such prompt:
Generate a node.js hello world that takes user input, use single aposthrophes for strings:

Interestingly, I’m getting correct result when I’m using structured output instead of function calling:

1 Like

I’m running into the exact same issue. @Grzegorz_Tanczyk would you be so kind as to share how you’ve worked around it using structured output?

I don’t consider this as a proper workaround, as I need to use function calling in my use case. I posted this example to have a reference point for this bug report.

I used the standard configuration for structured output:

    generationConfig: {
      responseMimeType: 'application/json',
      responseSchema: {
        type: FunctionDeclarationSchemaType.OBJECT,
        properties: {
          path: { type: FunctionDeclarationSchemaType.STRING },
          content: {
            type: FunctionDeclarationSchemaType.STRING,
            description: 'source code',
          },
        },
        required: ['path', 'content'],
      },
    },
1 Like

Thank you. My hunch is that Gemini is trying hard to output markdown but I don’t have any real evidence. I’ve tried prompting it to not apply any formatting, etc but it still insists on double escaping things and adding \n sequences all over the place.