리서치 에이전트 만들기

1. 서론

🧑‍💻 리서치 에이전트는 복잡한 Multi-hop 질문에 답변하기 위해 웹 검색, 외부 API, 내부 DB 검색, 차트 시각화 등 다양한 Tool 을 적절하게 활용하여 답변하는 에이전트입니다.

예시 질문)

  • 영화 '84제곱미터'의 젊은 남자 주연배우의 데뷔작의 방송 횟수는?

  • 올해 6월 새로 개통된 인천도시철도 1호선 북측 연장 구간의 길이(㎞)와 새로 생긴 역 개수를 곱하면 얼마인가?

  • 삼성전자의 2025년 1분기 영업이익 발표 당일, 코스피 지수 상승률은 몇 퍼센트인가?

2. 리서치 에이전트 워크플로우 (전체 구조)

사용자의 입력 질문을 이해하고, 적절한 Tool Calling 을 통해 출력 결과를 받는 리서치 과정을 반복하여 최종 답변을 생성합니다.

3. 노드 구성

3.1 Query Clarifier

사용자가 애매한 질문을 입력하는 경우에, 모호한 부분에 대해 되물어보는 노드입니다.

전체 구조에서는 Query Clarifier 가 빠져있습니다. (Deep Research 옵션을 켜는 경우 추가하면 좋습니다.)

  • 사용한 노드: Conditional Agent & Human in the loop

    • Conditional Agent 대신, LLM + Condition 노드를 사용하는 것도 가능합니다.

  • 실제로 애매한 질문에 대해서만 되물어보도록 Classification 모듈을 추가했습니다.

  • 사용자의 피드백을 바탕으로 query 를 rephrase 하여 리서치 워크플로우에서 활용할 수 있게 했습니다.

    • rephrase 된 쿼리는 State에 replace 하여 사용하면 됩니다.

사용한 프롬프트: . > 리서치 에이전트 프롬프트

3.2 Core Reasoner

Core Reasoner 의 역할은 Research Agent 에서 가장 중요한 역할로, 다음과 같은 역할을 수행합니다.

  1. 사용자 질문을 이해하여 적절한 Tool Calling 을 지시합니다.

  2. Tool Calling Output 을 이해하고, 다음 Step을 진행합니다.

사용하고자 하는 모델에 따라 아래 두가지 방안 중 실험을 통해 결정하면 좋습니다. (추론형 vs. 비추론형)

  • 방안 1) 추론형 모델의 경우 Agent 노드에 원하는 Tool을 붙여 사용합니다.

    • 예) deepseek/deepseek-r1-0528, qwen/qwen3-235b-a22b-thinking-2507, ...

  • 방안 2) 성능이 비교적 좋지 않은 경우, LLM 노드에서 <reasoning> Tool 사용을 위한 추론 </reasoning> 을 생성하도록 시스템 프롬프트를 설정하고, LLM Ouput 을 Custom Function 노드에서 정규식 파싱하여 사용합니다.

    • 예) moonshotai/kimi-k2, deepseek/deepseek-chat-v3-0324, qwen/qwen3-235b-a22b-2507, ...

전체적인 구조는 아래 이미지를 참고하시면 됩니다.

사용한 프롬프트: . > 리서치 에이전트 프롬프트

⚠️ CONVENTION

  • Core Reasoner 의 추론 과정을 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.

  1. "검색 타입 UI" 를 선택

  2. 노드 명을 "Visible Reasoner" 로 변경 (LLM or Custom Function 노드)

  3. 노드의 출력은 문자열 (string)

리서치 에이전트의 중요한 Tool 인 웹 검색 툴입니다.

  • 사용 가능한 상용 API 중 선호하는 것을 사용하시면 됩니다.

    • 현재 리서치 에이전트에서는 SearchAPI 를 사용하고 있습니다.

  • 일반적으로 입력한 검색어에 따라 Title, Snippet, URL 등으로 구성된 response 를 받을 수 있습니다.

  • 간단한 내용은 Snippet 의 내용만으로 충분하지만, 웹 페이지의 전문을 읽어야하는 경우도 있기에 3.4 Open URL 툴을 함께 사용하면 좋습니다.

  • 검색할 검색어는 Tool Calling 할 때 Core Reasoner LLM 노드에서 argument 형태의 output을 파싱하여 사용하거나, Agent 노드를 사용한다면 자동으로 검색어가 들어갈 수 있게 설계하시면 됩니다.

  • 일반적으로 웹 검색한 결과를 보고 다음 스텝을 판단할 수 있게 Core Reasoner 노드로 Loop Back 될 수 있도록 구현합니다. (Agent 노드로 구현한다면 Loop Back 이 필요하지 않습니다)

사용한 코드: . > 리서치 에이전트 커스텀 노드 함수

내부적으로 다섯가지 웹검색 API 에 대해 실험을 진행했을 때 결과는 아래와 같았습니다.

검색 API 성능 비교

순위
API
평균 처리 시간
평균 점수

1

Tavily

2.95초

5.39

2

Google CSE

3.20초

5.32

3

Jina

3.40초

4.51

4

SearchAPI

4.11초

4.86

5

LinkUp

4.55초

6.41

  • 평가 기준: 하나의 쿼리에 대한 검색 결과 각각에 대해 gpt-4o를 이용해 4가지의 기준에 따라 평가.

    • Accuracy: 0 (Factual error) / 1 (Partial) / 2 (Mostly) / 3 (Complete)

    • Query Relevance: 0 (Irrelevant) / 1 (Partially) / 2 (Mostly) / 3 (Perfect)

    • Freshness: 1 (Information from the last 12 months) / 0 (Not recent or N/A)

    • Duplication/Spam: 1 (Normal) / 0 (Duplicate, ad, or low-quality)

내부 검토를 위해 간단히 평가한 결과이므로, 참고만 해주시기 바랍니다.

⚠️ CONVENTION

  • Web Search 노드 관련하여 웹 검색하는 검색어를 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.

  1. "검색 타입 UI" 를 선택

  2. 노드 명을 "Visible Query Generator" 로 변경 (Custom Function 노드)

  3. 노드의 출력은 dict[list]

    {
     visible_web_search_query: ["검색어_1", "검색어_2", "검색어_3"]
    }

3.4 Tool - Open URL

웹 검색 결과 중 웹 페이지 전문을 읽어보아야 하는 경우 모델이 선택하는 툴입니다.

requests, beautifulSoup 등 추가 패키지가 필요하기 때문에, MCP Tool 로 구성하여 사용하면 됩니다.

사용한 코드: . > 리서치 에이전트 커스텀 노드 함수

사용한 MCP Tool: 튜토리얼: 기본편 > MCP > MCP Tool 예시 (웹 크롤링)

⚠️ CONVENTION

  • Open URL 노드 관련하여 검색어를 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.

  1. "검색 타입 UI" 를 선택

  2. 노드 명을 "Visible URL" 로 변경 (Custom Function 노드)

  3. 노드의 출력은 dict[list]

    {
     visible_url: ["URL_1", "URL_2", "URL_3"]
    }

3.4 Tool - External API

프로젝트 요구 사항에 따라, 다양한 외부 API를 Tool 처럼 활용할 수 있습니다.

  • 아래 내용은 DeepSearch API 를 활용하는 예시입니다.

  • 사용하고자 하는 API 명세서 기반으로 Custom Function 노드에 구현하거나, Agent 노드를 사용하는 경우 Tool 에 작성해주시면 됩니다.

사용한 코드: . > 리서치 에이전트 커스텀 노드 함수

3.5 Tool - Draw Chart

툴 사용 출력 결과 (tool_output_history)에 수치적인 데이터가 포함된 경우 차트로 시각화할 수 있는 tool 입니다.

  • Tool 노드의 Genos MCP 를 선택하여 사용 가능합니다.

  • 인풋 포맷과 자세한 코드는 아래 링크를 확인해주시기 바랍니다.

사용한 MCP Tool: 튜토리얼: 기본편 > MCP > MCP Tool 예시 (데이터 시각화)

4. 최종 답변 생성

4.1 Citation

⚠️ CONVENTION

  • 최종 답변에서 정보의 출처를 표기할 때 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.

  1. 표기하고자 하는 출처 URL 이 다음과 같이 출력되어야 합니다.

  2. ${url} 부분에 해당 url 이 입력되도록

  3. class="btn__chip"

  4. ${label} 부분은 출처 링크 버튼에 노출될 이름 (예시: bloomberg, NY Times, ...)

    "<a\n    href="${url}" \n    target="_blank" \n    class="btn__chip">\n    <strong>${label}</strong>\n</a>"
  • Conflict detector

  • Streaming

  • To be added more ...

Last updated

Was this helpful?