Agentes Bedrock: Resumen de memoria, límites versionados y base de conocimientos.
Controles de agente Bedrock impulsados por Terraform: memoria de sesión con un prompt personalizado para resumir, límites versionados con implementación por detección y bloqueo, y RAG respaldado en S3.
Fuentes: 6A. Building Chat Agent with AWS Bedrock and Terraform: Summary, Knowledge Base, and Guardrails
Fallas que no generan sonido
Pueden ocurrir muchos problemas en un sistema de agentes de IA, y las peores fallas no generan errores ni activan alertas. La calidad simplemente disminuye. La memoria de sesión acumula ruido en lugar de señales útiles, las reglas de seguridad se encuentran fuera del control de versiones, y el agente utiliza herramientas para obtener contenido que una base de conocimientos podría proporcionar directamente.
Tres elementos abordan esos problemas en Amazon Bedrock: una sobrescritura de MEMORY_SUMMARIZATION que mantiene las señales útiles del usuario a lo largo de las sesiones, una regla de seguridad Bedrock versionada en Terraform, y una base de conocimientos opcional respaldada por S3.
La ingeniería de prompts no puede asumir toda la carga. Los sistemas reales necesitan controles en tres lugares:
- Calidad de la memoria de sesión. Los resúmenes deben conservar las señales adecuadas del usuario.
- Gobernanza de seguridad. Las reglas de seguridad deben ser claras y versionadas.
Sin ellas, un sistema tiende a parecer estable en las demostraciones y luego degradarse una vez llega tráfico real y variado.
Cómo funciona la memoria de sesión
La resumen de la memoria mantiene el historial de un usuario disponible de una sesión a otra, de modo que no es necesario extraer y procesar nuevamente los mensajes antiguos en tiempo real. En los Agentes Clásicos, Bedrock ofrece una forma básica a través de enabled_memory_types = ["SESSION_SUMMARY"] en aws_bedrockagent_agent, y GetAgentMemory en el Entorno de Ejecución del Agente lee lo que está almacenado.
Con la memoria habilitada, el procesamiento se realiza de forma asíncrona después de que finalice una sesión. Bedrock resume la conversación completada, almacena ese resumen e lo incorpora en sesiones posteriores que comparten el mismo memoryId, todo ello sin retrasar la respuesta del usuario.
Bedrock incluye un prompt por defecto que define el comportamiento de la resumen:
{
"messages": [
{
"role" : "user",
"content" : "We will be given a conversation between a user and an AI
assistant.
When available, in order to have more context, we will also be given
summaries we previously generated.
Our goal is to summarize the input conversation.
When we generate summaries we ALWAYS follow the below guidelines:
<guidelines>
- Each summary MUST be formatted in XML format.
- Each summary must contain at least the following topics: 'user
goals', 'assistant actions'.
- Each summary, whenever applicable, MUST cover every topic and be
placed between <topic name='$TOPIC_NAME'></topic>.
- We ALWAYS output all applicable topics within <summary></summary>
- If nothing about a topic is mentioned, DO NOT produce a summary
for that topic.
- We summarize in <topic name='user goals'></topic> ONLY what is
related to the user, e.g., user goals.
- We summarize in <topic name='assistant actions'></topic> ONLY what
is related to the assistant, e.g., assistant actions.
- NEVER start with phrases like 'Here's the summary...', provide
directly the summary in the format described below.
</guidelines>The XML format of each summary is as follows:
<summary>
<topic name='$TOPIC_NAME'>
...
</topic>
...
</summary>
Here is the list of summaries we previously generated.
<previous_summaries>
$past_conversation_summary$
</previous_summaries>
And here is the current conversation session between a user and an AI
assistant:
<conversation>
$conversation$
</conversation>
Please summarize the input conversation following the above guidelines
plus the below additional guidelines:
<additional_guidelines>
- ALWAYS strictly follow the above XML schema and ALWAYS generate
well-formatted XML.
- NEVER forget any detail from the input conversation.
- We also ALWAYS follow the below special guidelines for some of the topics.
<special_guidelines>
<user_goals>
- We ALWAYS report in <topic name='user goals'></topic> all details the user
provided in formulating their request.
</user_goals>
<assistant_actions>
- We ALWAYS report in <topic name='assistant actions'></topic> all details
about actions taken by the assistant, e.g., parameters used to invoke actions.
</assistant_actions>
</special_guidelines>
</additional_guidelines>"
}
]
}
Sus instrucciones se encuentran principalmente en la sección <guidelines/>, la cual indica al agente que devuelva su resultado dentro de una etiqueta <summary/>. El resumen está dividido por temas: todo lo relacionado con los objetivos del usuario se incluye en el tema llamado user goals, las acciones propias del agente se ubican en assistant actions, y cada tema utiliza un contenedor <topic name='$TOPIC_NAME'></topic>. La salida esperada se ve así:
<summary>
<topic name='$TOPIC_NAME'>
...
</topic>
...
</summary>
Bedrock rellena <previous_summaries/> con resúmenes anteriores a través de la variable $past_conversation_summary$, y la conversación en tiempo real se muestra dentro de <conversation>$conversationlt;/conversation>. Otras dos secciones, <additional_guidelines/> y <special_guidelines/>, permiten añadir detalles a la estrategia de resumen.
El ciclo de vida es el siguiente:
- La memoria se activa en la configuración del agente con
memory_configurationyenabled_memory_types = ["SESSION_SUMMARY"]. - El usuario invoca al agente con un
memoryIdúnico para cada usuario. - La sesión finaliza ya sea mediante
endSession = trueo por tiempo de espera. - Bedrock genera el resumen en segundo plano.
memoryId, Bedrock coloca el contexto de memoria en marcadores de orquestación como $memory_content$.Surgen dos consecuencias. Los resúmenes no son instantáneos y pueden aparecer algún tiempo después de que se cierre una sesión. Además, si el memoryId cambia de solicitud en solicitud, se pierde la continuidad.
Advertencia: Los valores inestables de
memoryId, como los IDs de conexión a los que pertenecen los IDs de usuario, interrumpen la continuidad de la memoria. Utilice un identificador que permanezca fijo para cada usuario o entidad de conversación.
Hacer que los resúmenes sean útiles
El resumen por defecto es un resumen genérico. Eso está bien para un asistente general, pero a menudo resulta demasiado detallado para uno especializado. En el caso de un pequeño asistente de noticias, un resumen sólido debe incluir:
- temas recurrentes como noticias sobre IA, clima o geopolítica;
Sin esa estructura, la memoria aumenta mientras la relevancia disminuye.
Para habilitarla, se debe comenzar con el recurso agent en Terraform:
resource "aws_bedrockagent_agent" "agent" {
# ... existing code above ...
memory_configuration {
enabled_memory_types = ["SESSION_SUMMARY"]
storage_days = 30
session_summary_configuration {
max_recent_sessions = 5
}
}
# ... existing code below ...
}
Los agentes de Bedrock aceptan únicamente el tipo SESSION_SUMMARY aquí. AgentCore va más allá, ya que incluye resúmenes, preferencias del usuario, hechos semánticos y estrategias de memoria personalizadas. storage_days determina cuánto tiempo se conservan los resúmenes, mientras que max_recent_sessions controla cuántas sesiones recientes se resumen.
Cada llamada debe incluir un memoryId, que en este caso es el user_id, para que las conversaciones estén vinculadas a la misma entidad:
# Invoke with stable memoryId and explicit session end
resp = bedrock_agent_runtime.invoke_agent(
agentId=agent_id,
agentAliasId=alias_id,
sessionId=conversation_id,
memoryId=user_id, # stable per user
inputText=message_text,
endSession=is_last_turn
)
La recuperación utiliza el mismo memoryId:
# Retrieve summaries later (classic Agents API)
memory = bedrock_agent_runtime.get_agent_memory(
agentId=agent_id,
agentAliasId=alias_id,
memoryId=user_id,
memoryType="SESSION_SUMMARY"
)
Sobrescribir la instrucción de resumen
Con la memoria activada, Bedrock permite que una instrucción de sobrescripción reemplace la etapa MEMORY_SUMMARIZATION: se cambia prompt_type = "MEMORY_SUMMARIZATION" por prompt_creation_mode = "OVERRIDDEN". Los agentes clásicos utilizan dos marcadores especiales: $past_conversation_summary$ para los resúmenes almacenados vinculados a la misma identidad de memoria, y $conversation$ para el texto de la sesión actual. En las plantillas de orquestación, el contexto de memoria se expresa a través de $memory_guideline$ para la estrategia, $memory_content$ para la persistencia y $memory_action_guideline$ para las instrucciones del sistema.
Una versión personalizada de la instrucción predeterminada especifica qué debe capturar el agente y qué debe ignorar, de modo que solo queden los detalles útiles:
prompt_override_configuration {
prompt_configurations = [{
prompt_type = "MEMORY_SUMMARIZATION"
prompt_state = "ENABLED"
prompt_creation_mode = "OVERRIDDEN"
parser_mode = "DEFAULT"
base_prompt_template = <<-JSON
{
"system": "
We are summarizing a news research conversation for future sessions.
Capture:
- recurring topics,
- region focus,
- entities and stories the user tracks,
- explicit dislikes.
Ignore:
- greetings and small talk,
- implementation questions about the assistant itself.
Past summaries:
<previous_summaries>
$past_conversation_summary$
</previous_summaries>
Current session:
<conversation>
$conversation$
</conversation>
Return concise bullet points focused on user signal.",
"messages": [
{
"role": "user",
"content": [{ "text": "Generate a focused memory summary for personalization." }]
}
]
}
JSON
inference_configuration = [{
temperature = 0.2
top_k = 64
top_p = 0.9
max_length = 512
stop_sequences = []
}]
# ... existing code below ...
}
]
}
Sobrescriba la etapa cuando un resumen genérico no mejore las respuestas posteriores, cuando los resúmenes necesiten una alta relación señal-ruido, o cuando el presupuesto de tokens de memoria debe mantenerse ajustado y predecible. Si el asistente es genérico y no depende de la personalización, el valor predeterminado es adecuado.
Los errores típicos incluyen:
- valores inestables de
memoryId, como cuando los IDs de conexión sustituyen a los IDs de usuario; - sesiones que nunca terminan, por lo que nunca se genera ningún resumen;
- peticiones de resumen demasiado detalladas que reconstruyen prácticamente todo el transcripción completo;
- mezclar objetivos de resumen con objetivos de formato destinados al procesamiento posterior.
Límites: políticas que las peticiones no pueden imponer
A veces los usuarios son groseros, utilizan mal al asistente o piden detalles internos, secretos y datos personales de otras personas. Las medidas de control se encargan de eso. El principio es sencillo: los prompts guían el comportamiento, mientras que las medidas de control hacen cumplir la política. Utilice los prompts para tomar decisiones y formatear, y las medidas de control para establecer límites de seguridad en el contenido tanto de la entrada del usuario como de la salida del asistente.
Consejo: Pruebe las medidas de control en modo DETECT antes que en modo BLOCK. Auditando lo que se habría detenido no afecta a los testers.
Bedrock incluye varias capacidades de control que no requieren configuración adicional más allá de agregarlas a la lista:
- Filtros de contenido que abordan el odio, los insultos, la violencia, el contenido sexual, las conductas inapropiadas y los ataques mediante prompts, con niveles de efectividad tanto en la entrada como en la salida y las acciones correspondientes. Son ideales para garantizar una seguridad básica constante en el tráfico de usuarios habituales.
La mayoría de los equipos obtienen mejores resultados implementándolo por fases: primero filtros de contenido e información sensible, luego filtros de temas y palabras, y finalmente mecanismos de fundamentación y razonamiento una vez que las políticas de recuperación estén maduras.
Orden de evaluación
Las medidas de control examinan ambas direcciones:
- Entrada. Primero se evalúa la solicitud del usuario, con todas las políticas configuradas ejecutándose en paralelo. Un bloque hace que Bedrock devuelva
blocked_input_messagingy omita la inferencia. - Salida. Cuando la entrada pasa la verificación, el modelo responde y su salida se examina. Un bloque reemplaza la respuesta por
blocked_outputs_messaging, o la enmascara si están configurados filtros de información sensible.
El orden es importante para el costo. Una entrada bloqueada solo genera costos por la evaluación de las medidas de protección y no por la inferencia del modelo.
Cada filtro de contenido tiene dos configuraciones independientes. Fuerza (inputStrength y outputStrength) puede tomar los valores NINGUNO, BAJA, MEDIA o ALTA y controla cuán agresivamente se detectan las infracciones. Acción (inputAction y outputAction) puede ser BLOQUEAR, lo que impide el contenido y sustituye la comunicación bloqueada, o NINGUNO, que no hace nada más que registrar las detecciones en las respuestas de seguimiento, lo que equivale a un modo exclusivamente de detección.
Una estrategia predeterminada sensata:
- Comience con
MEDIUMen las categorías de alto riesgo como el odio, la violencia y las conductas inapropiadas, tanto para la entrada como para la salida; - En pruebas o entornos de preparación, empiece con
outputAction = "NONE"para poder contar los falsos positivos; - Pasé a
BLOCKsolo después de que los resultados de las pruebas y los rastros parezcan aceptables; - Mantenga las categorías de bajo riesgo en
LOWoMEDIUM, y no establezca todo enHIGHdesde el primer día.
Los filtros de contenido también existen en dos niveles de protección. CLASSIC es el filtrado básico, mientras que STANDARD ofrece una protección más sólida con análisis del dominio del código y soporte para categorías de ataques por prompts. Un asistente que maneja prompts al estilo de desarrollador, fragmentos de código o texto mezclado con código suele ser más seguro en el modo Standard.
Versionado
Las actualizaciones de las reglas de protección deben ser explícitas e inmutables, y cada cambio en la política debe convertirse en una nueva versión. aws_bedrock_guardrail_version permite esto: se crea una versión y se la asocia a aws_bedrock_guardrail a través de guardrail_configuration.
resource "aws_bedrock_guardrail" "guardrail" {
name = "${var.environment}-news-guardrail"
description = "Safety policies for news assistant"
blocked_input_messaging = "Your request violates our usage policy."
blocked_outputs_messaging = "This response was blocked by our safety policy."
content_policy_config {
filters_config {
type = "HATE"
input_strength = "MEDIUM"
output_strength = "MEDIUM"
}
filters_config {
type = "VIOLENCE"
input_strength = "MEDIUM"
output_strength = "MEDIUM"
}
filters_config {
type = "MISCONDUCT"
input_strength = "MEDIUM"
output_strength = "MEDIUM"
}
}
}
resource "aws_bedrock_guardrail_version" "guardrail_version" {
guardrail_arn = aws_bedrock_guardrail.guardrail.guardrail_arn
description = "release-${substr(sha256(var.guardrail_policy_fingerprint), 0, 12)}"
skip_destroy = true
}
resource "aws_bedrockagent_agent" "news_agent" {
# ... instruction, model, prompt overrides ...
guardrail_configuration {
guardrail_identifier = aws_bedrock_guardrail.guardrail.guardrail_id
guardrail_version = aws_bedrock_guardrail_version.guardrail_version.version
}
# ... existing code below ...
}
Esta división permite una reversión limpia. Los mensajes de confirmación permanecen tal como están, y solo la versión con protección se modifica cuando es necesario ajustar la política.
Base de conocimientos para contenido interno
Supongamos que el agente debe responder basándose en las políticas de la empresa o en el conocimiento acumulado con el tiempo, evitando llamadas a herramientas innecesarias. Bedrock utiliza una base de conocimientos asociada para generar respuestas a partir de documentos recuperados, y está activa por defecto una vez que se configura. Permite a los agentes conectarse de forma segura a datos privados de la empresa, de modo que los modelos base ofrezcan respuestas más relevantes, precisas y personalizadas a través de la Generación Aumentada por Recuperación de Información (RAG).
Es adecuado cuando la fuente de verdad son documentos internos o curados, cuando no se necesita actualización en tiempo real, o cuando se requieren respuestas fundamentadas con trazabilidad similar a citas.
Nota: La información indexada externamente en tiempo real se maneja mejor con herramientas API.
Bedrock Knowledge Base funciona como un pipeline RAG gestionado para su propio contenido. En lugar de construir la infraestructura de recuperación por sí mismo, permite que Bedrock reciba datos desde un conector, analice y divida los documentos en fragmentos, cree embeddings, almacene los vectores en un almacenamiento compatible y obtenga los fragmentos relevantes cuando llega una solicitud. Durante KNOWLEDGE_BASE_RESPONSE_GENERATION, esos fragmentos sirven para generar respuestas basadas en datos reales.
Hay dos flujos involucrados. La ingestión se ejecuta sin conexión o en modo sincronización: los documentos se analizan, se dividen en fragmentos según la estrategia de particionamiento, se convierten en vectores mediante un modelo de incrustación y se escriben en un índice de vectores con mapeos de metadatos. La recuperación en tiempo de ejecución se realiza por solicitud: la consulta se incrusta, el almacén de vectores devuelve fragmentos semánticamente relevantes, Bedrock los agrega al contexto del modelo y la fase de generación produce un resultado fundamentado; en los patrones de solo recuperación, se obtienen simplemente los resultados.
La partición tiene un significado operativo, ya que una mala calidad de recuperación suele ser un problema de ingestión o de particionamiento, y no un problema del prompt.
Nada se “inserta como fila” como en un caché SQL. Se añaden o actualizan archivos, o fuentes respaldadas por conectores, y luego se ejecuta sincronización.
Advertencia: La sincronización no es automática. Después de agregar documentos a S3, hay que activarla explícitamente antes de que el agente pueda recuperarlos.
Controles en tiempo de ejecución
numberOfResultsdetermina cuántos fragmentos de origen se devuelven (por defecto hasta 5, rango de 1 a 100).overrideSearchTypepermite elegirSEMANTICpara búsquedas únicamente vectoriales oHYBRIDpara búsquedas vectoriales además de búsquedas en texto sin procesar; esta opción solo está disponible en almacenes e índices compatibles. Si no se especifica, Bedrock elige automáticamente.- El
filterde metadatos y los grupos lógicos (andAll,orAll) permiten una recuperación precisa. - Un reordenamiento opcional mejora el orden final de los fragmentos.
Con la partición jerárquica, la cantidad de resultados puede ser menor a la solicitada, ya que los fragmentos hijos pueden ser reemplazados por sus padres en el momento de la respuesta.
Fragmentación
La fragmentación afecta significativamente la calidad de la recuperación. Bedrock ofrece una fragmentación predeterminada de unos 300 tokens en los límites de las oraciones, fragmentación de tamaño fijo con tamaño y solapamiento de tokens explícitos, fragmentos jerárquicos padre e hijo para mayor precisión y un contexto más amplio, fragmentación semántica con límites definidos por el modelo, y ninguna fragmentación, que trata cada documento como un único fragmento y es adecuada principalmente para contenido ya segmentado.
Un enfoque razonable: comenzar con la fragmentación predeterminada o de tamaño fijo, ya que es sencilla. Pasar a la jerárquica cuando las respuestas necesiten más contexto circundante, y a la semántica si la precisión sigue siendo baja después del ajuste del prompt. Comparar con un conjunto de evaluación de recuperación antes y después de cada cambio.
Almacenes de vectores
Las bases de conocimiento funcionan con varios backends vectoriales, como OpenSearch Serverless o un clúster gestionado, Aurora compatible con PostgreSQL, Pinecone, Redis Enterprise Cloud, MongoDB Atlas y Neptune Analytics, dependiendo del soporte del proveedor en el momento de la implementación. La elección afecta a la existencia de búsquedas HÍBRIDAS, a los filtros de metadatos posibles, así como a la complejidad operativa y al costo. OpenSearch Serverless suele ser la opción más rápida para comenzar. A continuación se muestra un ejemplo de configuración con Terraform:
resource "aws_bedrockagent_knowledge_base" "news_kb" {
name = "${var.environment}-news-kb"
role_arn = aws_iam_role.bedrock_execution_role.arn
knowledge_base_configuration {
type = "VECTOR"
vector_knowledge_base_configuration {
embedding_model_arn = "arn:aws:bedrock:${data.aws_region.current.name}::foundation-model/amazon.titan-embed-text-v2:0"
}
}
storage_configuration {
type = "OPENSEARCH_SERVERLESS"
opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.kb.arn
vector_index_name = "news-kb-index"
field_mapping {
vector_field = "vector"
text_field = "text"
metadata_field = "metadata"
}
}
}
# ... existing code below ...
}
resource "aws_bedrockagent_data_source" "news_docs" {
knowledge_base_id = aws_bedrockagent_knowledge_base.news_kb.id
name = "${var.environment}-news-docs"
data_source_configuration {
type = "S3"
s3_configuration {
bucket_arn = aws_s3_bucket.news_docs.arn
}
}
# ... existing code below ...
}
resource "aws_bedrockagent_agent_knowledge_base_association" "news_agent_kb" {
agent_id = aws_bedrockagent_agent.agent[0].agent_id
agent_version = "DRAFT"
knowledge_base_id = aws_bedrockagent_knowledge_base.news_kb.id
description = "Internal news assistant knowledge base for curated context and editorial guidelines"
knowledge_base_state = "ENABLED"
# ... existing code below ...
}
Ruteo entre la base de conocimientos y las herramientas
Al asociar una base de conocimientos, el agente dispone de un segundo camino para recuperar información. Para evitar ambigüedades, incluya las reglas de ruteo para la base de conocimientos frente a la herramienta API en el comando de orquestación, mantenga idéntico el contrato POST_PROCESSING independientemente de cuál fuente haya respondido, y especifique cuándo el agente debe hacer preguntas de aclaración debido a una baja confianza en la recuperación de datos.
Una política práctica para esta configuración: utilice la base de conocimientos para contextos internos y estáticos como documentos de políticas, estándares editoriales y notas históricas; utilice el grupo de acciones para datos externos en tiempo real; y no invoque ambos en una sola acción a menos que la solicitud requiera realmente una verificación cruzada.
Las medidas de seguridad también se aplican en las operaciones de recuperación y generación, lo cual es importante porque la recuperación basada en datos concretos no elimina por sí sola los riesgos de seguridad. Una recomendación común es evaluar primero el camino hacia la base de conocimientos con estas medidas en modo de detección, ajustar los falsos positivos y negativos a partir de las huellas generadas, y luego pasar a la bloqueo o enmascaramiento en entornos de producción.
Introducción del contenido
- Corpus inicial: para cargar una sola vez políticas, Preguntas Frecuentes y guías de estilo, suba los archivos al bucket S3 conectado a la fuente de datos e inicie una sincronización.
- Actualizaciones continuas: cuando el texto del producto o legal cambia según un calendario, una tarea nocturna puede subir nuevos archivos a S3 y activar
StartIngestionJobpara la fuente de datos, o recurrir a la sincronización automática si está habilitada.
kb/topics/eu-ai-act-overview.md, de modo que los límites de los fragmentos coincidan con los temas y las citaciones sean más claras que en un único PDF enorme.StartIngestionJob para que la base de conocimientos recoja los nuevos objetos.Problemas comunes
- Tratar la base de conocimientos como una fuente en tiempo real. Solo está tan actualizada como lo permita el horario de sincronización de la ingesta.
- Fragmentar el contenido en demasiados o demasiados pocos segmentos, lo que afecta la precisión.
- Metadatos deficientes, lo que hace que los filtros sean inútiles.
- Combinar las tareas de recuperación y formato en la misma etapa del prompt.
- Creer que reformular los prompts puede salvar un índice de recuperación deficiente.
Consecuencias totales
Los resúmenes funcionan mejor cuando están adaptados al dominio específico y no se dejan como textos generales. Los prompts y las restricciones operan en capas diferentes, por lo que deben versionarse por separado. Una base de conocimientos es una opción de recuperación y no sustituye a las API en tiempo real; por eso, los prompts deben indicar claramente cuándo una herramienta proporciona información actualizada y cuándo la base de conocimientos ofrece contexto seleccionado.
Juntos, estos componentes completan el flujo interno del agente: una instrucción MEMORY_SUMMARIZATION que condensa conversaciones largas en resúmenes reutilizables, una medida de seguridad Bedrock Guardrail que bloquea categorías de contenido dañino, y una base de conocimientos basada en un origen de datos S3 para la generación mejorada mediante recuperación de información.