Este artículo fue escrito en Colaboration Enrique Rodríguez
Prepárese para embarcarse en un viaje emocionante mientras combinamos el poder de Amazon Bedrock, ReactJS y el AWS JavaScript SDK para crear una aplicación AI generativa con un código de integración mínimo.
La integración de la IA generativa en las aplicaciones existentes presenta desafíos. Muchos desarrolladores tienen una experiencia limitada en los modelos de cimientos de capacitación, pero el objetivo es integrar capacidades generativas de IA con cambios de código mínimos.
Para resolver esto, creamos una aplicación que integra el poder de la IA generativa con una llamada a la API de rock de Amazon a partir de una aplicación web como el spa construido con JavaScript y React Framework. Sin middleware, bajando la barrera para incorporar la generación de IA a través de la integración mínima del código.
A lo largo de este tutorial, aprenderá cómo utilizar las credenciales de Amazon Cognito y los roles IAM para acceder de forma segura a la API de rock de Amazon dentro de su aplicación ReactJS construida con el sistema de diseño de nubes. Lo guiaremos a través del proceso de implementación de todos los recursos necesarios y alojando la aplicación utilizando AWS Amplify, simplificando el proceso de configuración e implementación.
Para mejorar la flexibilidad y la personalización del Modelo de Fundación (FM), demostraremos cómo asignar diferentes roles utilizando el indicador del sistema. Al crear una tabla de Amazon DynamoDB, puede almacenar y recuperar varios roles, lo que le permite administrar y acceder a distintas indicaciones del sistema asociadas con cada papel que desea asignar al FM. Este enfoque de repositorio centralizado permite una asignación de roles dinámico y respuestas de IA personalizadas basadas en el rol seleccionado.

En el repositorio de esta aplicación, encontrará el código listo para implementar el backend y el frontend.
✅ Backend: un grupo de usuarios y un grupo de identidad de Amazon Cognito, con un rol de gerente de identidad y acceso de AWS (rol de IAM) que contiene la política con los permisos para invocar la base de Amazon.
{ policyName: "amplify-permissions-custom-resources",
policyDocument: {
Version: "2012-10-17",
Statement: [
{
Resource: "*",
Action: ["bedrock:InvokeModel*", "bedrock:List*", "bedrock:Retrieve*"],
Effect: "Allow",
}
]
}
}
Verifique la guía y autorización de "integración de Amazon Cognito con aplicaciones web y móviles" para invocar las operaciones de AWS API de los usuarios autenticados con Amazon Cognito.
Estos permisos se pueden personalizar aquí: Código de rol de IAM
✅ Frontend: una aplicación de página única reactjs (SPA) construida con sistema de diseño de nubes.
Esta aplicación comprende 4 demostraciones:

Todas las demostraciones tienen en común el uso de BedrockRuntimeClient o BedrockagentruntimeClient para invocar el sábado o el servicio de rockagent en la base para una interacción conversacional. BedRockAgentClient también se usa para enumerar las bases de conocimiento de la roca madre actual implementada en la misma cuenta.
import { BedrockAgentClient } from "@aws-sdk/client-bedrock-agent"
import { BedrockAgentRuntimeClient } from "@aws-sdk/client-bedrock-agent-runtime"Amazon Bedrock es un servicio totalmente administrado que ofrece una selección de modelos de base de alto rendimiento (FMS) junto con un amplio conjunto de capacidades que necesita para construir y escalar aplicaciones generativas de IA.
Para invocar un FM, debe especificar la región, las respuestas de transmisión y las credenciales de API de la autenticación del grupo de usuarios. Para los argumentos del modelo, especifica el modelo para probar hasta 1000 tokens y para obtener más creativos y libertad de generación, use una temperatura de 1. Lo hacemos con la función getModel de llmlib.js
export const getModel = async ( modelId = "anthropic.claude-instant-v1" ) => {
const session = await fetchAuthSession ( ) ; //Amplify helper to fetch current logged in user
let region = session . identityId . split ( ":" ) [ 0 ] //
const model = new Bedrock ( {
model : modelId , // model-id you can try others if you want
region : region , // app region
streaming : true , // this enables to get the response in streaming manner
credentials : session . credentials , // the user credentials that allows to invoke bedrock service
// try to limit to 1000 tokens for generation
// temperature = 1 means more creative and freedom
modelKwargs : { max_tokens_to_sample : 1000 , temperature : 1 } ,
} ) ;
return model ;
} ; Para seleccionar el ModelID primero enumere los modelos de Amazon Bedrock Foundation utilizando ListFoundationModels en la función getFMs (LLMLIB.JS). Cada FM tiene su propia forma de invocar el modelo, y este blog solo se centra en los modelos multimodales de antrópico.
export const getFMs = async ( ) => {
const session = await fetchAuthSession ( )
let region = session . identityId . split ( ":" ) [ 0 ]
const client = new BedrockClient ( { region : region , credentials : session . credentials } )
const input = { byProvider : "Anthropic" , byOutputModality : "TEXT" , byInferenceType : "ON_DEMAND" }
const command = new ListFoundationModelsCommand ( input )
const response = await client . send ( command )
return response . modelSummaries
}Este código le permite elegir entre el soneto Antrópico Claude 3 o Haiku.

Te guiaremos a través de cada grupo de demostración para resaltar sus diferencias.

InvokEmodelwithResponseSteam se usa para invocar el modelo de rock de Amazon para ejecutar inferencia utilizando los parámetros de solicitud e inferencia proporcionados en el cuerpo de solicitud.
const session = await fetchAuthSession ( )
let region = session . identityId . split ( ":" ) [ 0 ]
const client = new BedrockRuntimeClient ( { region : region , credentials : session . credentials } )
const input = {
body : JSON . stringify ( body ) ,
contentType : "application/json" ,
accept : "application/json" ,
modelId : modelId
}
const command = new InvokeModelWithResponseStreamCommand ( input )
const response = await client . send ( command ) En el blog anterior, hicimos referencia a dos enfoques para invocar el modelo: uno se centró en simplemente hacer preguntas y recibir respuestas, y otro para realizar conversaciones completas con el modelo. Con Anthrope Claude 3, la conversación es manejada por los mensajes api: messages=[{"role": "user", "content": content}] .
Cada mensaje de entrada debe ser un objeto con un role (usuario o asistente) y contenido. El content puede estar en una sola cadena o en una matriz de bloques de contenido, cada bloque que tiene su propio type designado (texto o imagen).
type text igual: {"role": "user", "content": [{"type": "text", "text": "Hello, Claude"}]}

type image igual: {"role": "user", "content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "/9j/4AAQSkZJRg...",
}
},
{"type": "text", "text": "What is in this image?"}
]}

Este es un ejemplo de un cuerpo:
content = [
{"type": "image", "source": {"type": "base64",
"media_type": "image/jpeg", "data": content_image}},
{"type":"text","text":text}
]
body = {
"system": "You are an AI Assistant, always reply in the original user text language.",
"messages":content,"anthropic_version": anthropic_version,"max_tokens":max_tokens}
? ️ Anthrope actualmente admite el tipo de origen base64 para imágenes, y los tipos de imágenes de imágenes/jpeg, imagen/png, imagen/gif y imagen/webp. Puede ver la conversión de imágenes a Base64 para esta aplicación en la función
buildContentde MessageHelpers.js. Ver más ejemplos de entrada.

La API de mensajes nos permite agregar contexto o instrucciones al modelo a través de un mensaje de sistema (sistema).
Al utilizar el indicador del sistema, podemos asignar el FM un rol específico o proporcionarle instrucciones anteriores antes de alimentarla en la entrada. Para habilitar el FM para asumir múltiples roles, creamos un componente React que le permite generar un indicador del sistema, almacenarlo en una tabla de Amazon DynamoDB y luego seleccionarlo cuando desee asignar ese papel particular al FM.
Todas las operaciones de API para administrar las indicaciones se manejan mediante un punto final API de AWS AppSync GraphQL. AWS AppSync le permite crear y administrar API GraphQL, que proporcionan una forma flexible y eficiente de obtener y manipular datos de múltiples fuentes a través de un solo punto final. (Tutorial de AWS AppSync: Dynamodb Resolvers)

Revisemos un ejemplo de un mensaje en el que le decimos al FM que es un experto en JavaScript:

En el siguiente GIF, el modelo proporciona código y una explicación detallada, como un experto.

En esta demostración, hará preguntas a las bases de conocimiento para el lecho de roca de Amazon aprovechando la generación de recuperación aumentada (RAG). Debe tener al menos una base de conocimiento creada, hágalo siguiendo Crear una guía de base de conocimiento.
Se harán preguntas a las bases de conocimiento para Amazon Bedrock de dos maneras:

- Amazon Bedrock Remieve => LLM:

Enumere las bases de conocimiento con ListknowledgeBassCommand de la siguiente manera:
import { ListKnowledgeBasesCommand } from "@aws-sdk/client-bedrock-agent"
export const getBedrockKnowledgeBases = async ( ) => {
const session = await fetchAuthSession ( )
let region = session . identityId . split ( ":" ) [ 0 ]
const client = new BedrockAgentClient ( { region : region , credentials : session . credentials } )
const command = new ListKnowledgeBasesCommand ( { } )
const response = await client . send ( command )
return response . knowledgeBaseSummaries
}La clase Langchain Langchain de Amazon KnowledgeBaseretriever crea un retriever, un objeto capaz de recuperar documentos similares a una consulta de una base de conocimiento (en este caso es una base de conocimiento de Bedrock)
import { AmazonKnowledgeBaseRetriever } from "@langchain/community/retrievers/amazon_knowledge_base" ;
export const getBedrockKnowledgeBaseRetriever = async ( knowledgeBaseId ) => {
const session = await fetchAuthSession ( ) ;
let region = session . identityId . split ( ":" ) [ 0 ]
const retriever = new AmazonKnowledgeBaseRetriever ( {
topK : 10 , // return top 10 documents
knowledgeBaseId : knowledgeBaseId ,
region : region ,
clientOptions : { credentials : session . credentials }
} )
return retriever
}El Conversational Revalqachain se instancia con el Retriever y la memoria. Se encarga de la memoria, consulta el retriever y formula la respuesta (con los documentos) utilizando la instancia de LLM.
import { ConversationalRetrievalQAChain } from "langchain/chains" ;
export const getConversationalRetrievalQAChain = async ( llm , retriever , memory ) => {
const chain = ConversationalRetrievalQAChain . fromLLM (
llm , retriever = retriever )
chain . memory = memory
//Here you modify the default prompt to add the Human prefix and Assistant suffix needed by Claude.
//otherwise you get an exception
//this is the prompt that uses chat history and last question to formulate a complete standalone question
chain . questionGeneratorChain . prompt . template = "Human: " + chain . questionGeneratorChain . prompt . template + "nAssistant:"
// Here you finally answer the question using the retrieved documents.
chain . combineDocumentsChain . llmChain . prompt . template = `Human: Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
{context}
Question: {question}
Helpful Answer:
Assistant:`
return chain
} 
Código bedrockkbretrieve.jsx
- Bedrock de Amazon Recuperar y generar:
Aquí utilizará un servicio completo de trapo administrado AWS. No hay necesidad de paquetes adicionales (Langchain) o una mayor complejidad con las indicaciones. Utilizará solo una llamada API a BedRockAgentRuntimeclient . Además, la memoria es administrada por el Servicio mediante un SessionID .

Bedrock se inicializa con BedRockAgentRuntimeClient y con consultas de recuperación y consultas de Command, una base de conocimiento y un modelo de base genera respuestas basadas en los resultados recuperados. En esta demostración, Langchain no es necesario.
import { BedrockAgentRuntimeClient , RetrieveAndGenerateCommand } from "@aws-sdk/client-bedrock-agent-runtime"
export const ragBedrockKnowledgeBase = async ( sessionId , knowledgeBaseId , query , modelId = "anthropic.claude-instant-v1" ) => {
const session = await fetchAuthSession ( )
let region = session . identityId . split ( ":" ) [ 0 ]
const client = new BedrockAgentRuntimeClient ( { region : region , credentials : session . credentials } ) ;
const input = {
input : { text : query } , // user question
retrieveAndGenerateConfiguration : {
type : "KNOWLEDGE_BASE" ,
knowledgeBaseConfiguration : {
knowledgeBaseId : knowledgeBaseId ,
//your existing KnowledgeBase in the same region/ account
// Arn of a Bedrock model, in this case we jump to claude 2.1, the latest. Feel free to use another
modelArn : `arn:aws:bedrock: ${ region } ::foundation-model/ ${ modelId } ` , // Arn of a Bedrock model
} ,
}
}
if ( sessionId ) {
// you can pass the sessionId to continue a dialog.
input . sessionId = sessionId
}
const command = new RetrieveAndGenerateCommand ( input ) ;
const response = await client . send ( command )
return response
} 
Código BedRockkBandGenerate.jsx
Un agente de rock de Amazon es un componente de software que utiliza los modelos AI proporcionados por el servicio de rock de Amazon para ofrecer funcionalidades orientadas al usuario, como chatbots, asistentes virtuales o herramientas de generación de texto. Estos agentes se pueden personalizar y adaptarse a las necesidades específicas de cada aplicación, proporcionando una interfaz de usuario para que los usuarios finales interactúen con las capacidades de IA subyacentes. Los agentes de base manejan la integración con los modelos de lenguaje, procesan las entradas de los usuarios, la generación de respuestas y potencialmente otras acciones basadas en la salida de los modelos AI.
Para integrar los agentes de la roca madre de Amazon en esta aplicación, debe crear uno, siga los pasos Crear un agente en Amazon Bedrock
En Amazon Bedrock, puede crear una nueva versión de su agente creando un alias que apunte a la nueva versión de forma predeterminada, los alias se enumeran con ListagentaliasScommand (llmlib.js):
import { BedrockAgentClient , ListAgentAliasesCommand } from "@aws-sdk/client-bedrock-agent" ;
const client = new BedrockAgentRuntimeClient ( { region : region , credentials : session . credentials } )
export const getBedrockAgentAliases = async ( client , agent ) => {
const agentCommand = new ListAgentAliasesCommand ( { agentId : agent . agentId } )
const response = await client . send ( agentCommand )
return response . agentAliasSummaries
}Para enviar un mensaje para que el agente procese y responda, use InvokeAgentCommand
import { BedrockAgentRuntimeClient , InvokeAgentCommand } from "@aws-sdk/client-bedrock-agent-runtime" ;
export const invokeBedrockAgent = async ( sessionId , agentId , agentAlias , query ) => {
const session = await fetchAuthSession ( )
let region = session . identityId . split ( ":" ) [ 0 ]
const client = new BedrockAgentRuntimeClient ( { region : region , credentials : session . credentials } )
const input = {
sessionId : sessionId ,
agentId : agentId ,
agentAliasId : agentAlias ,
inputText : query
}
console . log ( input )
const command = new InvokeAgentCommand ( input )
const response = await client . send ( command , )
console . log ( "response:" , response )
let completion = ""
let decoder = new TextDecoder ( "utf-8" )
for await ( const chunk of response . completion ) {
console . log ( "chunk:" , chunk )
const text = decoder . decode ( chunk . chunk . bytes )
completion += text
console . log ( text )
}
return completion
}En el agente de este primer GIF, cree un boleto para soporte técnico:

En el segundo GIF, el usuario pregunta al agente sobre el estado del boleto:

La aplicación está construida con AWS Amplify. Para implementarlo en su cuenta:
https://github.com/build-on-aws/building-reactjs-gen-ai-apps-with-amazon-bedrock-javascript-sdk/forks
Crea una nueva rama: dev-branch .
Luego siga los pasos para comenzar con la guía de código existente.
En el paso 1, agregue la rama del repositorio , seleccione la rama principal y conecte un monorreo? Elija una carpeta e ingrese reactjs-gen-ai-apps como directorio raíz.

building-a-gen-ai-gen-ai-personal-assistant-reactjs-apps(this app) como nombre de la aplicación, en entorno Seleccione Crear un nuevo envitomente y escribir dev 
Si no hay un papel existente, cree uno nuevo para amplificar el servicio.
Implementa tu aplicación.
Una vez que se haya implementado la aplicación, vaya al enlace de la aplicación, que se encuentra debajo de la caja blanca.

Cuando ingrese el enlace, aparecerá el Sing in Window, por lo que debe crear un usuario de Amazon Cognito User Pool.

En la aplicación, vaya a entornos de backend y haga clic en la autenticación.

Luego, en autenticación, haga clic en Ver en Cognito :

En el grupo de usuarios , haga clic en el nombre de su grupo de usuarios y cree usuario .
Crea tu usuario y luego canta.
Nota: Puede crear el usuario directamente desde la aplicación cambiando False
hideSignUp: falseen App.jsx, pero esto puede introducir una falla de seguridad al darle acceso a cualquiera.
Antes de que pueda usar un modelo de base en Amazon Bedrock, debe solicitar acceso a él. Siga el paso en la guía de acceso del modelo Agregar.
Vaya al enlace de la aplicación e inicie sesión con el usuario que creó.
En esta publicación, demostramos cómo puede construir una aplicación web React que acceda directamente a la API de rock de Amazon con Amazon Cognito para una autenticación segura. Al aprovechar los servicios administrados de AWS como Cognito e IAM, puede integrar sin problemas potentes capacidades de IA generativas en sus aplicaciones JavaScript sin la necesidad de código de backend.
Este enfoque permite a los desarrolladores centrarse en crear experiencias conversacionales comunicativas mientras aprovecha el servicio de conocimiento administrado de Amazon Bedrock. Las respuestas de transmisión mejoran la experiencia del usuario al reducir los tiempos de espera y permitir interacciones más naturales con la IA conversacional.
Además, mostramos cómo puede asignar múltiples roles al modelo de base utilizando indicaciones del sistema almacenadas en una tabla de Amazon DynamoDB. Este repositorio centralizado proporciona flexibilidad y versatilidad, lo que le permite recuperar y asignar eficientemente roles distintos al modelo basado en su caso de uso específico.
Siguiendo los pasos descritos en esta publicación, puede desbloquear el potencial de la IA generativa en sus aplicaciones React. Ya sea que esté construyendo una nueva aplicación desde cero o mejorando una existente, Amazon Bedrock y el AWS JavaScript SDK hacen que sea más fácil que nunca incorporar capacidades de IA de vanguardia.
Le recomendamos que explore las muestras de código y los recursos proporcionados para comenzar a construir sus propias aplicaciones generativas de IA. Si tiene alguna pregunta o comentarios, deje un comentario a continuación. ¡Feliz codificación!
Ver contribuyendo para más información.
Esta biblioteca tiene licencia bajo la licencia MIT-0. Ver el archivo de licencia.