인공지능에 대한 심층 연구는 하나의 단일 모델이 아니며, 오히려 답을 찾을 때까지 검색하고, 읽고, 추론하는 반복적 워크플로우 과정입니다. ChatGPT 또는 GPT-4와 같은 OpenAI의 독점 시스템은 지속적으로 응답을 refinement하는 복잡한 파이프라인을 사용합니다. 이제 오픈 소스 도구를 사용하여 유사한 시스템을 구축할 수 있다고 상상해 보십시오. 이 기사는 jina-ai/node-DeepResearch 프로젝트를 사용하여 심층 연구 시스템을 재현하는 방법을 설명합니다. 우리는 코드를 분해하고, 각 구성 요소를 자세히 설명하며, 시스템을 설정하고 확장하는 방법을 보여줄 것입니다.
1. 개요 및 목적
DeepResearch는 간단하면서도 강력한 아이디어를 기반으로 구축되었습니다:
답이 발견될 때까지(또는 토큰 예산을 초과할 때까지) 웹페이지를 계속 검색하고 읽습니다.
시스템은 쿼리(예: "누가 더 큽니까? cohere, jina ai, voyage?")를 입력하고 루프에 들어갑니다. 각 단계에서 에이전트(지능형 모듈)는 행동을 결정합니다. 새로운 키워드를 검색하거나, URL의 내용을 읽거나, 후속 질문을 생성하여 반영하거나, 확신이 있으면 답변을 제공합니다. 이 반복 사이클은 답이 확정적이거나 토큰 예산(계산 자원의 대리)이 초과될 때까지 계속됩니다.
설치 및 설정
코드에 들어가기 전에 필요한 종속성을 설치하고 API 키를 설정해야 합니다. 이 프로젝트는 언어 모델링에 Gemini를 사용하고 웹 검색에 Brave 또는 DuckDuckGo를 사용하며 웹페이지 내용을 가져오는 데 Jina Reader를 사용합니다. 프로젝트를 설정하는 방법은 다음과 같습니다:
export GEMINI_API_KEY=... # Gemini API용, Han에게 문의
export JINA_API_KEY=jina_... # 무료 Jina API 키는 https://jina.ai/reader에서 가져옵니다.
export BRAVE_API_KEY=... # 선택 사항; 제공되지 않으면 DuckDuckGo 검색으로 기본 설정됩니다.
git clone https://github.com/jina-ai/node-DeepResearch.git
cd node-DeepResearch
npm install
README에는 다양한 쿼리로 시스템을 실행하기 위한 예제도 제공합니다:
- 간단한 쿼리:
npm run dev "1+1="
또는npm run dev "프랑스의 수도는 무엇인가요?"
- 다단계 쿼리:
npm run dev "Jina AI에서의 최신 뉴스는 무엇인가요?"
npm run dev "jina ai의 창립자의 트위터 계정은 무엇인가요?"
- 모호한 연구와 같은 쿼리:
npm run dev "누가 더 큽니까? cohere, jina ai, voyage?"
npm run dev "2028년에 미국 대통령은 누가 될까요?"
npm run dev "2025년을 위한 jina ai 전략은 무엇이어야 합니까?"
커맨드라인 인터페이스 외에도 이 프로젝트는 쿼리를 제출하고 진행 상황 업데이트를 스트리밍하는 API를 포함하는 웹 서버도 포함됩니다.
2. 아키텍처 및 주요 구성 요소
시스템의 주요 구성 요소를 핵심 파일을 탐색하면서 분해해 봅시다:
2.1 agent.ts – 핵심 로직
agent.ts
파일은 시스템의 심장부입니다. 이는 "심층 연구" 사이클의 로직을 구현합니다: 프롬프트 생성, 행동 결정, 검색, 읽기, 반영 및 답변 단계를 반복합니다.
agent.ts의 주요 요소:
임포트 및 설정:
파일은 다양한 도구 및 라이브러리를 임포트하는 것으로 시작합니다:
- GoogleGenerativeAI는 언어 생성을 위해 사용됩니다.
- readUrl는
./tools/read
에서 웹페이지 콘텐츠를 가져오고 처리합니다. - duckSearch와 braveSearch는 외부 검색 기능을 제공합니다.
- rewriteQuery, dedupQueries, evaluateAnswer, analyzeSteps와 같은 유틸리티 함수는 쿼리를 다듬고 응답을 평가하는 데 도움이 됩니다.
- 구성 값(API 키, 토큰 예산 및 모델 구성)은
config.ts
에서 임포트됩니다. - 토큰 및 액션 추적 유틸리티는 토큰 사용량 및 에이전트의 진행 상태를 모니터링합니다.
- 마지막으로, 파일은
types.ts
에서 정의된 타입(예:StepAction
,ResponseSchema
)을 임포트합니다.
대기 함수:
async function sleep(ms: number) {
const seconds = Math.ceil(ms / 1000);
console.log(`Waiting ${seconds}s...`);
return new Promise(resolve => setTimeout(resolve, ms));
}
이 헬퍼 함수는 외부 API를 호출할 때 비율 제한을 피하기 위해 유용하게 사용됩니다.
스키마 생성:
getSchema
함수는 에이전트의 응답을 위한 JSON 스키마를 정의합니다. 이는 다음과 같은 속성을 포함하는 스키마를 동적으로 생성합니다:
- search: 키워드 기반의
searchQuery
가 필요합니다. - answer: 최종 답변 내에 자연어 텍스트와 지원되는 참조(정확한 인용 및 URL)를 포함해야 함을 지정합니다.
- reflect: 지식 공백을 채우기 위한 명확한 하위 질문을 나열합니다.
- visit: 외부 콘텐츠를 읽기 위한 URL 대상을 포함합니다.
엄격한 JSON 스키마를 통해 에이전트의 출력은 일관성 있고 기계해독 가능하게 유지됩니다.
프롬프트 생성:
getPrompt
함수는 언어 모델에 전송되는 상세 프롬프트를 생성합니다. 여러 섹션을 집계합니다:
- 헤더: 현재 날짜와 원래 질문을 포함합니다.
- 맥락 및 지식: 이전 작업 및 수집된 중간 지식이 포함됩니다.
- 실패한 시도: 이전 작업이 확정적인 답을 제공하지 못한 경우, 그 실패(이유 및 개선 사항)를 기록합니다.
- 행동: 가능한 행동 목록이 표시됩니다. 플래그(예:
allowSearch
,allowRead
등)에 따라 허용된 작업이 나열됩니다. "Beast Mode"에서는 불확실성이 남아 있어도 답변을 도출하기 위해 최선을 다하라는 지침이 제공됩니다.
이 계층화된 프롬프트는 생성 AI 모델이 단계별로 "사고"하고 매번 하나의 행동을 선택하는 데 도움을 줍니다.
getResponse의 주요 루프:
getResponse
함수는 에이전트의 반복 루프의 핵심입니다. 초기 맥락을 설정합니다:
- 추적기: 두 개의 추적기가 사용됩니다—하나는 사용된 토큰 수를 모니터링하는 TokenTracker이고, 다른 하나는 각 단계와 그 결과를 추적하는 ActionTracker입니다.
- 공백 및 지식: 이것은 "공백"(원래 질문)으로 시작한 후, 시스템이 추론을 반영할 필요가 있는 경우 중간 질문을 추가합니다.
while 루프 내부에서 에이전트는:
- API 비율 제한을 피하기 위해 대기합니다(대기 함수 사용).
- 현재 맥락에 따라 프롬프트를 생성합니다.
- 생성 모델(GoogleGenerativeAI를 통해)을 호출하여 응답을 생성합니다.
- JSON 응답을 구문 분석하여 어떤 행동이 이루어졌는지 결정합니다(답변, 반영, 검색 또는 방문).
- 행동에 따라:
- 답변: 답변을 평가하고, 확정적이면 루프를 종료합니다.
- 반영: 지식 공백을 채우기 위해 하위 질문을 처리합니다.
- 검색: 검색 쿼리를 재작성하고 이전에 사용된 키워드를 중복 제거하며 DuckDuckGo 또는 Brave에서 새로운 URL을 검색합니다.
- 방문: 제공된 URL의 내용을 읽고 지식 기반을 업데이트합니다.
루프의 예산이 소진되거나 너무 많은 실패한 시도가 발생하면 시스템은 "Beast Mode"로 전환되어 최종적이고 공격적인 답변 시도를 하게 됩니다.
맥락 저장:
storeContext
함수는 현재 프롬프트와 다양한 메모리 상태(맥락, 쿼리, 질문 및 수집된 지식)를 파일에 기록합니다. 이 보관 프로세스는 디버깅에 도움이 되며 의사결정 과정을 추가로 분석할 수 있게 합니다.
최종 실행:
agent.ts
의 마지막 부분에 있는 main()
함수는 커맨드라인 인수(쿼리)를 사용하여 getResponse
를 호출하고 최종 답변과 함께 토큰 사용 요약을 출력합니다.
2.2 config.ts – 환경 구성
config.ts
파일은 환경 및 모델 구성이 정의되는 곳입니다:
- 환경 변수:
dotenv
를 사용하여 Gemini, Jina, Brave의 API 키를 로드합니다. HTTPS 프록시 구성도 지원합니다. - 검색 제공자: 시스템은 Brave API 키가 제공되는지 여부에 따라 검색 제공자를 동적으로 선택합니다. 제공되지 않으면 DuckDuckGo로 기본 설정됩니다.
- 모델 구성: 이 파일은 쿼리 재작성, 중복 제거 및 평가와 같은 다양한 작업을 위한 기본 및 특정 모델 구성을 설정합니다. 예를 들어, 에이전트의 생성 모델은 창의성과 결정성을 균형 있게 맞추기 위해 0.7의 온도로 구성되어 있습니다.
- 토큰 예산 및 지연: 상수
STEP_SLEEP
는 1000밀리초로 설정되어, 단계 간 1초의 일시 중지를 보장합니다.
이 구성 파일을 통해 설정을 쉽게 변경하고 시스템을 다양한 환경이나 모델 행동에 적응시킬 수 있습니다.
2.3 server.ts – 웹 서버 API
사용자가 HTTP 요청을 통해 DeepResearch와 상호작용할 수 있도록 시스템에는 server.ts
에 간단한 Express 기반 서버가 포함되어 있습니다. 이 파일은 쿼리 제출 및 실시간으로 진행 상황 업데이트를 처리하는 엔드포인트를 설정합니다.
server.ts의 주요 포인트:
Express 설정:
서버는 Express 및 CORS를 사용하여 교차 출처 요청을 지원합니다. 3000번 포트(또는 환경에서 지정된 포트)를 수신합니다.
쿼리 엔드포인트 (POST /api/v1/query
):
- 클라이언트는 쿼리, 토큰 예산 및 최대 허용 실패 시도를 포함하는 JSON 페이로드를 보냅니다.
- 서버는 새 추적기(토큰 사용량 및 액션 상태)를 생성하고 고유한
requestId
를 할당합니다. - 요청은
getResponse
를 호출하여 비동기적으로 처리됩니다. - 완료되면 최종 응답이 저장되고, 진행 상황은
EventEmitter
를 사용하여 방출됩니다.
스트리밍 엔드포인트 (GET /api/v1/stream/:requestId
):
- 이 엔드포인트는 서버 전송 이벤트(SSE)를 사용하여 클라이언트로 지속적으로 업데이트를 푸시합니다.
- 에이전트가 행동(검색, 반영, 방문, 답변)을 취할 때 진행 상황 이벤트가 방출됩니다. 각 이벤트는 현재 단계 정보, 토큰 사용량 및 행동 세부사항을 포함합니다.
- 이것은 클라이언트가 연구 프로세스를 실시간으로 모니터링할 수 있게 해줍니다.
작업 저장 및 검색:
서버는 작업 결과를 파일 시스템(작업 디렉토리 아래)에 기록하고 저장된 결과를 검색하기 위한 엔드포인트(GET /api/v1/task/:requestId
)를 제공합니다.
이 웹 서버 구성 요소는 연구 에이전트를 HTTP를 통해 접근 가능하게 하여 대화형 실험 및 더 큰 시스템에 통합할 수 있게 합니다.
2.4 test-duck.ts – 검색 테스트 유틸리티
test-duck.ts
파일은 Axios를 사용하여 외부 API(이 경우 jsonplaceholder.typicode.com
)에 HTTP GET 요청을 보내는 독립 실행형 스크립트입니다. 이 파일의 주요 기능은 HTTP 요청이 올바르게 작동하는지 확인하는 것이며(적절한 헤더 설정 및 오류 처리 포함), 시스템 내에서 외부 요청이 어떻게 처리되는지를 보여주는 예제로 활용됩니다. 더 복잡한 설정에서는 DuckDuckGo나 Brave와 같은 검색 API를 쿼리할 때 유사한 패턴이 사용됩니다.
2.5 types.ts – 일관된 데이터 구조 정의
types.ts
파일은 프로젝트 전반에서 사용되는 모든 사용자 정의 타입을 정의합니다:
작업 타입:
여기에는 에이전트가 수행할 수 있는 다양한 행동이 포함됩니다:
- SearchAction:
searchQuery
문자열을 포함합니다. - AnswerAction:
answer
문자열과 지원하는references
가 필요합니다. - ReflectAction:
questionsToAnswer
의 배열을 포함합니다. - VisitAction:
URLTargets
의 목록을 포함합니다.
응답 타입:
파일은 검색 결과, URL 읽기, 평가, 오류 분석 등을 위한 구조화된 응답을 정의합니다. 이는 일관성을 유지하는 데 도움이 되며 모든 모듈이 데이터를 동일하게 해석하도록 보장합니다.
스키마 타입:
JSON 스키마 정의는 언어 모델에 의해 생성된 응답이 예상 형식을 엄격하게 준수하도록 보장합니다. 이것은 다운스트림 처리에 매우 중요합니다.
추적기 맥락:
토큰 및 액션 추적기를 위한 사용자 정의 타입도 정의되어 있으며, 이는 대화의 상태 및 연구 프로세스를 모니터링하는 데 사용됩니다.
3. 반복적 심층 연구 프로세스
전체 시스템은 인간 연구자가 작업할 때의 방식과 유사한 방법론적이며 반복적인 프로세스를 따릅니다:
초기화:
이 프로세스는 원래 질문으로 시작되며 "\gaps\g" 목록(즉, 채워야 할 미지의 사항)에서 추가됩니다.
프롬프트 생성:
에이전트는 현재 질문, 이전 맥락, 수집된 지식 및 심지어 실패한 시도를 사용하여 프롬프트를 구성합니다. 이 프롬프트는 생성 AI 모델에 전송됩니다.
행동 선택:
모델의 출력에 따라 에이전트는 여러 행동 중 하나를 선택합니다:
- 검색: 더 많은 데이터를 수집하기 위한 새로운 쿼리를 형성합니다.
- 방문: 특정 URL에서 상세한 콘텐츠를 검색합니다.
- 반영: 지식 공백을 해결하기 위해 명확한 하위 질문을 생성합니다.
- 답변: 정보가 확정적이라고 판단되면 최종 답변을 제공합니다.
맥락 업데이트:
각 단계는 내부 추적기(토큰 사용량 및 행동 상태)를 업데이트하고 현재 상태를 파일에 보관합니다. 이는 투명성을 보장하고 디버깅 또는 후속 검토를 가능하게 합니다.
평가 및 루프:
답변이 제안되면 평가 단계에서 그것이 확정적인지 확인합니다. 그렇지 않으면 시스템은 실패한 시도 세부정보를 저장하고 전략을 조정합니다. 사이클은 만족스러운 답변을 찾거나 토큰 예산이 소진될 때까지 계속됩니다.
Beast Mode:
정상 단계가 제약 내에서 확정적인 답변을 생성하지 못하는 경우 시스템은 "Beast Mode"로 전환됩니다. 이 모드에서는 생성 AI가 축적된 맥락을 기반으로 답변을 생성해야 하며, 심지어 교육적인 추측을 해야 할 수도 있습니다.
4. 실시간 진행 및 피드백
DeepResearch 시스템의 필수 기능 중 하나는 실시간 피드백 메커니즘입니다. 웹 서버의 스트리밍 엔드포인트를 통해:
- 클라이언트는 어떤 행동이 취해졌는지, 토큰 사용 통계 및 현재 상태 등의 진행 상황 업데이트를 받습니다.
- 진행 상황 이벤트(README 예제에 표시)는 에이전트의 사고 과정과 현재 단계 및 토큰 세부정보를 포함합니다.
- 이 실시간 피드백 루프는 디버깅, 자원 사용 모니터링 및 시스템의 추론 방식을 이해하는 데 매우 유용합니다.
예를 들어, 진행 상황 이벤트는 다음과 같을 수 있습니다:
data: {
"type": "progress",
"trackers": {
"tokenUsage": 74950,
"tokenBreakdown": {
"agent": 64631,
"read": 10319
},
"actionState": {
"action": "search",
"thoughts": "텍스트는 Jina AI의 여러 투자자를 언급하지만 소유 지분에 대한 명시적인 언급은 없습니다. 직접 검색이 필요합니다.",
"URLTargets": [],
"answer": "",
"questionsToAnswer": [],
"references": [],
"searchQuery": "Jina AI 투자자 소유 지분"
},
"step": 7,
"badAttempts": 0,
"gaps": []
}
}
이 상세한 진행 상황 보고서는 개발자가 에이전트의 추론이 시간이 지남에 따라 어떻게 발전하는지 확인할 수 있게 하여 성공과 개선이 필요한 영역에 대한 통찰력을 제공합니다.
5. DeepResearch 확장 및 사용자 정의
이 프로젝트의 오픈 소스 특성 덕분에 시스템을 필요에 맞게 조정할 수 있습니다. 다음은 DeepResearch를 확장할 수 있는 몇 가지 아이디어입니다:
사용자 정의 검색 제공자:
추가 검색 제공자를 통합하거나 도메인별 검색을 위한 쿼리 재작성 프로세스를 사용자 정의할 수 있습니다.
향상된 읽기 모듈:
더 상세한 텍스트 처리가 필요한 경우 대체 NLP 모델을 통합하거나 Jina Reader 구성 요소를 조정하여 새로운 콘텐츠 유형을 처리할 수 있습니다.
개선된 평가:
현재 평가 모듈은 답변이 확정적인지 확인합니다. 이를 확장하여 감정 분석이나 사실 확인 알고리즘과 같은 더 미세한 메트릭을 포함할 수 있습니다.
사용자 인터페이스:
현재 시스템은 커맨드라인 인터페이스와 이벤트 스트리밍을 위한 간단한 웹 서버를 사용하고 있습니다. 그러나 보다 대화형 연구 세션을 위해 전체 웹 또는 모바일 인터페이스를 구축할 수 있습니다.
확장성 향상:
현재 구현은 단일 노드 서비스로 실행됩니다. 생산 환경에서는 애플리케이션을 컨테이너화하고, Kubernetes 또는 다른 오케스트레이션 플랫폼을 사용하여 고트래픽 및 분산 처리를 처리하도록 배포하는 것을 고려하십시오.
6. 보안, 성능 및 모범 사례
DeepResearch와 같은 AI 기반 시스템을 배포할 때 몇 가지 추가 고려 사항이 있습니다:
API 키 관리:
Gemini, Jina 및 Brave의 API 키가 안전하게 저장되고 소스 코드에 하드코딩되지 않도록 하십시오. 환경 변수와 보안 금고를 사용하는 것이 좋습니다.
비율 제한:
내장된 sleep
함수는 연속 요청을 지연시켜 비율 제한을 피하는 데 도움이 됩니다. 그러나 서버 또는 API 게이트웨이 수준에서 추가 비율 제한 메커니즘을 구현하는 것을 고려하십시오.
데이터 검증:
입력 쿼리 및 응답을 엄격하게 검증합니다. 에이전트에 정의된 JSON 스키마는 도움을 주지만, 악의적인 입력을 방지하기 위해 수신 HTTP 요청도 검증해야 합니다.
오류 처리:
견고한 오류 처리는 필수적입니다(서버 코드 및 test-duck.ts에서 볼 수 있듯이). 이는 예기치 않은 API 실패나 잘못된 응답이 시스템을 충돌시키지 않도록 보장합니다.
자원 모니터링:
토큰 사용량을 추적하는 것은 매우 중요합니다. TokenTracker 및 ActionTracker 클래스는 자원 소비에 대한 통찰력을 제공합니다. 이러한 메트릭을 모니터링하면 시스템 성능을 미세 조정하고 과도한 사용을 피하는 데 도움이 됩니다.
7. 결론
Jina AI의 DeepResearch 프로젝트는 복잡하고 반복적인 연구 프로세스를 오픈 소스 도구를 사용하여 구축하는 방법을 보여줍니다. 검색 엔진, 생성 AI 모델 및 지능적인 추론 루프를 통합함으로써 이 시스템은 확실해질 때까지 또는 자원 제한이 도달할 때까지 응답을 지속적으로 refinement합니다.
이 기사에서는 오픈 소스 접근 방식으로 OpenAI Deep Research를 재현하는 방법을 탐구했습니다:
- 설치 단계 및 환경 설정 방법을 논의했습니다.
agent.ts
의 반복 에이전트 로직부터 구성, 웹 서버 API 및 타입 정의에 이르기까지 핵심 모듈을 분해했습니다.- 추론 프로세스에 대한 투명성을 제공하는 진행 상황 업데이트를 스트리밍하는 실시간 피드백 메커니즘을 검토했습니다.
- 마지막으로 이러한 시스템을 배포하는 데 있어 잠재적인 확장, 사용자 정의 옵션 및 모범 사례를 살펴보았습니다.
이와 같은 고급 연구 기술을 오픈 소스로 제공함으로써 DeepResearch와 같은 프로젝트는 최첨단 AI 방법에 대한 접근을 민주화합니다. 연구자, 개발자 또는 워크플로우에 심층 연구 기능을 통합하려는 기업이든, 이 프로젝트는 영감과 자신만의 솔루션을 구축하기 위한 실질적인 기반이 됩니다.
검색, 읽기, 반영 및 답변을 연속적인 루프로 결합한 반복적 설계는 모호하거나 복잡한 쿼리도 여러 겹의 검토로 처리된다는 것을 보장합니다. 그리고 토큰 사용량을 추적하고 실시간 피드백을 제공하는 상세한 아키텍처 덕분에 각 답변 뒤에 있는 추론 과정에 대해 깊은 통찰력을 얻게 됩니다.
실험을 하고 싶다면, 레포지토리를 복제하고, 설명된 대로 환경을 설정한 후, 간단한 산술 문제부터 다면적인 연구 질문까지 다양한 쿼리를 실행해 보십시오. 약간의 사용자 정의를 통해 새로운 도메인에 시스템을 맞춤 설정하고 심지어 그 추론 기능을 향상시킬 수 있습니다. 이러한 오픈 소스 프로젝트는 AI 연구의 커뮤니티 주도 혁신의 길을 엽니다.
이 상세한 분석을 따라 OpenAI의 Deep Research 아이디어를 완전히 오픈 소스 방식으로 재현하고 확장할 수 있습니다. 기존 코드베이스를 기반으로 구축하거나 유사한 방법론을 프로젝트에 통합하려는 경우 경로는 명확합니다: 반복하고, 개선하며, 자동화된 연구의 경계를 밀어붙이십시오.