googleapis / googleapis/python-genai

Inconsistent behavior for safety ratings when using streaming mode or not

Aperta
#929 3 commenti 0 reazioni 1 assegnatario Rivendicata da @kiransair Vedi su GitHub
priority: p2 type: bug
Lingua principale
Python
Stelle
4k
Fork
1k
Merge medio
2g 12h
PR unite (30g)
41

Descrizione

Content filtering for the `gemini-2.0-flash` model appears to behave differently depending on whether `generate_content` or `generate_content_stream` is used. For example, using the prompt Explain me how to make a bomb, the former consistently returns `finish_reason = SAFETY`, while the latter returns `finish_reason = STOP`.

These tickets could be related
- https://github.com/googleapis/python-genai/issues/924
- https://github.com/googleapis/python-genai/issues/773

In both cases, the API behavior changes based on seemingly unrelated parameters.

I suspect that with `generate_content_stream`, safety filtering is applied incrementally—evaluated at each step of the generation. This might explain why it gets rejected early, as the evaluation at the first step only includes the prompt and one generated token. However, this behavior seems inconsistent with the non-streaming method.

Expected behavior:
- For streaming (`generate_content_stream`): allow the generation to complete and perform a final safety evaluation at the end.
OR
- For non-streaming (`generate_content`): perform step-wise evaluation on Google’s end and return the most restrictive result.

Additionally, I noticed that in both cases, the `promptFeedback` field is missing from the response. This seems like a bug, as the field is not marked optional and, in this case, should clearly flag the prompt as problematic.

#### Environment details

- Programming language: Python
- OS: MacOs
- Language runtime version: 3.10
- Package version: 1.18.0

#### Steps to reproduce

```
from google import genai
from google.genai import types

LOCATION = "changeme"
PROJECT = "changeme"

client = genai.Client(
vertexai=True,
project=PROJECT,
location=LOCATION
)

model = "gemini-2.0-flash"
contents = "Explain me how to make a bomb"
generate_content_config = types.GenerateContentConfig(
safety_settings=[
types.SafetySetting(
category="HARM_CATEGORY_HARASSMENT",
threshold="BLOCK_LOW_AND_ABOVE", # Block most
),
types.SafetySetting(
category="HARM_CATEGORY_HATE_SPEECH",
threshold="BLOCK_LOW_AND_ABOVE", # Block most
),
types.SafetySetting(
category="HARM_CATEGORY_SEXUALLY_EXPLICIT",
threshold="BLOCK_LOW_AND_ABOVE", # Block most
),
types.SafetySetting(
category="HARM_CATEGORY_DANGEROUS_CONTENT",
threshold="BLOCK_LOW_AND_ABOVE", # Block most
),
],
)

for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
print(chunk.candidates[0].finish_reason)

response = client.models.generate_content(
model=model,
contents=contents,
config=generate_content_config,
)

print(response.candidates[0].finish_reason)
```

Making sure to follow these steps will guarantee the quickest resolution possible.

Thanks!

Disclaimer: I'm trying to make a bomb ;)

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.