리서치 에이전트 만들기
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 에서 가장 중요한 역할로, 다음과 같은 역할을 수행합니다.
사용자 질문을 이해하여 적절한 Tool Calling 을 지시합니다.
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 의 추론 과정을 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.
"검색 타입 UI" 를 선택
노드 명을 "Visible Reasoner" 로 변경 (LLM or Custom Function 노드)
노드의 출력은 문자열 (string)
3.3 Tool - Web Search
리서치 에이전트의 중요한 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 성능 비교
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 노드 관련하여 웹 검색하는 검색어를 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.
"검색 타입 UI" 를 선택
노드 명을 "Visible Query Generator" 로 변경 (Custom Function 노드)
노드의 출력은 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 노드 관련하여 검색어를 채팅 화면의 "작업 탭"에서 보여주기 위한 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.
"검색 타입 UI" 를 선택
노드 명을 "Visible URL" 로 변경 (Custom Function 노드)
노드의 출력은 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
최종 답변에서 정보의 출처를 표기할 때 컨벤션이 존재합니다. 다음과 같은 조건을 만족해야 합니다.
표기하고자 하는 출처 URL 이 다음과 같이 출력되어야 합니다.
${url}
부분에 해당 url 이 입력되도록class="btn__chip"
${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?