microsoft / microsoft/azurechat
Improve handling of bad responses (content filtering)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 1
Description
Current state
User: Enters something that gets flagged by the Azure OpenAI Service content filtering
Bot: No response
The backend receives a 400 and doesn't know how to handle it.
Error in handler Handler, handleChainError: Error: Request failed with status code 400 and body {"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":true,"severity":"high"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":true,"severity":"medium"}}}}}
- error node_modules\langchain\dist\util\axios-fetch-adapter.js (351:18) @ createError
log.js:70
- error unhandledRejection: Error: Request failed with status code 400 and body {"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":true,"severity":"high"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":true,"severity":"medium"}}}}}
at createError (webpack-internal:///(rsc)/./node_modules/langchain/dist/util/axios-fetch-adapter.js:320:19)
at settle (webpack-internal:///(rsc)/./node_modules/langchain/dist/util/axios-fetch-adapter.js:28:16)
at eval (webpack-internal:///(rsc)/./node_modules/langchain/dist/util/axios-fetch-adapter.js:162:124)
at new Promise (<anonymous>)
at fetchAdapter (webpack-internal:///(rsc)/./node_modules/langchain/dist/util/axios-fetch-adapter.js:157:12)
at process.processTicksAndRejections (C:\repos\Aware\azurechat\src\lib\internal\process\task_queues.js:95:5)
at async RetryOperation.eval [as _fn] (webpack-internal:///(rsc)/./node_modules/p-retry/index.js:40:25) {name: 'Error', digest: undefined, stack: 'Error: Request failed with status code 400 an…/(rsc)/./node_modules/p-retry/index.js:40:25)', message: 'Request failed with status code 400 and body…e":{"filtered":true,"severity":"medium"}}}}}', Symbol(NextjsError): 'server'}
Ideal state
- Content filtering is automatically handled in the sample.
- A framework for a handler of non-2XX responses is provided as part of the sample.
Attempts
In terms of developing a solution myself, I got as far as identifying the handlers object in chat-simple-api.ts as providing methods like handleLLMError, handleToolError, and handleChainError, defined here as a likely place to wire into. However, since they all return void, and I want to return StreamingResponse I'm kind of stuck as to where to go from here (I want to return a generic message to the user).
const chain = new ConversationChain({
llm: chat,
memory,
prompt: chatPrompt
});
handlers.handleLLMError = async (e: Error, runId: string) => {
// Handle response here
const errorMessage = e.message;
console.error(errorMessage);
if (errorMessage.includes("Azure OpenAI's content management policy")) {
// Do stuff in here
return new StreamingTextResponse(new ReadableStream("Content filtering policy triggered"));
}
else {
// Other handling in here
}
};
chain.call({ input: lastHumanMessage.content }, [handlers]);
return new StreamingTextResponse(stream);
Wrapping chain.call in a try-catch and explicitly throwing inside the handleLLMError function also doesn't seem to work as my catch block is never hit.
const chain = new ConversationChain({
llm: chat,
memory,
prompt: chatPrompt
});
handlers.handleLLMError = async (e: Error, runId: string) => {
// Handle response here
const errorMessage = e.message;
console.error(errorMessage);
// Also doesn't work
// throw e;
throw new error(errorMessage);
};
try {
chain.call({ input: lastHumanMessage.content }, [handlers]);
} catch (e) {
console.error(e);
}
return new StreamingTextResponse(stream);
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in chat-simple-api.ts by tracing chain.call, the handlers object, and the StreamingTextResponse path. Check how handleLLMError and handleChainError receive the Azure OpenAI 400 response, then define handling for content_filter and other non-2XX errors. Done means filtered prompts produce a user-visible generic message instead of an unhandled rejection, with a reusable error-handling approach in the sample.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, typescript
- Domain
- api, backend, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100