Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined array key "content" (MS OpenAI Content Filtering issue) #198

Open
chrisrickard opened this issue Aug 28, 2023 · 8 comments
Open
Assignees

Comments

@chrisrickard
Copy link

When using using the Azure OpenAI API, if content filtering is kicked off an error is returned Undefined array key "content" as there is no content parameter in the array within CreateResponseMessage.php

    /**
     * @param  array{role: string, content: ?string, function_call: ?array{name: string, arguments: string}}  $attributes
     */
    public static function from(array $attributes): self
    {
        return new self(
            $attributes['role'],
            $attributes['content'],
            isset($attributes['function_call']) ? CreateResponseFunctionCall::from($attributes['function_call']) : null,
        );
    }

The choices array looks something like this,

    "choices": [
        {
            "index": 0,
            "finish_reason": "content_filter",
            "message": {
                "role": "assistant"
            },
            "content_filter_results": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": true,
                    "severity": "medium"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    ],

That example above has the "sexual" filter triggered, hence why there is no content back from the assistant.

It would be great if this lib handled the content filtering issues (e.g. threw an exception with a message etc)

@gehrisandro
Copy link
Collaborator

Hi @chrisrickard

Could you provide a path to replicate this issue? Maybe an example prompt leading to this behaviour?

@gehrisandro
Copy link
Collaborator

Looks like have of the problem has been fixed here: #184

But the content_filter_results will not be available through this library. Therefore your prompts would still be helpful.

@gehrisandro gehrisandro self-assigned this Aug 28, 2023
@chrisrickard
Copy link
Author

hey @gehrisandro ah nice pickup, that PR should at least stop the error from being thrown.

Annoyingly I cannot seem to find an example prompt that replicated this behaviour without exposing my very large (private) prompt I'm afraid,

Most times I try and force the content filter I get back:

{
    "error": {
        "message": "The response was filtered due to the prompt triggering Azure OpenAI’s content management policy. Please modify your prompt and retry. To learn more about our content filtering policies please read our documentation: https://go.microsoft.com/fwlink/?linkid=2198766",
        "type": null,
        "param": "prompt",
        "code": "content_filter",
        "status": 400,
        "innererror": {
            "code": "ResponsibleAIPolicyViolation",
            "content_filter_result": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": true,
                    "severity": "medium"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    }
}

But that's fine, as the lib correctly throws an exception with that error.

However with my specific prompt (sorry I cannot supply this), I simply get

{
    "id": "chatcmpl-7shSxtAcFghboE1TxuEjr4MZDYtNc",
    "object": "chat.completion",
    "created": 1693271151,
    "model": "gpt-4",
    "prompt_annotations": [
        {
            "prompt_index": 0,
            "content_filter_results": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": false,
                    "severity": "safe"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    ],
    "choices": [
        {
            "index": 0,
            "finish_reason": "content_filter",
            "message": {
                "role": "assistant"
            },
            "content_filter_results": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": true,
                    "severity": "medium"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    ],
    "usage": {
        "completion_tokens": 2277,
        "prompt_tokens": 3034,
        "total_tokens": 5311
    }
}

@gehrisandro
Copy link
Collaborator

Hi @chrisrickard

Thank you for the information provided. I fully understand that you are not able to share everything with us.

I took a bit deeper look into the Azure stuff now, because I've never worked with Azure so far.

For me it looks like there are various things on the Azure API not available through the regular OpenAI API. For example this prompt_annotations is only visible in the latest preview of the Azure documentation: https://github.com/Azure/azure-rest-api-specs/blob/0762e82bcccef4a032e29dda5e4c07fd7cc822a6/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-08-01-preview/generated.json#L607

Do you or anyone else know more about the way Azure and OpenAI are behaving together? Will the APIs stay to be consistent where one of them is sometimes updated earlier then the other or are they going to divert more and more?
The reason I am asking is, because I am not sure if we should implement support for this "Azure only" features within this package or if we should build a separate package for Azure (extending this library).

@chrisrickard
Copy link
Author

Hi @gehrisandro, that's a good question - I know OpenAI and MS have a partnership, and I hazard a guess that is because MS has invested 18+Billion, but I don't know if the API's will stay in sync etc.

I know that the Azure Open AI Offering is currently more of an enterprise play, and offers some more compliance than OpenAI for larger companies - and I believe the content filter is one of these.

Whether OpenAI will also integrate this into their API's I'm not sure.

So as you say, it may make sense to have a separate repo that augments the core functionality with Azure? 🤷‍♂️

@gehrisandro
Copy link
Collaborator

Hi @chrisrickard

Thanks for your response.

I will leave this issue open and try to figure out some more information about OpenAI and Azure.

@Sam152
Copy link

Sam152 commented Oct 18, 2023

This can also be reproduced directly with OpenAI credentials, without azure:

$client = $container->get(\OpenAI\Client::class);
$client->chat()->create([
    'model' => 'gpt-4-0613',
    'messages' => [['role' => 'system', 'content' => 'call my_function']],
    'functions' => [['name' => 'my_function', 'parameters' => ['type' => 'object', 'properties' => (object)[]]]],
    'function_call' => ['name' => 'my_function'],
]);

And here is a var_dump of $result, at the start of the response processing code here:

        $response = $this->transporter->requestStream($payload);
        return new StreamResponse(CreateStreamedResponse::class, $response);
$response = [
    'id' => 'chatcmpl-xxxxxxx',
    'object' => 'chat.completion',
    'created' => 1697598503,
    'model' => 'gpt-4-0613',
    'choices' => [
        [
            'index' => 0,
            'message' => [
                'role' => 'assistant',
                'content' => null,
                'function_call' => [
                    'name' => 'my_function',
                    'arguments' => '{}',
                ],
            ],
            'finish_reason' => 'stop',
        ],
    ],
    'usage' => [
        'prompt_tokens' => 37,
        'completion_tokens' => 1,
        'total_tokens' => 38,
    ],
];

@gehrisandro
Copy link
Collaborator

@Sam152 I ran your code but I don't know, what you mean by that. Could you please explain what exactly you can reproduce?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants