feat: 도메인 시스템 개선 + 검색 한글→영문 번역
주요 변경: - Domain Agent 제거, 코드 직접 처리로 전환 - suggest_domains: 등록 가능 도메인만 표시, 10개 미만 시 재시도 - search_web: 한글 검색어 자동 영문 번역 (GPT-4o-mini) - WHOIS: raw 데이터 파싱으로 상세 정보 추출 - 가격 조회: API 필드명 수정 (register_krw → krw) - 동적 도구 로딩 시스템 추가 - 문서 정리 및 업데이트 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -69,30 +69,52 @@ export async function getLatestSummary(
|
||||
return summary || null;
|
||||
}
|
||||
|
||||
// 모든 요약 조회 (최대 3개, 최신순)
|
||||
export async function getAllSummaries(
|
||||
db: D1Database,
|
||||
userId: number,
|
||||
chatId: string
|
||||
): Promise<Summary[]> {
|
||||
const { results } = await db
|
||||
.prepare(`
|
||||
SELECT id, generation, summary, message_count, created_at
|
||||
FROM summaries
|
||||
WHERE user_id = ? AND chat_id = ?
|
||||
ORDER BY generation DESC
|
||||
LIMIT 3
|
||||
`)
|
||||
.bind(userId, chatId)
|
||||
.all();
|
||||
|
||||
return (results || []) as Summary[];
|
||||
}
|
||||
|
||||
// 전체 컨텍스트 조회
|
||||
export async function getConversationContext(
|
||||
db: D1Database,
|
||||
userId: number,
|
||||
chatId: string
|
||||
): Promise<ConversationContext> {
|
||||
const [previousSummary, recentMessages] = await Promise.all([
|
||||
getLatestSummary(db, userId, chatId),
|
||||
const [summaries, recentMessages] = await Promise.all([
|
||||
getAllSummaries(db, userId, chatId),
|
||||
getBufferedMessages(db, userId, chatId),
|
||||
]);
|
||||
|
||||
const previousSummary = summaries[0] || null; // 최신 요약 (호환성)
|
||||
const totalMessages = (previousSummary?.message_count || 0) + recentMessages.length;
|
||||
|
||||
return {
|
||||
previousSummary,
|
||||
summaries,
|
||||
recentMessages,
|
||||
totalMessages,
|
||||
};
|
||||
}
|
||||
|
||||
// AI 요약 생성
|
||||
// AI 요약 생성 (모든 요약 통합)
|
||||
async function generateSummary(
|
||||
env: Env,
|
||||
previousSummary: string | null,
|
||||
allSummaries: Summary[],
|
||||
messages: BufferedMessage[]
|
||||
): Promise<string> {
|
||||
// 사용자 메시지만 추출
|
||||
@@ -106,29 +128,37 @@ async function generateSummary(
|
||||
|
||||
let prompt: string;
|
||||
|
||||
if (previousSummary) {
|
||||
prompt = `당신은 사용자 프로필 분석 전문가입니다.
|
||||
기존 사용자 프로필과 새로운 대화를 통합하여 사용자에 대한 이해를 업데이트하세요.
|
||||
if (allSummaries.length > 0) {
|
||||
// 모든 기존 프로필 통합 (오래된 것부터)
|
||||
const existingProfiles = allSummaries
|
||||
.slice()
|
||||
.reverse()
|
||||
.map((s) => `[v${s.generation}] ${s.summary}`)
|
||||
.join('\n\n');
|
||||
|
||||
## 기존 사용자 프로필
|
||||
${previousSummary}
|
||||
prompt = `당신은 사용자 프로필 분석 전문가입니다.
|
||||
기존 사용자 프로필들과 새로운 대화를 통합하여 사용자에 대한 이해를 업데이트하세요.
|
||||
|
||||
## 기존 사용자 프로필 (${allSummaries.length}개 버전)
|
||||
${existingProfiles}
|
||||
|
||||
## 새로운 사용자 발언 (${userMsgCount}개)
|
||||
${userMessages}
|
||||
|
||||
## 요구사항
|
||||
1. **사용자 중심**: 봇 응답은 무시하고 사용자가 말한 내용만 분석
|
||||
2. **의미 있는 정보 추출**:
|
||||
1. **통합 분석**: 모든 기존 프로필을 종합하고 새로운 정보를 추가
|
||||
2. **사용자 중심**: 봇 응답은 무시하고 사용자가 말한 내용만 분석
|
||||
3. **의미 있는 정보 추출**:
|
||||
- 사용자의 관심사, 취미, 선호도
|
||||
- 질문한 주제들 (무엇에 대해 알고 싶어하는지)
|
||||
- 요청사항, 목표, 해결하려는 문제
|
||||
- 개인적 맥락 (직업, 상황, 배경 등)
|
||||
- 감정 상태나 태도 변화
|
||||
3. **무의미한 내용 제외**: 인사말, 단순 확인, 감사 표현 등은 생략
|
||||
4. **간결하게**: 300-400자 이내
|
||||
5. **한국어로 작성**
|
||||
- 관심사 변화 추이
|
||||
4. **무의미한 내용 제외**: 인사말, 단순 확인, 감사 표현 등은 생략
|
||||
5. **간결하게**: 400-500자 이내
|
||||
6. **한국어로 작성**
|
||||
|
||||
업데이트된 사용자 프로필:`;
|
||||
통합된 사용자 프로필:`;
|
||||
} else {
|
||||
prompt = `당신은 사용자 프로필 분석 전문가입니다.
|
||||
대화 내용에서 사용자에 대한 정보를 추출하여 프로필을 작성하세요.
|
||||
@@ -200,17 +230,19 @@ export async function processAndSummarize(
|
||||
return { summarized: false };
|
||||
}
|
||||
|
||||
const previousSummary = await getLatestSummary(env.DB, userId, chatId);
|
||||
// 모든 기존 요약 조회 (통합 분석용)
|
||||
const allSummaries = await getAllSummaries(env.DB, userId, chatId);
|
||||
const latestSummary = allSummaries[0] || null;
|
||||
|
||||
// AI 요약 생성
|
||||
// AI 요약 생성 (모든 요약 통합)
|
||||
const newSummary = await generateSummary(
|
||||
env,
|
||||
previousSummary?.summary || null,
|
||||
allSummaries,
|
||||
messages
|
||||
);
|
||||
|
||||
const newGeneration = (previousSummary?.generation || 0) + 1;
|
||||
const newMessageCount = (previousSummary?.message_count || 0) + messages.length;
|
||||
const newGeneration = (latestSummary?.generation || 0) + 1;
|
||||
const newMessageCount = (latestSummary?.message_count || 0) + messages.length;
|
||||
|
||||
// 트랜잭션 실행
|
||||
await env.DB.batch([
|
||||
@@ -242,18 +274,30 @@ export async function generateAIResponse(
|
||||
): Promise<string> {
|
||||
const context = await getConversationContext(env.DB, userId, chatId);
|
||||
|
||||
const systemPrompt = `당신은 친절하고 유능한 AI 어시스턴트입니다.
|
||||
${context.previousSummary ? `
|
||||
## 사용자 프로필
|
||||
${context.previousSummary.summary}
|
||||
// 모든 요약 통합 (최신순 → 오래된순으로 정렬하여 시간순 표시)
|
||||
const integratedProfile = context.summaries.length > 0
|
||||
? context.summaries
|
||||
.slice()
|
||||
.reverse() // 오래된 것부터 표시
|
||||
.map((s, i) => `[v${s.generation}] ${s.summary}`)
|
||||
.join('\n\n')
|
||||
: null;
|
||||
|
||||
위 프로필을 바탕으로 사용자의 관심사와 맥락을 이해하고 개인화된 응답을 제공하세요.
|
||||
const systemPrompt = `당신은 친절하고 유능한 AI 어시스턴트입니다.
|
||||
${integratedProfile ? `
|
||||
## 사용자 프로필 (${context.summaries.length}개 버전 통합)
|
||||
${integratedProfile}
|
||||
|
||||
위 프로필들을 종합하여 사용자의 관심사, 맥락, 변화를 이해하고 개인화된 응답을 제공하세요.
|
||||
최신 버전(높은 번호)의 정보를 우선시하되, 이전 버전의 맥락도 고려하세요.
|
||||
` : ''}
|
||||
- 날씨, 시간, 계산 요청은 제공된 도구를 사용하세요.
|
||||
- 최신 정보, 실시간 데이터, 현재 가격, 뉴스, 특정 사실 확인이 필요한 질문은 반드시 search_web 도구로 검색하세요. 자체 지식으로 답변하지 마세요.
|
||||
- 최신 정보, 실시간 데이터, 뉴스, 특정 사실 확인이 필요한 질문은 반드시 search_web 도구로 검색하세요. 자체 지식으로 답변하지 마세요.
|
||||
- 예치금, 입금, 충전, 잔액, 계좌 관련 요청은 반드시 manage_deposit 도구를 사용하세요. 금액 제한이나 규칙을 직접 판단하지 마세요.
|
||||
- 도메인 관련 요청은 반드시 manage_domain 도구를 사용하세요.
|
||||
- manage_deposit, manage_domain 도구 결과는 그대로 전달하세요. 추가 질문이나 "도움이 필요하시면~" 같은 멘트를 붙이지 마세요.
|
||||
- 도메인 추천, 도메인 제안, 도메인 아이디어 요청은 반드시 suggest_domains 도구를 사용하세요. 직접 도메인을 나열하지 마세요.
|
||||
- 도메인/TLD 가격 조회(".com 가격", ".io 가격" 등)는 manage_domain 도구의 action=price를 사용하세요.
|
||||
- 기타 도메인 관련 요청(조회, 등록, 네임서버, WHOIS 등)은 manage_domain 도구를 사용하세요.
|
||||
- manage_deposit, manage_domain, suggest_domains 도구 결과는 그대로 전달하세요. 추가 질문이나 "도움이 필요하시면~" 같은 멘트를 붙이지 마세요.
|
||||
- 응답은 간결하고 도움이 되도록 한국어로 작성하세요.`;
|
||||
|
||||
const recentContext = context.recentMessages.slice(-10).map((m) => ({
|
||||
|
||||
Reference in New Issue
Block a user