UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

146 lines (137 loc) 4.4 kB
import { RSSFetcher, RSSFeedConfig, RSSDocument } from "./rss/rssFetcher"; import { extractMainContent, ExtractorOptions } from "./web/contentExtractor"; import { WebpageSummarizer, SummarizerOptions, SummarizationResult, } from "./summarizer/summarizer"; import { QueryExpander, QueryExpanderOptions, QueryType, } from "./query/queryExpander"; export interface AgentcRAGConfig { rssFeeds: RSSFeedConfig[]; extractor?: ExtractorOptions; summarizer?: SummarizerOptions & { apiKey: string }; queryExpander?: QueryExpanderOptions; logLevel?: "info" | "warn" | "error" | "debug"; onLog?: (level: string, msg: string, meta?: any) => void; onMetric?: (event: string, data?: any) => void; } export class AgentcRAG { private rssFetcher: RSSFetcher; private summarizer: WebpageSummarizer; private queryExpander: QueryExpander; private config: AgentcRAGConfig; private log: (level: string, msg: string, meta?: any) => void; private metric: (event: string, data?: any) => void; constructor(config: AgentcRAGConfig) { this.config = config; this.rssFetcher = new RSSFetcher(config.rssFeeds); this.summarizer = new WebpageSummarizer( config.summarizer?.apiKey || "", config.summarizer ); this.queryExpander = new QueryExpander(config.queryExpander); this.log = config.onLog || ((level, msg, meta) => { if ( !config.logLevel || config.logLevel === "info" || level !== "info" ) { // eslint-disable-next-line no-console console.log(`[${level}]`, msg, meta || ""); } }); this.metric = config.onMetric || (() => {}); } /** * RSS → Content → Summary 전체 파이프라인 실행 */ public async runPipeline() { this.log("info", "Starting RAG pipeline"); for (const feedCfg of this.config.rssFeeds) { try { const parser = new RSSFetcher([feedCfg]); // 실제 서비스에서는 스케줄러가 아닌 단발성 fetch로 처리 const feed = await parser["parser"].parseURL(feedCfg.url); for (const item of feed.items) { const doc: RSSDocument = parser["toDocument"](item, feedCfg.url); this.log("debug", "Fetched RSS item", doc); const mainContent = extractMainContent( doc.content, this.config.extractor ); this.log("debug", "Extracted main content", { mainContent }); const summary: SummarizationResult = await this.summarizer.summarize( mainContent, { ...doc } ); this.log("info", "Summarized content", { summary }); this.metric("summary_generated", { feed: feedCfg.url }); // TODO: 벡터스토어 저장 등 후처리 } } catch (err) { this.log("error", "Pipeline error", err); this.metric("pipeline_error", { feed: feedCfg.url, error: err }); } } this.log("info", "RAG pipeline completed"); } /** * 질의 확장 및 재구성 */ public expandQuery(query: string): { type: QueryType; expanded: string; reformulated: string; } { const type = this.queryExpander.classify(query); const expanded = this.queryExpander.expand(query, type); const reformulated = this.queryExpander.reformulate(expanded); this.log("debug", "Query expanded", { query, type, expanded, reformulated, }); this.metric("query_expanded", { query, type }); return { type, expanded, reformulated }; } /** * 피드백 기록 */ public feedback( original: string, reformulated: string, success: boolean, notes?: string ) { this.queryExpander.feedback(original, reformulated, success, notes); this.metric("feedback", { original, reformulated, success }); } /** * 피드백 전체 조회 */ public getFeedbacks() { return this.queryExpander.getFeedbacks(); } } /** * 사용 예시: * * const rag = new AgentcRAG({ * rssFeeds: [{ url: 'https://example.com/rss', interval: '0 * * * *' }], * summarizer: { apiKey: 'sk-xxx' }, * logLevel: 'info', * onLog: (level, msg, meta) => { ... }, * onMetric: (event, data) => { ... }, * }); * * await rag.runPipeline(); * const q = rag.expandQuery('AI?'); * rag.feedback('AI?', q.reformulated, true, '정확한 답변'); */