diff --git a/README.md b/README.md index 558a364..0574256 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,8 @@ - **OpenAI GPT-4o-mini**: 고품질 AI 응답 및 Function Calling 지원 - **사용자 프로필**: 대화에서 사용자의 관심사, 목표, 맥락을 추출하여 프로필 구축 -- **Function Calling**: 날씨, 검색, 시간, 계산 등 AI가 자동으로 도구 호출 +- **Function Calling**: 날씨, 검색, 시간, 계산, **문서 조회** 등 AI가 자동으로 도구 호출 +- **Context7 연동**: 프로그래밍 라이브러리 공식 문서 실시간 조회 - **무한 컨텍스트**: 슬라이딩 윈도우(3개)로 프로필 유지, 무제한 대화 기억 - **개인화 응답**: 프로필 기반으로 맞춤형 AI 응답 제공 - **폴백 지원**: OpenAI 미설정 시 Workers AI(Llama)로 자동 전환 @@ -32,6 +33,7 @@ | **Workers** | 서버리스 런타임 | | **D1** | SQLite 데이터베이스 | | **OpenAI** | GPT-4o-mini + Function Calling | +| **Context7** | 라이브러리 문서 조회 API | | **Workers AI** | 폴백용 (Llama 3.1 8B) | --- @@ -55,11 +57,12 @@ │ (Function Call) │ 도구 호출 자동 판단 └──────────────────┘ │ - ┌───┴───┬───────┬───────┐ - ▼ ▼ ▼ ▼ -[날씨] [검색] [시간] [계산] → 외부 API - │ │ │ │ - └───┬───┴───────┴───────┘ + ┌───┴───┬───────┬───────┬───────┐ + ▼ ▼ ▼ ▼ ▼ +[날씨] [검색] [시간] [계산] [문서] → 외부 API + │ │ │ │ │ + │ │ │ │ └── Context7 API + └───┬───┴───────┴───────┴───────┘ ▼ ┌──────────────────┐ │ 최종 응답 생성 │ @@ -116,6 +119,7 @@ OpenAI Function Calling을 통해 AI가 자동으로 필요한 도구를 호출 | **검색** | "파이썬이 뭐야", "클라우드플레어란" | DuckDuckGo | | **시간** | "지금 몇 시야", "뉴욕 시간" | 내장 | | **계산** | "123 * 456", "100의 20%" | 내장 | +| **문서** | "React hooks 사용법", "OpenAI API 예제" | Context7 | ### 동작 방식 @@ -325,3 +329,10 @@ database_id = "c285bb5b-888b-405d-b36f-475ae5aed20e" - [Cloudflare D1](https://developers.cloudflare.com/d1/) - [Cloudflare Workers](https://developers.cloudflare.com/workers/) - [Telegram Bot API](https://core.telegram.org/bots/api) +- [Context7 API](https://context7.com/docs/api-guide) + +--- + +## 소스 코드 + +**Gitea**: https://gitea.anvil.it.com/kaffa/telegram-bot-workers diff --git a/src/openai-service.ts b/src/openai-service.ts index e36b140..3993045 100644 --- a/src/openai-service.ts +++ b/src/openai-service.ts @@ -93,6 +93,27 @@ const tools = [ }, }, }, + { + type: 'function', + function: { + name: 'lookup_docs', + description: '프로그래밍 라이브러리의 공식 문서를 조회합니다. React, OpenAI, Cloudflare Workers 등의 최신 문서와 코드 예제를 검색할 수 있습니다.', + parameters: { + type: 'object', + properties: { + library: { + type: 'string', + description: '라이브러리 이름 (예: react, openai, cloudflare-workers, next.js)', + }, + query: { + type: 'string', + description: '찾고 싶은 내용 (예: hooks 사용법, API 호출 방법)', + }, + }, + required: ['library', 'query'], + }, + }, + }, ]; // 도구 실행 @@ -162,6 +183,38 @@ async function executeTool(name: string, args: Record): Promise< } } + case 'lookup_docs': { + const library = args.library; + const query = args.query; + try { + // Context7 REST API 직접 호출 + // 1. 라이브러리 검색 + const searchUrl = `https://context7.com/api/v2/libs/search?libraryName=${encodeURIComponent(library)}&query=${encodeURIComponent(query)}`; + const searchResponse = await fetch(searchUrl); + const searchData = await searchResponse.json() as any; + + if (!searchData.libraries?.length) { + return `📚 "${library}" 라이브러리를 찾을 수 없습니다.`; + } + + const libraryId = searchData.libraries[0].id; + + // 2. 문서 조회 + const docsUrl = `https://context7.com/api/v2/context?libraryId=${encodeURIComponent(libraryId)}&query=${encodeURIComponent(query)}`; + const docsResponse = await fetch(docsUrl); + const docsData = await docsResponse.json() as any; + + if (docsData.error) { + return `📚 문서 조회 실패: ${docsData.message || docsData.error}`; + } + + const content = docsData.context || docsData.content || JSON.stringify(docsData, null, 2); + return `📚 ${library} 문서 (${query}):\n\n${content.slice(0, 1500)}`; + } catch (error) { + return `📚 문서 조회 중 오류: ${String(error)}`; + } + } + default: return `알 수 없는 도구: ${name}`; }