From c41e3d683969183cca8762bbec37e53136a5d2f0 Mon Sep 17 00:00:00 2001 From: Corneliu CROITORU Date: Wed, 28 Aug 2024 18:18:17 +0200 Subject: [PATCH] update doc --- docs/astro.config.mjs | 5 +- .../agents/built-in/bedrock-llm-agent.mdx | 15 +- .../built-in/bedrock-translator-agent.mdx | 276 ++++++++++++ .../docs/agents/built-in/chain-agent.mdx | 208 +++++++++ .../built-in/comprehend-filter-agent.mdx | 421 ++++++++++++++++++ .../agents/chain_agent.py | 5 +- .../classifiers/anthropic_classifier.py | 3 +- .../multi_agent_orchestrator/orchestrator.py | 2 +- 8 files changed, 922 insertions(+), 13 deletions(-) create mode 100644 docs/src/content/docs/agents/built-in/bedrock-translator-agent.mdx create mode 100644 docs/src/content/docs/agents/built-in/chain-agent.mdx create mode 100644 docs/src/content/docs/agents/built-in/comprehend-filter-agent.mdx diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index ee9d77d..4731a5c 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -63,7 +63,10 @@ export default defineConfig({ { label: 'Amazon Bedrock Agent', link: '/agents/built-in/amazon-bedrock-agent' }, { label: 'Amazon Lex Bot Agent', link: '/agents/built-in/lex-bot-agent' }, { label: 'AWS Lambda Agent', link: '/agents/built-in/lambda-agent' }, - { label: 'OpenAI Agent', link: '/agents/built-in/openai-agent' } + { label: 'OpenAI Agent', link: '/agents/built-in/openai-agent' }, + { label: 'Chain Agent', link: '/agents/built-in/chain-agent' }, + { label: 'Comprehend Filter Agent', link: '/agents/built-in/comprehend-filter-agent' }, + { label: 'Amazon Bedrock Translator Agent', link: '/agents/built-in/bedrock-translator-agent' } ] }, { label: 'Custom Agents', link: '/agents/custom-agents' }, diff --git a/docs/src/content/docs/agents/built-in/bedrock-llm-agent.mdx b/docs/src/content/docs/agents/built-in/bedrock-llm-agent.mdx index 41e7d90..ae750db 100644 --- a/docs/src/content/docs/agents/built-in/bedrock-llm-agent.mdx +++ b/docs/src/content/docs/agents/built-in/bedrock-llm-agent.mdx @@ -4,7 +4,7 @@ description: Documentation for the BedrockLLMAgent in the Multi-Agent Orchestrat --- ## Overview -The `BedrockLLMAgent` is a powerful and flexible agent class in the Multi-Agent Orchestrator System. It leverages [Amazon Bedrock's Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) to interact with various LLMs supported by Amazon Bedrock. +The **Bedrock LLM Agent** is a powerful and flexible agent class in the Multi-Agent Orchestrator System. It leverages [Amazon Bedrock's Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) to interact with various LLMs supported by Amazon Bedrock. This agent can handle a wide range of processing tasks, making it suitable for diverse applications such as conversational AI, question-answering systems, and more. @@ -20,11 +20,11 @@ This agent can handle a wide range of processing tasks, making it suitable for d ## Creating a BedrockLLMAgent -By default, the Bedrock LLM Agent uses the `anthropic.claude-3-haiku-20240307-v1:0` model. +By default, the **Bedrock LLM Agent** uses the `anthropic.claude-3-haiku-20240307-v1:0` model. ### Basic Example -To create a new `BedrockLLMAgent` with only the required parameters, use the following code: +To create a new **Bedrock LLM Agent** with only the required parameters, use the following code: import { Tabs, TabItem } from '@astrojs/starlight/components'; @@ -55,7 +55,7 @@ In this basic example, only the `name` and `description` are provided, which are ### Advanced Example -For more complex use cases, you can create a BedrockLLMAgent with all available options. All parameters except `name` and `description` are optional: +For more complex use cases, you can create a **Bedrock LLM Agent** with all available options. All parameters except `name` and `description` are optional: @@ -177,7 +177,6 @@ For more complex use cases, you can create a BedrockLLMAgent with all available ## Setting a New Prompt -You can update the agent's system prompt at any time using the `set_system_prompt` method: @@ -214,7 +213,7 @@ This method allows you to dynamically change the agent's behavior and focus with ## Adding the Agent to the Orchestrator -To integrate the BedrockLLMAgent into your Multi-Agent Orchestrator, follow these steps: +To integrate the **Bedrock LLM Agent** into your orchestrator, follow these steps: 1. First, ensure you have created an instance of the orchestrator: @@ -273,4 +272,6 @@ To integrate the BedrockLLMAgent into your Multi-Agent Orchestrator, follow thes -By leveraging the `BedrockLLMAgent`, you can create sophisticated, context-aware AI agents capable of handling a wide range of tasks and interactions, all powered by the latest LLM models available through Amazon Bedrock. \ No newline at end of file +--- + +By leveraging the **Bedrock LLM Agent**, you can create sophisticated, context-aware AI agents capable of handling a wide range of tasks and interactions, all powered by the latest LLM models available through Amazon Bedrock. \ No newline at end of file diff --git a/docs/src/content/docs/agents/built-in/bedrock-translator-agent.mdx b/docs/src/content/docs/agents/built-in/bedrock-translator-agent.mdx new file mode 100644 index 0000000..06123e6 --- /dev/null +++ b/docs/src/content/docs/agents/built-in/bedrock-translator-agent.mdx @@ -0,0 +1,276 @@ +--- +title: Bedrock Translator Agent +description: Documentation for the Bedrock Translator Agent in the Multi-Agent Orchestrator System +--- + +The `BedrockTranslatorAgent` uses Amazon Bedrock's language models to translate text between different languages. + +## Key Features + +- Utilizes Amazon Bedrock's language models +- Supports translation between multiple languages +- Allows dynamic setting of source and target languages +- Can be used standalone or as part of a [ChainAgent](/multi-agent-orchestrator/agents/built-in/chain-agent) +- Configurable inference parameters for fine-tuned control + +## Creating a Bedrock Translator Agent + +### Basic Example + +To create a new `BedrockTranslatorAgent` with minimal configuration: + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + ```typescript + import { BedrockTranslatorAgent, BedrockTranslatorAgentOptions } from 'multi-agent-orchestrator'; + + const agent = new BedrockTranslatorAgent({ + name: 'BasicTranslator', + description: 'Translates text to English', + targetLanguage: 'English' + }); + ``` + + + ```python + from multi_agent_orchestrator.agents import BedrockTranslatorAgent, BedrockTranslatorAgentOptions + + agent = BedrockTranslatorAgent(BedrockTranslatorAgentOptions( + name='BasicTranslator', + description='Translates text to English', + target_language='English' + )) + ``` + + + +### Advanced Example + +For more complex use cases, you can create a BedrockTranslatorAgent with custom settings: + + + + ```typescript + import { BedrockTranslatorAgent, BedrockTranslatorAgentOptions, BEDROCK_MODEL_ID_CLAUDE_3_SONNET } from 'multi-agent-orchestrator'; + + const options: BedrockTranslatorAgentOptions = { + name: 'AdvancedTranslator', + description: 'Advanced translator with custom settings', + sourceLanguage: 'French', + targetLanguage: 'German', + modelId: BEDROCK_MODEL_ID_CLAUDE_3_SONNET, + region: 'us-west-2', + inferenceConfig: { + maxTokens: 2000, + temperature: 0.1, + topP: 0.95, + stopSequences: ['###'] + } + }; + + const agent = new BedrockTranslatorAgent(options); + ``` + + + ```python + from multi_agent_orchestrator.agents import BedrockTranslatorAgent, BedrockTranslatorAgentOptions + from multi_agent_orchestrator.types import BEDROCK_MODEL_ID_CLAUDE_3_SONNET + + options = BedrockTranslatorAgentOptions( + name='AdvancedTranslator', + description='Advanced translator with custom settings', + source_language='French', + target_language='German', + model_id=BEDROCK_MODEL_ID_CLAUDE_3_SONNET, + region='us-west-2', + inference_config={ + 'maxTokens': 2000, + 'temperature': 0.1, + 'topP': 0.95, + 'stopSequences': ['###'] + } + ) + + agent = BedrockTranslatorAgent(options) + ``` + + + +## Dynamic Language Setting + +To set the language during the invocation: + + + + ```typescript + import { MultiAgentOrchestrator, BedrockTranslatorAgent } from 'multi-agent-orchestrator'; + + const translator = new BedrockTranslatorAgent({ + name: 'DynamicTranslator', + description: 'Translator with dynamically set languages' + }); + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(translator); + + async function translateWithDynamicLanguages(text: string, fromLang: string, toLang: string) { + translator.setSourceLanguage(fromLang); + translator.setTargetLanguage(toLang); + + const response = await orchestrator.routeRequest( + text, + 'user123', + 'session456' + ); + + console.log(`Translated from ${fromLang} to ${toLang}:`, response); + } + + // Usage + translateWithDynamicLanguages("Hello, world!", "English", "French"); + translateWithDynamicLanguages("Bonjour le monde!", "French", "Spanish"); + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + from multi_agent_orchestrator.agents import BedrockTranslatorAgent, BedrockTranslatorAgentOptions + + translator = BedrockTranslatorAgent(BedrockTranslatorAgentOptions( + name='DynamicTranslator', + description='Translator with dynamically set languages' + )) + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(translator) + + async def translate_with_dynamic_languages(text: str, from_lang: str, to_lang: str): + translator.set_source_language(from_lang) + translator.set_target_language(to_lang) + + response = await orchestrator.route_request( + text, + 'user123', + 'session456' + ) + + print(f"Translated from {from_lang} to {to_lang}:", response) + + # Usage + import asyncio + + asyncio.run(translate_with_dynamic_languages("Hello, world!", "English", "French")) + asyncio.run(translate_with_dynamic_languages("Bonjour le monde!", "French", "Spanish")) + ``` + + + +## Usage with ChainAgent + +The `BedrockTranslatorAgent` can be effectively used within a `ChainAgent` for complex multilingual processing workflows. Here's an example that demonstrates translating user input and processing it: + + + + ```typescript + import { MultiAgentOrchestrator, ChainAgent, BedrockTranslatorAgent, BedrockLLMAgent } from 'multi-agent-orchestrator'; + + // Create translator agents + const translatorToEnglish = new BedrockTranslatorAgent({ + name: 'TranslatorToEnglish', + description: 'Translates input to English', + targetLanguage: 'English' + }); + + // Create a processing agent (e.g., a BedrockLLMAgent) + const processor = new BedrockLLMAgent({ + name: 'EnglishProcessor', + description: 'Processes text in English' + }); + + // Create a ChainAgent + const chainAgent = new ChainAgent({ + name: 'TranslateProcessTranslate', + description: 'Translates, processes, and translates back', + agents: [translatorToEnglish, processor] + }); + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(chainAgent); + + // Function to handle user input + async function handleMultilingualInput(input: string, sourceLanguage: string) { + translatorToEnglish.setSourceLanguage(sourceLanguage); + + const response = await orchestrator.routeRequest( + input, + 'user123', + 'session456' + ); + + console.log('Response:', response); + } + + // Usage + handleMultilingualInput("Hola, ¿cómo estás?", "Spanish"); + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + from multi_agent_orchestrator.agents import ChainAgent, BedrockTranslatorAgent, BedrockLLMAgent + from multi_agent_orchestrator.agents import ChainAgentOptions, BedrockTranslatorAgentOptions, BedrockLLMAgentOptions + + # Create translator agents + translator_to_english = BedrockTranslatorAgent(BedrockTranslatorAgentOptions( + name='TranslatorToEnglish', + description='Translates input to English', + target_language='English' + )) + + # Create a processing agent (e.g., a BedrockLLMAgent) + processor = BedrockLLMAgent(BedrockLLMAgentOptions( + name='EnglishProcessor', + description='Processes text in English' + )) + + # Create a ChainAgent + chain_agent = ChainAgent(ChainAgentOptions( + name='TranslateProcessTranslate', + description='Translates, processes, and translates back', + agents=[translator_to_english, processor] + )) + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(chain_agent) + + # Function to handle user input + async def handle_multilingual_input(input_text: str, source_language: str): + translator_to_english.set_source_language(source_language) + + response = await orchestrator.route_request( + input_text, + 'user123', + 'session456' + ) + + print('Response:', response) + + # Usage + import asyncio + + asyncio.run(handle_multilingual_input("Hola, ¿cómo estás?", "Spanish")) + ``` + + + +In this example: +1. The first translator agent converts the input to English. +2. The processor agent (e.g., a `BedrockLLMAgent`) processes the English text. + +This setup allows for seamless multilingual processing, where the core logic can be implemented in English while supporting input and output in various languages. + +--- + +By leveraging the `BedrockTranslatorAgent`, you can create sophisticated multilingual applications and workflows, enabling seamless communication and processing across language barriers in your Multi-Agent Orchestrator system. \ No newline at end of file diff --git a/docs/src/content/docs/agents/built-in/chain-agent.mdx b/docs/src/content/docs/agents/built-in/chain-agent.mdx new file mode 100644 index 0000000..7402d74 --- /dev/null +++ b/docs/src/content/docs/agents/built-in/chain-agent.mdx @@ -0,0 +1,208 @@ +--- +title: Chain Agent +description: Documentation for the Chain Agent in the Multi-Agent Orchestrator System +--- +The `ChainAgent` is an agent class in the Multi-Agent Orchestrator System that allows for the sequential execution of multiple agents. It processes a request by passing the output of one agent as input to the next, creating a chain of agent interactions. + +## Creating a ChainAgent + +### Basic Example + +Here's how to create a ChainAgent with only the required parameters: + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + ```typescript + import { ChainAgent, ChainAgentOptions } from 'multi-agent-orchestrator'; + import { BedrockLLMAgent } from 'multi-agent-orchestrator'; + + const agent1 = new BedrockLLMAgent({ + name: 'Agent 1', + description: '..AGENT DESCRIPTION..' + }); + + const agent2 = new BedrockLLMAgent({ + name: 'Agent 2', + description: '..AGENT DESCRIPTION..' + }); + + const chainAgent = new ChainAgent({ + name: 'Chain Tech Agent', + description: 'Specializes in technology areas including software development, hardware, AI, cybersecurity, blockchain, cloud computing, emerging tech innovations, and pricing/costs related to technology products and services.', + agents: [agent1, agent2] + }); + ``` + + + ```python + from multi_agent_orchestrator.agents import ChainAgent, ChainAgentOptions + from multi_agent_orchestrator.agents import BedrockLLMAgent, BedrockLLMAgentOptions + + agent1 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 1', + description='..AGENT DESCRIPTION..' + )) + + agent2 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 2', + description='..AGENT DESCRIPTION..' + )) + + chain_agent = ChainAgent(ChainAgentOptions( + name='BasicChainAgent', + description='A simple chain of multiple agents', + agents=[agent1, agent2] + )) + ``` + + + +### Intermediate Example + +This example shows how to create a ChainAgent with a custom default output: + + + + ```typescript + import { ChainAgent, ChainAgentOptions } from 'multi-agent-orchestrator'; + import { BedrockLLMAgent } from 'multi-agent-orchestrator'; + + const agent1 = new BedrockLLMAgent({ + name: 'Agent 1', + description: '..AGENT DESCRIPTION..' + }); + + const agent2 = new BedrockLLMAgent({ + name: 'Agent 2', + description: '..AGENT DESCRIPTION..', + streaming: true + }); + + const chainAgent = new ChainAgent({ + name: 'IntermediateChainAgent', + description: 'A chain of agents with custom default output', + agents: [agent1, agent2], + defaultOutput: 'The chain encountered an issue during processing.' + }); + ``` + + + ```python + from multi_agent_orchestrator.agents import ChainAgent, ChainAgentOptions + from multi_agent_orchestrator.agents import BedrockLLMAgent, BedrockLLMAgentOptions + + agent1 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 1', + description='..AGENT DESCRIPTION..' + )) + + agent2 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 2', + description='..AGENT DESCRIPTION..' + )) + + chain_agent = ChainAgent(ChainAgentOptions( + name='IntermediateChainAgent', + description='A chain of agents with custom default output', + agents=[agent1, agent2], + default_output='The chain encountered an issue during processing.' + )) + ``` + + + +### Advanced Example + +For more complex use cases, you can create a ChainAgent with all available options: + + + + ```typescript + import { ChainAgent, ChainAgentOptions } from 'multi-agent-orchestrator'; + import { BedrockLLMAgent } from 'multi-agent-orchestrator'; + + const agent1 = new BedrockLLMAgent({ + name: 'Agent 1', + description: '..AGENT DESCRIPTION..' + }); + + const agent2 = new BedrockLLMAgent({ + name: 'Agent 2', + description: '..AGENT DESCRIPTION..', + streaming: true + }); + + const options: ChainAgentOptions = { + name: 'AdvancedChainAgent', + description: 'A sophisticated chain of agents with all options', + agents: [agent1, agent2], + defaultOutput: 'The chain processing encountered an issue.', + saveChat: true + }; + + const chainAgent = new ChainAgent(options); + ``` + + + ```python + from multi_agent_orchestrator.agents import ChainAgent, ChainAgentOptions + from multi_agent_orchestrator.agents import BedrockLLMAgent, BedrockLLMAgentOptions + + agent1 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 1', + description='..AGENT DESCRIPTION..' + )) + + agent2 = BedrockLLMAgent(BedrockLLMAgentOptions( + name='Agent 2', + description='..AGENT DESCRIPTION..', + streaming=True + )) + + options = ChainAgentOptions( + name='AdvancedChainAgent', + description='A sophisticated chain of agents with all options', + agents=[agent1, agent2], + default_output='The chain processing encountered an issue.', + save_chat=True + ) + + chain_agent = ChainAgent(options) + ``` + + + +## Integrating ChainAgent into the Multi-Agent Orchestrator + +To integrate the ChainAgent into your Multi-Agent Orchestrator: + + + + ```typescript + import { MultiAgentOrchestrator } from "multi-agent-orchestrator"; + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(chainAgent); + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(chain_agent) + ``` + + + +## Streaming Responses + +The ChainAgent supports streaming responses only for the last agent in the chain. + +This design ensures efficient processing through the chain while still enabling streaming capabilities for the end result. + +--- + +By leveraging the ChainAgent, you can create sophisticated, multi-step processing pipelines within your Multi-Agent Orchestrator system, allowing for complex interactions and transformations of user inputs, with the added flexibility of streaming output from the final processing step. \ No newline at end of file diff --git a/docs/src/content/docs/agents/built-in/comprehend-filter-agent.mdx b/docs/src/content/docs/agents/built-in/comprehend-filter-agent.mdx new file mode 100644 index 0000000..adbddb2 --- /dev/null +++ b/docs/src/content/docs/agents/built-in/comprehend-filter-agent.mdx @@ -0,0 +1,421 @@ +--- +title: Comprehend Filter Agent +description: Documentation for the Comprehend Filter Agent in the Multi-Agent Orchestrator System +--- +The `ComprehendFilterAgent` is an agent class in the Multi-Agent Orchestrator System that uses [Amazon Comprehend](https://aws.amazon.com/comprehend/?nc1=h_ls) to analyze and filter content based on sentiment, Personally Identifiable Information (PII), and toxicity. + +It can be used as a standalone agent within the Multi-Agent Orchestrator or as part of a chain in the ChainAgent. + +When used in a [ChainAgent](/multi-agent-orchestrator/agents/built-in/chain-agent) configuration, it's particularly effective as the first agent in the list. In this setup, it can check the user input against all configured filters, and if the content passes these checks, it will forward the original user input to the next agent in the chain. This allows for a robust content moderation system that can be seamlessly integrated into more complex processing pipelines, ensuring that only appropriate content is processed by subsequent agents. + +## Key Features + +- Content analysis using Amazon Comprehend +- Configurable checks for sentiment, PII, and toxicity +- Customizable thresholds for sentiment and toxicity +- Support for multiple languages +- Ability to add custom content checks + +## Creating a Comprehend Filter Agent + +### Basic Example + +To create a new `ComprehendFilterAgent` with default settings: + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + ```typescript + import { ComprehendFilterAgent, ComprehendFilterAgentOptions } from 'multi-agent-orchestrator'; + + const agent = new ComprehendFilterAgent({ + name: 'ContentModerator', + description: 'Analyzes and filters content using Amazon Comprehend' + }); + ``` + + + ```python + from multi_agent_orchestrator.agents import ComprehendFilterAgent, ComprehendFilterAgentOptions + + agent = ComprehendFilterAgent(ComprehendFilterAgentOptions( + name='ContentModerator', + description='Analyzes and filters content using Amazon Comprehend' + )) + ``` + + + +### Advanced Example + +For more complex use cases, you can create a `ComprehendFilterAgent` with custom settings: + + + + ```typescript + import { ComprehendFilterAgent, ComprehendFilterAgentOptions } from 'multi-agent-orchestrator'; + + const options: ComprehendFilterAgentOptions = { + name: 'AdvancedContentModerator', + description: 'Advanced content moderation with custom settings', + region: 'us-west-2', + enableSentimentCheck: true, + enablePiiCheck: true, + enableToxicityCheck: true, + sentimentThreshold: 0.8, + toxicityThreshold: 0.6, + allowPii: false, + languageCode: 'en' + }; + + const agent = new ComprehendFilterAgent(options); + ``` + + + ```python + from multi_agent_orchestrator.agents import ComprehendFilterAgent, ComprehendFilterAgentOptions + + options = ComprehendFilterAgentOptions( + name='AdvancedContentModerator', + description='Advanced content moderation with custom settings', + region='us-west-2', + enable_sentiment_check=True, + enable_pii_check=True, + enable_toxicity_check=True, + sentiment_threshold=0.8, + toxicity_threshold=0.6, + allow_pii=False, + language_code='en' + ) + + agent = ComprehendFilterAgent(options) + ``` + + + +## Integrating Comprehend Filter Agent + +To integrate the `ComprehendFilterAgent` into your orchestrator: + + + + ```typescript + import { MultiAgentOrchestrator } from "multi-agent-orchestrator"; + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(agent); + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(agent) + ``` + + + +## Adding Custom Checks + +This example demonstrates how to add a **Custom Check** to the `ComprehendFilterAgent`: + + + + ```typescript + import { ComprehendFilterAgent, ComprehendFilterAgentOptions } from 'multi-agent-orchestrator'; + + const filterAgent = new ComprehendFilterAgent({ + name: 'AdvancedContentFilter', + description: 'Advanced content filter with custom checks' + }); + + // Add a custom check for specific keywords + filterAgent.addCustomCheck(async (text: string) => { + const keywords = ['banned', 'inappropriate', 'offensive']; + for (const keyword of keywords) { + if (text.toLowerCase().includes(keyword)) { + return `Banned keyword detected: ${keyword}`; + } + } + return null; + }); + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(filterAgent); + + const response = await orchestrator.routeRequest( + "This message contains a banned word.", + "user789", + "session101" + ); + + if (response) { + console.log("Content passed all checks"); + } else { + console.log("Content was flagged by the filter"); + } + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + from multi_agent_orchestrator.agents import ComprehendFilterAgent, ComprehendFilterAgentOptions + + filter_agent = ComprehendFilterAgent(ComprehendFilterAgentOptions( + name='AdvancedContentFilter', + description='Advanced content filter with custom checks' + )) + + # Add a custom check for specific keywords + async def custom_keyword_check(text: str) -> Optional[str]: + keywords = ['banned', 'inappropriate', 'offensive'] + for keyword in keywords: + if keyword in text.lower(): + return f"Banned keyword detected: {keyword}" + return None + + filter_agent.add_custom_check(custom_keyword_check) + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(filter_agent) + + response = await orchestrator.route_request( + "This message contains a banned word.", + "user789", + "session101" + ) + + if response: + print("Content passed all checks") + else: + print("Content was flagged by the filter") + ``` + + + +## Dynamic Language Detection and Handling + +The `ComprehendFilterAgent` offers flexible language handling capabilities. You can specify the language either at initialization or dynamically during invocation. Additionally, it supports automatic language detection, allowing it to adapt to content in various languages without manual specification. + +This example demonstrates dynamic language detection and handling: + + + + ```typescript + import { MultiAgentOrchestrator, ComprehendFilterAgent } from 'multi-agent-orchestrator'; + import { ComprehendClient, DetectDominantLanguageCommand } from "@aws-sdk/client-comprehend"; + + const filterAgent = new ComprehendFilterAgent({ + name: 'MultilingualContentFilter', + description: 'Filters content in multiple languages' + }); + + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(filterAgent); + + async function detectLanguage(text: string): Promise { + const comprehendClient = new ComprehendClient({ region: "us-east-1" }); + const command = new DetectDominantLanguageCommand({ Text: text }); + const response = await comprehendClient.send(command); + return response.Languages[0].LanguageCode; + } + + let detectedLanguage: string | null = null; + + async function processUserInput(userInput: string, userId: string, sessionId: string): Promise { + if (!detectedLanguage) { + detectedLanguage = await detectLanguage(userInput); + console.log(`Detected language: ${detectedLanguage}`); + } + + try { + const response = await orchestrator.routeRequest( + userInput, + userId, + sessionId, + { languageCode: detectedLanguage } + ); + + console.log("Processed response:", response); + } catch (error) { + console.error("Error:", error); + } + } + + // Example usage + processUserInput("Hello, world!", "user123", "session456"); + // Subsequent calls will use the same detected language + processUserInput("How are you?", "user123", "session456"); + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + from multi_agent_orchestrator.agents import ComprehendFilterAgent, ComprehendFilterAgentOptions + import boto3 + import asyncio + + filter_agent = ComprehendFilterAgent(ComprehendFilterAgentOptions( + name='MultilingualContentFilter', + description='Filters content in multiple languages' + )) + + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(filter_agent) + + def detect_language(text: str) -> str: + comprehend = boto3.client('comprehend', region_name='us-east-1') + response = comprehend.detect_dominant_language(Text=text) + return response['Languages'][0]['LanguageCode'] + + detected_language = None + + async def process_user_input(user_input: str, user_id: str, session_id: str): + global detected_language + if not detected_language: + detected_language = detect_language(user_input) + print(f"Detected language: {detected_language}") + + try: + response = await orchestrator.route_request( + user_input, + user_id, + session_id, + additional_params={"language_code": detected_language} + ) + + print("Processed response:", response) + except Exception as error: + print("Error:", error) + + # Example usage + asyncio.run(process_user_input("Hello, world!", "user123", "session456")) + # Subsequent calls will use the same detected language + asyncio.run(process_user_input("How are you?", "user123", "session456")) + ``` + + + +## Usage with ChainAgent + +This example demonstrates how to use the `ComprehendFilterAgent` as part of a `ChainAgent` configuration: + + + + ```typescript + import { MultiAgentOrchestrator, ChainAgent, ComprehendFilterAgent, BedrockLLMAgent } from 'multi-agent-orchestrator'; + + // Create a ComprehendFilterAgent + const filterAgent = new ComprehendFilterAgent({ + name: 'ContentFilter', + description: 'Filters inappropriate content', + enableSentimentCheck: true, + enablePiiCheck: true, + enableToxicityCheck: true, + sentimentThreshold: 0.7, + toxicityThreshold: 0.6 + }); + + // Create a BedrockLLMAgent (or any other agent you want to use after filtering) + const llmAgent = new BedrockLLMAgent({ + name: 'LLMProcessor', + description: 'Processes filtered content using a language model' + }); + + // Create a ChainAgent that combines the filter and LLM agents + const chainAgent = new ChainAgent({ + name: 'FilteredLLMChain', + description: 'Chain that filters content before processing with LLM', + agents: [filterAgent, llmAgent] + }); + + // Add the chain agent to the orchestrator + const orchestrator = new MultiAgentOrchestrator(); + orchestrator.addAgent(chainAgent); + + // Use the chain + const response = await orchestrator.routeRequest( + "Process this message after ensuring it's appropriate.", + "user123", + "session456" + ); + + if (response) { + console.log("Message processed successfully:", response); + } else { + console.log("Message was filtered out due to inappropriate content"); + } + ``` + + + ```python + from multi_agent_orchestrator.orchestrator import MultiAgentOrchestrator + from multi_agent_orchestrator.agents import ChainAgent, ComprehendFilterAgent, BedrockLLMAgent + from multi_agent_orchestrator.agents import ChainAgentOptions, ComprehendFilterAgentOptions, BedrockLLMAgentOptions + + # Create a ComprehendFilterAgent + filter_agent = ComprehendFilterAgent(ComprehendFilterAgentOptions( + name='ContentFilter', + description='Filters inappropriate content', + enable_sentiment_check=True, + enable_pii_check=True, + enable_toxicity_check=True, + sentiment_threshold=0.7, + toxicity_threshold=0.6 + )) + + # Create a BedrockLLMAgent (or any other agent you want to use after filtering) + llm_agent = BedrockLLMAgent(BedrockLLMAgentOptions( + name='LLMProcessor', + description='Processes filtered content using a language model' + )) + + # Create a ChainAgent that combines the filter and LLM agents + chain_agent = ChainAgent(ChainAgentOptions( + name='FilteredLLMChain', + description='Chain that filters content before processing with LLM', + agents=[filter_agent, llm_agent] + )) + + # Add the chain agent to the orchestrator + orchestrator = MultiAgentOrchestrator() + orchestrator.add_agent(chain_agent) + + # Use the chain + response = await orchestrator.route_request( + "Process this message after ensuring it's appropriate.", + "user123", + "session456" + ) + + if response: + print("Message processed successfully:", response) + else: + print("Message was filtered out due to inappropriate content") + ``` + + + +## Configuration Options + +The `ComprehendFilterAgent` supports the following configuration options: + +- `enableSentimentCheck`: Enable sentiment analysis (default: true) +- `enablePiiCheck`: Enable PII detection (default: true) +- `enableToxicityCheck`: Enable toxicity detection (default: true) +- `sentimentThreshold`: Threshold for negative sentiment (default: 0.7) +- `toxicityThreshold`: Threshold for toxic content (default: 0.7) +- `allowPii`: Allow PII in content (default: false) +- `languageCode`: ISO 639-1 language code for analysis (default: 'en') + +## Supported Languages + +The `ComprehendFilterAgent` supports the following languages: + +'en' (English), 'es' (Spanish), 'fr' (French), 'de' (German), 'it' (Italian), 'pt' (Portuguese), 'ar' (Arabic), 'hi' (Hindi), 'ja' (Japanese), 'ko' (Korean), 'zh' (Chinese Simplified), 'zh-TW' (Chinese Traditional) + +--- + +By leveraging the `ComprehendFilterAgent`, you can implement robust content moderation in your Multi-Agent Orchestrator system, ensuring safe and appropriate interactions while leveraging the power of Amazon Comprehend for advanced content analysis. diff --git a/python/src/multi_agent_orchestrator/agents/chain_agent.py b/python/src/multi_agent_orchestrator/agents/chain_agent.py index 269b833..2f233f8 100644 --- a/python/src/multi_agent_orchestrator/agents/chain_agent.py +++ b/python/src/multi_agent_orchestrator/agents/chain_agent.py @@ -27,12 +27,11 @@ async def process_request( ) -> Union[ConversationMessage, AsyncIterable[any]]: current_input = input_text final_response: Union[ConversationMessage, AsyncIterable[any]] - print(f"Processing chain with {len(self.agents)} agents") for i, agent in enumerate(self.agents): is_last_agent = i == len(self.agents) - 1 try: - print(f"Input for agent {i}: {current_input}") + #print(f"Input for agent {i}: {current_input}") response = await agent.process_request( current_input, user_id, @@ -44,7 +43,7 @@ async def process_request( if response.content and 'text' in response.content[0]: current_input = response.content[0]['text'] final_response = response - print(f"Output from agent {i}: {current_input}") + #print(f"Output from agent {i}: {current_input}") else: Logger.logger.warning(f"Agent {agent.name} returned no text content.") return self.create_default_response() diff --git a/python/src/multi_agent_orchestrator/classifiers/anthropic_classifier.py b/python/src/multi_agent_orchestrator/classifiers/anthropic_classifier.py index 24c9ce7..ce79b21 100644 --- a/python/src/multi_agent_orchestrator/classifiers/anthropic_classifier.py +++ b/python/src/multi_agent_orchestrator/classifiers/anthropic_classifier.py @@ -4,7 +4,8 @@ from multi_agent_orchestrator.utils.logger import Logger from multi_agent_orchestrator.types import ConversationMessage from multi_agent_orchestrator.classifiers import Classifier, ClassifierResult - +import logging +logging.getLogger("httpx").setLevel(logging.WARNING) ANTHROPIC_MODEL_ID_CLAUDE_3_5_SONNET = "claude-3-5-sonnet-20240620" diff --git a/python/src/multi_agent_orchestrator/orchestrator.py b/python/src/multi_agent_orchestrator/orchestrator.py index 7c906c6..2eb8627 100644 --- a/python/src/multi_agent_orchestrator/orchestrator.py +++ b/python/src/multi_agent_orchestrator/orchestrator.py @@ -90,7 +90,7 @@ async def dispatch_to_agent(self, agent_chat_history = await self.storage.fetch_chat(user_id, session_id, selected_agent.id) self.logger.print_chat_history(agent_chat_history, selected_agent.id) - self.logger.info(f"Routing intent '{user_input}' to {selected_agent.id} ...") + #self.logger.info(f"Routing intent '{user_input}' to {selected_agent.id} ...") response = await self.measure_execution_time( f"Agent {selected_agent.name} | Processing request",