googleapis / googleapis/python-genai
Inconsistent behavior for safety ratings when using streaming mode or not
- 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.