How to Prevent Tool Output Summarization in Responses API

Hello,
I have a question about Tools in the Responses API. How can I ensure that the text given to a Tool is used without summarization? For example, if there’s a Tool that returns a URL, and this URL is long, the Responses API summarizes it. Since it’s a URL, summarization is problematic. I’ve attached a sample below.
Thanks,

import { OpenAI } from "openai";
import dotenv from "dotenv";
import assert from 'assert';

dotenv.config();
const openai = new OpenAI();
const model = "gpt-4.1";
const response1 = await openai.responses.create({
  model,
  input: "Search the book",
  tools: [
    {
      type: "function",
      name: "searchBook",
      description: "Book search",
    }
  ]
});
const toolCall = response1.output[0];
assert(toolCall.type === "function_call");
assert(toolCall.name === "searchBook");
const input: (OpenAI.Responses.ResponseOutputItem | OpenAI.Responses.ResponseFunctionToolCallInputItem)[] = [];
input.push(toolCall);
const output = `
 ## abstract
 "Book of ABC-XYZ"
 ## pdf
 https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz
`;
input.push({
  type: "function_call_output",
  call_id: toolCall.call_id,
  output,
});
const response2 = await openai.responses.create({
  model,
  input,
});
console.log(response2.output_text);

You might consider giving back a JSON string so that it is very clear what is the URL. And of course in your prompt (or in the tool function description) you can mention that the URL might be very long but cannot be truncated.

I tried that, but didn’t work…

1 Like

I just tried it in playground (using 4.1) and this prompt ‘Find the book “Alone” return Markdown with the title of the book and the embedded link to the book.’ And I pasted exactly you string and added ‘F0’ at the end so I could see that it took the whole string. The response was as expected:

## [Alone](https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyzF0)

(notice the F0 at the end)
And this was using the your output (ie your text string, not JSON. I think it might be a different problem.

2 Likes

When I do the same thing several times, sometimes it works and sometimes it doesn’t. That’s the problem.

1 Like

If you want an accurate repeater, best to add some more parameters.

Alongside model, try: top_p = 0.0

Thanks for your suggestion. I tried:

const response2 = await openai.responses.create({
  model,
  input,
  top_p: 0.0,
});

but nothing changed, output:

Here is the information I found:

**Book Title:** Book of ABC-XYZ

**Abstract:** (No detailed abstract provided.)

**PDF Link:** You can access the full book as a PDF here: [Book of ABC-XYZ PDF](https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&...)

If you need a summary, specific chapters, or have any questions about the content, let me know!
1 Like

Maybe try a real URL instead of something that inherently looks like a placeholder.

DALL-E is also a ridiculous URL generator if you need 200 characters.

You might also feed the AI a placeholder URL, and then have code translate it back for the client, and save yourself that many tokens.

Actually, it’s a signed AWS S3 link with long URL parameters. I’m troubled by this phenomenon, so I abstracted it to ask the question here.

1 Like

I tested it here and couldn’t replicate your issue using the placeholder you provided.
Could you try this python script, replacing your own url to see if the problem persists?
I only added a few system instructions and provided the return answer as a json.

Python example
from openai import OpenAI

client = OpenAI()

select_model="gpt-4.1"

tools = [{
    "type": "function",
    "name": "get_book_information",
    "description": "Search for a e-book information like description and url to access.",
    "parameters": {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
        },
        "required": ["name"],
        "additionalProperties": False
    },
    "strict": True
}]

input_messages = [{"role": "user", "content": "I need details on the book: Getting started with XYZ, and a link to download it."}]

response = client.responses.create(
    model=select_model,
    input=input_messages,
    instructions="Make sure that URLs always remain unchanged.",
    tools=tools,
)


tool_call = response.output[0]
args = json.loads(tool_call.arguments)

result = {
            "description": "a book about xyz",
            "url":"https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz#EOF" 
         }

# append result message
input_messages = [{
    "type": "function_call_output",
    "call_id": tool_call.call_id,
    "output": str(result)
}]
response_2 = client.responses.create(
    model=select_model,
    previous_response_id=response.id,
    input=input_messages,
    tools=tools,
)
print(response_2.output_text)

Output:

Here are the details for the book you requested:

Title: Getting Started with XYZ
Description: A book about xyz.

You can download the book using the following link:
Download Getting Started with XYZ

If you need more information or another book, let me know!

1 Like

Thank you.
When I ran the Python script you provided several times, it indeed resulted in the URL being summarized as follows.

Here are the details for the book "Getting started with XYZ":

- Description: A book about xyz.

You can download the book using this link: Download Getting started with XYZ (https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&...#EOF)

How strange. Could you try this one?

Revised code
from openai import OpenAI
import json

client = OpenAI()

select_model="gpt-4.1-mini"

tools = [{
    "type": "function",
    "name": "get_book_information",
    "description": "Search for a e-book information like description and url to access.",
    "parameters": {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
        },
        "required": ["name"],
        "additionalProperties": False
    },
    "strict": True
}]

input_messages = [{"role": "user", "content": "I need details on the book: Getting started with XYZ, and a link to download it. Return a JSON with the keys: book, description, url."}]

response = client.responses.create(
    model=select_model,
    input=input_messages,
    instructions="Make sure that URL always remain unmodified. ",
    tools=tools,
    text = {"format": {
                "type": "json_object"
               }
            },
    truncation='disabled',
    max_output_tokens=5000,
    temperature=0.0,
    top_p=0.0,
)

expected_url = "https://abc.com/xyz.pdf?abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz&abcdefghijklmnopqrstuvwxyz=abcdefghijklmnopqrstuvwxyz#EOF"

for i in range(1,11):
    print(f"Try #{i}: ",end="")
    tool_call = response.output[0]
    args = json.loads(tool_call.arguments)

    result = {
                "description": "a book about xyz",
                "url":expected_url 
            }

    # append result message
    input_messages = [{
        "type": "function_call_output",
        "call_id": tool_call.call_id,
        "output": str(result)
    }]
    response_2 = client.responses.create(
        model=select_model,
        previous_response_id=response.id,
        input=input_messages,
        tools=tools,
        truncation='disabled',
        max_output_tokens=5000,
        temperature=0.0,
        top_p=0.0,
    )
    answer = json.loads(response_2.output_text)
    print("OK" if answer.get('url').strip()== expected_url.strip() else "Changed" )

And if it persists, could you provide how often it misses, and an anonymized version that looks a bit closer to your url?

The URL is no longer being shortened. Because of Return a JSON with the keys: book, description, url. ? I’ll try a bit more. Thank you.

2 Likes

Nice. Also considering you always expect an url, you could simply take the json and replace the string directly before returning the final result, preventing the model from unintentionally modifying it further.

Whether using JSON format is suitable for the app under development requires consideration. However, it’s helpful that the options to consider have increased. Thanks.

The app I’m developing is based on AI chat. Since I want natural interactions in normal use, I don’t want to do JSON-like processing. Is there a way to receive only the output from when search tools are used in JSON format?

You can re-run the first code I sent you (text) with the extra parameters. I only used json to be able to check if it matches. I added truncation, temperature, top_p and max_token parameters.

It is what I told you the first time for your function output :slight_smile:

1 Like

Even if I use JSON format, it seems that URLs still get ‘summarized’ when the overall amount of information increases. That’s disappointing. But thank you.

1 Like

Any way to limit the variety of URLs?

Any scheme you can use to manipulate short URLs instead?

Or use some short reference to associate with the longer URL and convert deterministically at point of use?