Агенты Bedrock: краткое изложение памяти, версионированные ограничения и база знаний.
Управление агентами Bedrock с использованием Terraform: память сессии с пользовательским запросом на краткое изложение, версионированные ограничения с реализацией метода обнаружение-заблокировка и система RAG с хранением в S3.
Источники: 6A. Building Chat Agent with AWS Bedrock and Terraform: Summary, Knowledge Base, and Guardrails
Сбои, которые не оставляют следов
В системе ИИ-агентов может произойти множество проблем, при этом самые серьезные сбои не вызывают ошибок и не активируют уведомлений. Качество постепенно снижается. Память сессии накапливает шум вместо полезных данных, правила безопасности находятся вне системы контроля версий, а агент обращается к инструментам для получения информации, которую можно было бы напрямую предоставить из базы знаний.
В Amazon Bedrock существуют три решения для устранения этих проблем: функция переопределения MEMORY_SUMMARIZATION, позволяющая сохранять значимые сигналы от пользователя между сессиями, инструмент Bedrock Guardrail в формате Terraform с поддержкой версионирования, а также необязательная база знаний, хранящаяся на S3.
Только оптимизация запросов недостаточна. Настоящие системы требуют механизмов контроля в трех областях:
- Качество памяти сессии. Резюме должны сохранять важные сигналы от пользователя.
- Управление безопасностью. Правила должны быть четко сформулированы и иметь версионирование.
Без них система, как правило, кажется стабильной в демо-версиях, но начинает работать хуже при поступлении реального, разнообразного трафика.
Как работает память сессии
Суммаризация памяти позволяет сохранять историю действий пользователя между сессиями, так что старые сообщения не нужно повторно извлекать и обрабатывать в реальном времени. В классических агентах Bedrock предоставляет базовую формулировку через enabled_memory_types = ["SESSION_SUMMARY"] в объекте aws_bedrockagent_agent, а функция GetAgentMemory в среде выполнения агента считывает сохраненные данные.
При включенной памяти обработка происходит асинхронно после закрытия сессии. Bedrock подводит итоги завершенного разговора, сохраняет эти итоги и вставляет их в последующие сессии, использующие тот же memoryId, при этом ответ пользователя не задерживается.
Bedrock поставляется с предустановленным промптом, определяющим поведение функции подведения итогов:
{
"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>"
}
]
}
Инструкции по его использованию в основном находятся в разделе <guidelines/>, где указано, что агент должен возвращать свой результат внутри тега <summary/>. Резюме разделено по темам. Информация, касающаяся целей пользователя, помещается в тему с названием user goals, собственные действия агента — в тему assistant actions; каждая тема оборачивается тегами <topic name='$TOPIC_NAME'></topic>. Ожидаемый формат вывода выглядит следующим образом:
<summary>
<topic name='$TOPIC_NAME'>
...
</topic>
...
</summary>
Bedrock заполняет <previous_summaries/> предыдущими краткими отчетами с помощью переменной $past_conversation_summary$, а текущее общение отображается внутри <conversation>$conversationlt;/conversation>. Еще два раздела, <additional_guidelines/> и <special_guidelines/>, позволяют добавить дополнительные детали к стратегии составления кратких отчетов.
Цикл жизни работает следующим образом:
- В настройках агента включается функция хранения данных с помощью параметров
memory_configurationиenabled_memory_types = ["SESSION_SUMMARY"]. - Запрашивающий пользователь вызывает агента, указав уникальный
memoryIdдля каждого пользователя. - Сессия завершается либо при указании параметра
endSession = true, либо по истечении времени ожидания. - Bedrock генерирует краткий отчет на фоне.
memoryId Bedrock помещает контекст памяти в места для оркестрации, такие как $memory_content$.Это приводит к двум последствиям. Краткие сводки появляются не мгновенно и могут отобразиться спустя некоторое время после завершения сессии. Кроме того, если memoryId меняется от запроса к запросу, непрерывность теряется.
Предупреждение: Нестабильные значения
memoryId, такие как идентификаторы соединений, к которым относятся идентификаторы пользователей, нарушают непрерывность памяти. Используйте идентификатор, который остается неизменным для каждого пользователя или сущности разговора.
Сделать краткие сводки полезными
По умолчанию краткая сводка представляет собой общий обзор. Это подходит для универсальных помощников, но часто слишком информативно для специализированных. Для небольшого новостного помощника хорошей краткой сводкой будет та, которая включает:
- повторяющиеся темы, такие как новости об ИИ, климат или геополитика;
Без такой структуры объем данных растет, в то время как их релевантность снижается.
Чтобы ее включить, сначала необходимо настроить ресурс агента в 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 ...
}
В Bedrock агенты принимают здесь только тип SESSION_SUMMARY. AgentCore предлагает более широкие возможности: краткие отчеты, предпочтения пользователя, семантические данные и пользовательские стратегии хранения информации. Параметр storage_days определяет срок хранения отчетов, а max_recent_sessions — количество недавних сессий, для которых будут генерироваться отчеты.
Каждый вызов должен содержать параметр memoryId, который здесь соответствует user_id, чтобы разговоры связывались с одним и тем же объектом:
# 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
)
При получении данных используется тот же 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"
)
Переопределение промпта для подведения итогов
При включенной памяти Bedrock позволяет промпту с переопределением заменить этап MEMORY_SUMMARIZATION: вместо prompt_type = „MEMORY_SUMMARIZATION“ используется prompt_creation_mode = „OVERRIDDEN“. Классические агенты используют два специальных местоположения: $past_conversation_summary$ для сохраненных резюме, связанных с той же идентичностью памяти, и $conversation$ для текста текущей сессии. В шаблонах оркестрации контекст памяти передается через $memory_guideline$ для стратегии, $memory_content$ для сохранения данных и $memory_action_guideline$ для системных промптов.
Специальная версия стандартного промпта указывает, что агент должен зафиксировать, а что игнорировать, так что сохраняются только полезные детали:
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 ...
}
]
}
Переопределите этап обработки, когда общий обзор не улучшает последующих ответов, когда для резюме требуется высокое соотношение сигнал/шум, или когда бюджет токенов памяти должен оставаться ограниченным и предсказуемым. Если ассистент является универсальным и не основан на персонализации, стандартный вариант подходит.
К типичным ошибкам относятся:
- нестабильные значения
memoryId, когда, например, идентификаторы соединений заменяют собой идентификаторы пользователей; - сессии, которые никогда не заканчиваются, в результате чего резюме так и не формируется;
- длинные запросы на составление резюме, которые воссоздают практически полный текст разговора;
- смешивание целей составления резюме с целями форматирования, предназначенными для последующей обработки.
Ограничения: правила, которые запросы не могут навязать
Иногда пользователи ведут себя грубо, злоупотребляют агентом или запрашивают внутренние детали, секретную информацию и личные данные других людей. Механизмы контроля решают эту проблему. Принцип прост: подсказки направляют поведение, а механизмы контроля обеспечивают соблюдение правил. Используйте подсказки для принятия решений и форматирования, а механизмы контроля — для соблюдения ограничений безопасности контента как в пользовательских запросах, так и в ответах ассистента.
Совет: Сначала протестируйте механизмы контроля в режиме DETECT, прежде чем использовать режим BLOCK. Проверка того, что могло бы быть заблокировано, не влияет на тестировщиков.
В Bedrock предусмотрено несколько функций контроля, которые не требуют дополнительной настройки — достаточно просто добавить их в список:
- Фильтры контента позволяют блокировать ненавистнические высказывания, оскорбления, насилие, сексуальный контент, ненадлежащее поведение и атаки через подсказки; они включают параметры эффективности для входных и выходных данных, а также соответствующие действия. Они идеально подходят для постоянной базовой защиты обычного трафика пользователей.
Большинство команд эффективнее внедряют эти механизмы поэтапно: сначала фильтры контента и конфиденциальной информации, затем фильтры по темам и словам, а уже после совершенствования политик поиска — механизмы обоснования ответов.
Порядок оценки
Механизмы контроля проверяют информацию в обоих направлениях:
- Входные данные. Сначала оценивается запрос от пользователя, при этом все настроенные политики применяются параллельно. Если срабатывает блокировка, Bedrock возвращает значение
blocked_input_messagingи пропускает процесс вывода результата. - Результаты. После прохождения проверки входных данных модель отвечает, и её результат анализируется. Если срабатывает блокировка, ответ заменяется на значение
blocked_outputs_messaging, либо маскируется в тех частях, где настроены фильтры конфиденциальной информации.
Порядок имеет значение с точки зрения стоимости. Заблокированный входной данные обходятся только в стоимость оценки защитных мер, а не инференции модели.
У каждого фильтра контента есть два независимых настройки. Интенсивность (inputStrength и outputStrength) может принимать значения NONE, LOW, MEDIUM или HIGH и определяет степень активности обнаружения нарушений. Действие (inputAction и outputAction) может быть BLOCK, когда контент блокируется и заменяется сообщением об ошибке, или NONE, когда ничего не происходит, а обнаружения фиксируются в отчетах о трафике, что фактически является режимом только обнаружения.
Разумная стандартная стратегия:
- для категорий с высоким риском, таких как ненависть, насилие и ненадлежащее поведение, начинайте с уровня
MEDIUMкак для входных, так и для выходных данных; - во время тестирования или на стадии разработки используйте параметр
outputAction = "NONE", чтобы можно было подсчитывать ложноположительные результаты; - переключайтесь на уровень
BLOCKтолько после того, как результаты тестирования покажутся приемлемыми; - для категорий с низким риском сохраняйте уровень
LOWилиMEDIUM, и не устанавливайте все на уровеньHIGHс самого начала.
Фильтры контента также имеют два уровня защиты. CLASSIC — это базовый уровень фильтрации, тогда как STANDARD обеспечивает более строгую защиту за счет анализа кода и поддержки категорий атак с использованием промптов. Ассистент, обрабатывающий промпты в стиле разработчиков, фрагменты кода или смешанный текст с кодом, обычно работает более надежно в режиме Standard.
Версионирование
Обновления правил защиты должны быть явными и неизменяемыми, причем каждое изменение политики должно приводить к созданию новой версии. aws_bedrock_guardrail_version позволяет это реализовать: создается версия, которая затем привязывается к aws_bedrock_guardrail с помощью параметра 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 ...
}
Такое разделение позволяет осуществить чистую откатку. Подсказки остаются прежними, и меняется только версия с защитными мерами при необходимости настройки политик.
База знаний для внутреннего контента
Предположим, что агент должен отвечать на вопросы, опираясь на корпоративные правила или знания, накопленные со временем, и избегать ненужных вызовов инструментов. Bedrock использует привязанную базу знаний для генерации ответов на основе полученных документов; она включена по умолчанию после её настройки. Это позволяет агентам безопасно подключаться к закрытым корпоративным данным, чтобы модели могли давать более релевантные, точные и персонализированные ответы с помощью технологии Retrieval Augmented Generation (RAG).
Этот подход подходит, когда источником информации являются внутренние или тщательно отобранные документы, когда не требуется мгновенная актуальность данных или когда нужны обоснованные ответы с возможностью отслеживания источников, похожей на цитирование.
Примечание: Для работы с информацией, индексируемой в реальном времени извне, более подходят инструменты API.
Bedrock Knowledge Base функционирует как управляемый конвейер RAG для обработки собственного контента. Вместо того чтобы самостоятельно создавать инфраструктуру поиска, вы позволяете Bedrock получать данные из подключения, анализировать и разбивать документы на части, генерировать векторные представления, хранить их в поддерживаемом хранилище и извлекать соответствующие части при поступлении запроса. Во время этапа KNOWLEDGE_BASE_RESPONSE_GENERATION эти части используются для формирования основанных на фактах ответов.
Здесь задействованы два процесса. Прием данных выполняется офлайн или в режиме синхронизации: документы анализируются, разделяются на фрагменты согласно стратегии разбиения, преобразуются в векторы с помощью модели эмбеддингов и записываются в индекс векторов вместе с маппингами метаданных. Поиск во время выполнения происходит по каждому запросу: запрос преобразуется в эмбеддинг, хранилище векторов возвращает семантически релевантные фрагменты, Bedrock добавляет их в контекст модели, а на этапе генерации формируется осмысленный результат, либо в режиме только поиска возвращаются результаты поиска.
Разбиение на фрагменты имеет операционное значение, поскольку плохое качество поиска часто связано с проблемами приема данных или разбиения на фрагменты, а не с проблемами запроса.
Ничего не «вставляется как строка», как в кэше SQL. Вы добавляете или обновляете файлы или источники, поддерживаемые коннекторами, а затем запускаете синхронизацию.
Предупреждение: синхронизация происходит не автоматически. После добавления документов в S3 необходимо явно запустить её, прежде чем агент сможет их получить.
Контроль во время выполнения
numberOfResultsопределяет количество возвращаемых исходных фрагментов (по умолчанию до 5, диапазон от 1 до 100).overrideSearchTypeпозволяет выбратьSEMANTICдля поиска только с использованием векторов илиHYBRIDдля поиска с использованием векторов и текста в необработанном виде; поддерживается только на совместимых хранилищах и индексах. Если значение не установлено, Bedrock делает выбор сам.- Фильтры метаданных
filterи логические группы (andAll,orAll) позволяют осуществлять точный поиск. - Необязательная переориентация улучшает окончательный порядок фрагментов.
При иерархическом разделении на фрагменты количество результатов может быть меньше запрошенного, поскольку дочерние фрагменты могут быть заменены их родительскими в момент ответа.
Разбиение на чанки
Разбиение текста на чанки сильно влияет на качество поиска. Bedrock предлагает стандартное разбиение примерно на 300 токенов по границам предложений, разбиение фиксированного размера с указанием размера токенов и степени перекрытия, иерархические родительские и дочерние чанки для повышения точности и получения более широкого контекста, семантическое разбиение с использованием границ, определяемых моделью, а также вариант без разбиения, при котором каждый документ рассматривается как отдельный чанк и который в основном подходит для заранее сегментированного контента.
Разумный подход: начните с стандартного или фиксированного разбиения, поскольку оно простое. Перейдите к иерархическому разбиению, когда для получения ответа потребуется больше контекста, и к семантическому разбиению, если точность остается низкой после настройки запроса. Сравнивайте результаты с набором данных для оценки поиска до и после каждой изменения.
Хранилища векторов
Базы знаний могут работать с несколькими векторными движками, такими как OpenSearch Serverless или управляемый кластер, совместимый с Aurora PostgreSQL, Pinecone, Redis Enterprise Cloud, MongoDB Atlas и Neptune Analytics, в зависимости от поддержки поставщика на момент развертывания. Выбор влияет на наличие гибридного поиска, возможные фильтры метаданных, а также на операционную сложность и стоимость. OpenSearch Serverless обычно позволяет быстрее начать работу. Ниже приведен пример настройки с использованием 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 ...
}
Маршрутизация между базой знаний и инструментами
Использование базы знаний предоставляет агенту дополнительный путь поиска информации. Чтобы избежать неоднозначности, укажите правила маршрутизации для базы знаний и API-инструмента в команде оркестрации, сохраняйте контракт POST_PROCESSING неизменным независимо от того, какой источник предоставил ответ, а также указывайте моменты, когда агенту следует задавать уточняющие вопросы из-за низкой степени уверенности в результатах поиска.
Практический подход к такой настройке: используйте базу знаний для внутреннего, статического контекста, такого как документы с правилами, редакционные стандарты и исторические записи; используйте группу действий для актуальных внешних данных; и не обращайтесь к обоим источникам за один раз, если только запрос действительно не требует перепроверки.
Ограничения также применяются при операциях по извлечению и генерации информации, что важно, поскольку метод основанного на фактах извлечения сам по себе не устраняет риски для безопасности. Распространённой рекомендацией является сначала оценка пути к базе знаний с использованием ограничений в режиме обнаружения, настройка параметров ложноположительных и ложноотрицательных результатов на основе полученных данных, а затем переход к блокировке или маскировке в режиме производства.
Получение контента
- Исходный корпус: для однократной загрузки политик, часто задаваемых вопросов и руководств по стилю необходимо загрузить файлы в бакет S3, связанный с источником данных, и запустить процесс синхронизации.
- Постоянные обновления: когда текст продукта или юридические документы изменяются по расписанию, еженочная задача может загружать новые файлы в S3 и запускать функцию
StartIngestionJobдля соответствующего источника данных, либо использовать автоматическую синхронизацию, если она включена.
kb/topics/eu-ai-act-overview.md, так что границы блоков совпадают с темами, а цитаты становятся более понятными по сравнению с одним огромным PDF.StartIngestionJob, чтобы база знаний обработала новые объекты.Подводные камни
- Рассматривание базы знаний как реального потока данных. Её актуальность определяется только расписанием синхронизации.
- Чрезмерное или недостаточное разделение на блоки, что снижает точность.
- Некачественные метаданные, из-за которых фильтры становятся бесполезными.
- Совмещение задач по извлечению информации и форматированию в одном этапе запроса.
- Убеждение в том, что перефразирование запросов может спасти слабый индекс извлечения информации.
Что это в сумме дает
Резюме работают наилучшим образом, когда они адаптированы под конкретную область, а не являются универсальным кратким изложением. Запросы и ограничения действуют на разных уровнях, поэтому их следует версионировать отдельно. База знаний — это лишь один из вариантов извлечения информации и не заменяет API в реальном времени, поэтому запросы должны четко указывать, когда инструмент обеспечивает актуальные данные, а когда база знаний предоставляет отобранный контекст.
Вместе эти компоненты образуют внутреннюю систему агента: промпт MEMORY_SUMMARIZATION, преобразующий длинные разговоры в повторно используемые краткие сводки, механизм Bedrock Guardrail, блокирующий категории вредоносного контента, и база знаний на источнике данных S3 для генерации с использованием дополнительных данных.