본문 바로가기
WIKI 기술 지식 베이스

Using agentic memory for agentic search

원문 보기 위키 갱신

출처: 문서

본문

에이전틱 검색에서 에이전틱 메모리 사용하기

에이전틱 메모리는 전용 메모리 컨테이너를 통해 에이전틱 검색에서 대화 컨텍스트를 관리하는 구조화된 접근 방식을 제공해요. 대화형 에이전트가 사용하는 기본 conversation_index 메모리 타입과 달리, 에이전틱 메모리는 별도로 생성하고 구성하는 메모리 컨테이너를 사용하기 때문에 대화 기록을 저장하고 관리하는 방식을 더 세밀하게 제어할 수 있어요. 에이전트와 독립적으로 메모리 라이프사이클을 관리하거나, 메모리 동작을 구성하거나, 서로 다른 워크플로우에서 메모리 컨테이너를 공유하려는 시나리오에서 유용해요.

다음 예제에서는 메모리 컨테이너를 만들고, 에이전틱 메모리를 사용하도록 에이전트를 구성하고, 여러 검색 쿼리에 걸쳐 메모리 연속성을 활용하는 방법을 보여 줘요.

1단계: 제품 인덱스 생성하기

product_name, price, color, category와 같은 다양한 제품 속성을 담은 제품 데이터로 샘플 인덱스를 만들어요:

PUT /products-index
{
  "settings": {
    "number_of_shards": "4",
    "number_of_replicas": "2"
  },
  "mappings": {
    "properties": {
      "product_name": { "type": "text" },
      "description": { "type": "text" },
      "price": { "type": "float" },
      "currency": { "type": "keyword" },
      "rating": { "type": "float" },
      "review_count": { "type": "integer" },
      "in_stock": { "type": "boolean" },
      "color": { "type": "keyword" },
      "size": { "type": "keyword" },
      "category": { "type": "keyword" },
      "brand": { "type": "keyword" },
      "tags": { "type": "keyword" }
    }
  }
}

{% include copy-curl.html %}

2단계: 샘플 데이터 적재하기

인덱스에 샘플 제품 문서를 추가해요:

POST _bulk
{ "index": { "_index": "products-index", "_id": "1" } }
{ "product_name": "Nike Air Max 270", "description": "Comfortable running shoes with Air Max technology", "price": 150.0, "currency": "USD", "rating": 4.5, "review_count": 1200, "in_stock": true, "color": "white", "size": "10", "category": "shoes", "brand": "Nike", "tags": ["running", "athletic", "comfortable"] }
{ "index": { "_index": "products-index", "_id": "2" } }
{ "product_name": "Adidas Ultraboost 22", "description": "Premium running shoes with Boost midsole", "price": 180.0, "currency": "USD", "rating": 4.7, "review_count": 850, "in_stock": true, "color": "black", "size": "9", "category": "shoes", "brand": "Adidas", "tags": ["running", "premium", "boost"] }
{ "index": { "_index": "products-index", "_id": "3" } }
{ "product_name": "Converse Chuck Taylor", "description": "Classic canvas sneakers", "price": 65.0, "currency": "USD", "rating": 4.2, "review_count": 2100, "in_stock": true, "color": "white", "size": "8", "category": "shoes", "brand": "Converse", "tags": ["casual", "classic", "canvas"] }
{ "index": { "_index": "products-index", "_id": "4" } }
{ "product_name": "Puma RS-X", "description": "Retro-inspired running shoes with modern comfort", "price": 120.0, "currency": "USD", "rating": 4.3, "review_count": 750, "in_stock": true, "color": "black", "size": "9", "category": "shoes", "brand": "Puma", "tags": ["retro", "running", "comfortable"] }

{% include copy-curl.html %}

3단계: 모델 생성하기

모델 구성을 검토하고 사용할 모델을 선택해요.

다음 예제에서는 conversational 에이전트와 QueryPlanningTool 모두가 사용할 GPT 모델을 등록해요:

POST /_plugins/_ml/models/_register
{
  "name": "My OpenAI model: gpt-5",
  "function_name": "remote",
  "description": "test model",
  "connector": {
    "name": "My openai connector: gpt-5",
    "description": "The connector to openai chat model",
    "version": 1,
    "protocol": "http",
    "parameters": {
      "model": "gpt-5"
    },
    "credential": {
      "openAI_key": "your-openai-api-key"
    },
    "actions": [
      {
        "action_type": "predict",
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "headers": {
          "Authorization": "Bearer ${credential.openAI_key}"
        },
        "request_body": "{ \"model\": \"${parameters.model}\", \"messages\": [{\"role\":\"developer\",\"content\":\"${parameters.system_prompt}\"},${parameters._chat_history:-}{\"role\":\"user\",\"content\":\"${parameters.user_prompt}\"}${parameters._interactions:-}], \"reasoning_effort\":\"low\"${parameters.tool_configs:-}}"
      }
    ]
  }
}

{% include copy-curl.html %}

4단계: 메모리 컨테이너 생성하기

에이전트의 대화 컨텍스트를 저장할 메모리 컨테이너를 만들어요:

POST /_plugins/_ml/memory_containers/_create
{
  "name": "agent-memory-container",
  "configuration": {
    "disable_history": true
  }
}

{% include copy-curl.html %}

메모리 컨테이너는 독립적으로 생성되며 다양한 옵션을 사용해 구성할 수 있어요. 자세한 내용은 구성 객체를 참조하세요.

응답에는 메모리 컨테이너 ID가 포함되어 있어요:

{
  "memory_container_id": "your-memory-container-id"
}

5단계: 에이전틱 메모리로 에이전트 등록하기

메모리 타입으로 agentic_memory를 사용하는 대화형 에이전트를 등록해요. 이전 단계에서 만든 메모리 컨테이너를 memory_container_id 필드에 지정해요. 에이전트에는 쿼리 도메인 특화 언어(DSL)를 생성하는 데 필요한 QueryPlanningTool이 포함되어 있어요:

POST /_plugins/_ml/agents/_register
{
  "name": "GPT 5 Agent for Agentic Search",
  "type": "conversational",
  "description": "Use this for Agentic Search",
  "llm": {
    "model_id": "your-model-id",
    "parameters": {
      "max_iteration": 15
    }
  },
  "memory": {
    "type": "agentic_memory",
    "memory_container_id": "your-memory-container-id"
  },
  "parameters": {
    "_llm_interface": "openai/v1/chat/completions"
  },
  "tools": [
    {
      "type": "QueryPlanningTool"
    }
  ],
  "app_type": "os_chat"
}

{% include copy-curl.html %}

더 많은 구성 옵션은 에이전틱 검색 에이전트 구성하기를 참조하세요.

6단계: 검색 파이프라인 구성하기

요청 프로세서와 응답 프로세서를 모두 포함하는 검색 파이프라인을 만들어요. agentic_query_translator 요청 프로세서는 자연어 쿼리를 query DSL로 변환해요. agentic_context 응답 프로세서는 모니터링과 대화 연속성을 위해 에이전트 실행 컨텍스트 정보를 추가해요:

PUT _search/pipeline/agentic_search_pipeline
{
  "request_processors": [
    {
      "agentic_query_translator": {
        "agent_id": "your-agent-id"
      }
    }
  ],
  "response_processors": [
    {
      "agentic_context": {
        "dsl_query": true
      }
    }
  ]
}

{% include copy-curl.html %}

7단계: 에이전틱 검색 실행하기

에이전틱 검색을 실행하려면 자연어 검색 쿼리를 전송해요:

GET /_search?search_pipeline=agentic_search_pipeline
{
  "query": {
    "agentic": {
      "query_text": "Find me white shoes under 150 dollars"
    }
  }
}

{% include copy-curl.html %}

에이전트가 요청을 분석하고, 적절한 인덱스를 찾아내고, 최적화된 DSL 쿼리를 생성해요. 응답의 hits 배열에는 일치하는 제품이 포함되어 있어요. ext 객체에는 대화를 이어가는 데 사용하는 memory_id와 생성된 dsl_query가 들어 있어요:

{
  "took": 32240,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.0,
    "hits": [
      {
        "_index": "products-index",
        "_id": "3",
        "_score": 0.0,
        "_source": {
          "product_name": "Converse Chuck Taylor",
          "description": "Classic canvas sneakers",
          "price": 65.0,
          "currency": "USD",
          "rating": 4.2,
          "review_count": 2100,
          "in_stock": true,
          "color": "white",
          "size": "8",
          "category": "shoes",
          "brand": "Converse",
          "tags": [
            "casual",
            "classic",
            "canvas"
          ]
        }
      },
      {
        "_index": "products-index",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "product_name": "Nike Air Max 270",
          "description": "Comfortable running shoes with Air Max technology",
          "price": 150.0,
          "currency": "USD",
          "rating": 4.5,
          "review_count": 1200,
          "in_stock": true,
          "color": "white",
          "size": "10",
          "category": "shoes",
          "brand": "Nike",
          "tags": [
            "running",
            "athletic",
            "comfortable"
          ]
        }
      }
    ]
  },
  "ext": {
    "memory_id": "BrLLHJ0BMk3oS6TPFO_2",
    "dsl_query": "{\"size\":10,\"query\":{\"bool\":{\"filter\":[{\"term\":{\"category.keyword\":\"shoes\"}},{\"term\":{\"color.keyword\":\"white\"}},{\"range\":{\"price\":{\"lte\":150}}}]}}}"
  }
}

8단계: 후속 에이전틱 검색 실행하기

이전 응답에서 받은 memory_id를 사용해 후속 쿼리를 전송해요:

GET /_search?search_pipeline=agentic_search_pipeline
{
  "query": {
    "agentic": {
      "query_text": "Actually, show black ones instead",
      "memory_id": "<memory_id from previous response>"
    }
  }
}

{% include copy-curl.html %}

에이전틱 메모리 컨테이너를 사용해서 에이전트가 이전 대화를 기억하고 새 요청에 적용해요. 에이전트는 150달러 이하라는 가격 제약을 유지하면서 "black ones instead"라는 표현을 성공적으로 해석해요. 응답에서 memory_id는 동일하게 유지되고, 생성된 DSL 쿼리는 다른 모든 제약 조건을 그대로 유지한 채 색상 필터만 흰색에서 검은색으로 바뀌어요:

{
  "took": 19311,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.0,
    "hits": [
      {
        "_index": "products-index",
        "_id": "4",
        "_score": 0.0,
        "_source": {
          "product_name": "Puma RS-X",
          "description": "Retro-inspired running shoes with modern comfort",
          "price": 120.0,
          "currency": "USD",
          "rating": 4.3,
          "review_count": 750,
          "in_stock": true,
          "color": "black",
          "size": "9",
          "category": "shoes",
          "brand": "Puma",
          "tags": [
            "retro",
            "running",
            "comfortable"
          ]
        }
      },
      {
        "_index": "products-index",
        "_id": "2",
        "_score": 0.0,
        "_source": {
          "product_name": "Adidas Ultraboost 22",
          "description": "Premium running shoes with Boost midsole",
          "price": 180.0,
          "currency": "USD",
          "rating": 4.7,
          "review_count": 850,
          "in_stock": true,
          "color": "black",
          "size": "9",
          "category": "shoes",
          "brand": "Adidas",
          "tags": [
            "running",
            "premium",
            "boost"
          ]
        }
      }
    ]
  },
  "ext": {
    "memory_id": "BrLLHJ0BMk3oS6TPFO_2",
    "dsl_query": "{\"size\":10,\"query\":{\"bool\":{\"filter\":[{\"term\":{\"category.keyword\":\"shoes\"}},{\"term\":{\"color.keyword\":\"black\"}},{\"range\":{\"price\":{\"lte\":150}}}]}}}"
  }
}

다음 단계

더 알아보기 (Learn more)