1. RAG ?
๊ฒ์(Retrieval) + ๋ต๋ณ ์์ฑ(Generation)์ ๊ฒฐํฉํ ๊ธฐ์ . ๋ง์น ์คํ๋ถ ์ํ์ฒ๋ผ, ํ์ํ ์๋ฃ๋ฅผ ์ฐพ์๋ณด๋ฉด์ ๋ต๋ณํ๋ ๋ฐฉ์.
์ธ๋ถ ๋ฌธ์๋ฅผ ์
๋ก๋ํ๊ณ ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์์ฑํ ๋ ๊ด๋ จ ๋ฌธ์๋ฅผ ๊ฒ์ํด์ LLM์ด ๋ ์ ํํ ๋ต๋ณ์ ์์ฑ.
์ ํ์ํ ๊น?
LLM์ ํ์ต ๋ฐ์ดํฐ์๋ง ์์กด. ํ์ง๋ง RAG๋ฅผ ์ฌ์ฉํ๋ฉด?
- ์ต์ ์ ๋ณด ํ์ฉ ๊ฐ๋ฅ
- ์ฌ๋ด ๋ฌธ์, ๊ฐ์ธ ์๋ฃ ๋ฑ ์ธ๋ถ ์ง์ ํ์ฉ
- Hallucination(ํ์๋ฆฌ) ๊ฐ์
- ๋ต๋ณ์ ์ถ์ฒ ์ถ์ ๊ฐ๋ฅ
2. ๋ฐ๋ชจ
2.1 ์์ฝ
- ๋ฌธ์๋ฅผ ๋ฒกํฐ๋ก ๋ณํํด์ Vector DB์ ์ ์ฅ
- ์ง๋ฌธ๋ ๋ฒกํฐ๋ก ๋ณํํด์ ์ ์ฌํ ๋ฌธ์ ๊ฒ์
- ๊ฒ์ ๊ฒฐ๊ณผ + ์ง๋ฌธ์ LLM์ ์ ๋ฌํด ๋ต๋ณ ์์ฑ
2.2 ์ค๋น
- Gemini key ์์ฑํด์ ๊ฐ์ ธ์ค๊ธฐ
- https://aistudio.google.com/api-keys
2.3 sample.txt ์์ฑ
์งํฌ: "์ฌ๊ธฐ๊น์ง ํผ์ ์ซ์์ฌ ์ค์ ๋ชฐ๋๊ตฐ… ๋ฆฌ๋ฐ์ด."
๋ฆฌ๋ฐ์ด: "๋ ๊ณ์ ๋๋ง์น๊ธฐ๋ง ํ๋ฉด ์ด ์ ์์ ์ค ์์์ง."
์งํฌ: "๋ค๊ฐ ๊ทธ ๋ง์ ๋ณ์ฌ๋ค์ ๋ฒ ๊ณ ์จ ๊ฑธ ์๋ฉด์๋… ํ๋ค๋ฆฌ์ง ์๋ ๋ณด๊ตฐ."
๋ฆฌ๋ฐ์ด: "๊ทธ๊ฑด ๋ค๊ฐ ๋ง๋ ์ ํ์ด์ผ. ๋ค๊ฐ ์ฃฝ์ธ ๊ฑด ๊ทธ์ ์ซ์๊ฐ ์๋๊ณ … ๋ด ๋๋ฃ๋ค์ด์๋ค."
์งํฌ: "์ ์์ด๋ ๊ทธ๋ฐ ๊ฑฐ์ง. ๋๊ฐ ์ณ์์ง ๋ฐ์ง๊ธฐ ์ ์, ๋๊ตฌ๋ฅผ ๋จผ์ ์ ๊ฑฐํ๋๋๊ฐ ๊ฒฐ์ ํ๋ค."
๋ฆฌ๋ฐ์ด: "๋ง ์ฐธ ์ํ๋ค. ๋ง์น ํผํด์์ธ ์ฒ."
์งํฌ: "๋ํฌ๋ค์ ์ธ์ ๋ ‘์ธ๋ฅ์ ์์ ’๋ผ๋ ์ด๋ฆ์ผ๋ก ํ์ด์ ์ ๋นํํ์ง."
๋ฆฌ๋ฐ์ด: "๋ค ์
์์ ๊ทธ๋ฐ ๋ง์ด ๋์ค๋ค๋ ์๊ธฐ์ง๋ ์๋๊ตฐ."
์งํฌ: "๊ทธ๋… ๋ํฌ๋ ๋ด๊ฐ ์ง์น๊ฑฐ์ธ์ด๊ธฐ ๋๋ฌธ์ ์
๋ง๋ผ๊ณ ๋ถ๋ฅด๊ฒ ์ง. ํ์ง๋ง ์ง์ง ์
๋ง๋—"
๋ฆฌ๋ฐ์ด: "์
๋ค๋ฌผ์ด. ๋ค ๋ณ๋ช
๋ฃ์๊ณ ์จ ๊ฑฐ ์๋๋ค."
์งํฌ: "…์ญ์, ๋ํ๋ก ์ค๋ํ ์ ์๋ ์ข
๋ฅ๊ตฐ."
๋ฆฌ๋ฐ์ด: "๋ค๊ฐ ๋ณด์ฌ์คฌ์์. ๋ง๋ก๋ ์๋ฌด๊ฒ๋ ํด๊ฒฐ๋์ง ์๋๋ค๋ ๊ฑธ."
์งํฌ: "๊ทธ๋? ๊ทธ๋ผ ์ง์ง ํ์ผ๋ก ๋๋ด๋ณด์๊ณ . ๋ค๊ฐ ์๋ํ๋ ์๋, ๊ทธ ์นผ์ง… ๋ค ์๊ณ ์๋ค."
๋ฆฌ๋ฐ์ด: "์๋ฉด ์ข์ง. ์ค๋น๋ผ๋ ๋์ด ์์ด๋ผ."
์งํฌ: "๋ํฌ ์ธ๊ฐ์ ์ฐธ ์ด์ํด. ํฌ๋ง์ด ์๋ค๊ณ ๋งํ๋ฉด์๋ ๊ณ์ ์์ผ๋ก ์ค์ง."
๋ฆฌ๋ฐ์ด: "๊ทธ๊ฑด ๋ค๊ฐ ๋ชจ๋ฅด๋ ๋ถ๋ถ์ด์ง. ์ฐ๋ฆฐ ์ ๋ง ์์์๋ ๋ฒํด๋ค๋ ๊ฑธ."
์งํฌ: "๋ฒํฐ๋ฉด ๋ญ๊ฐ ๋จ์ง? ์ด์๋จ์ ์๋ค์ ์ฃ์ฑ
๊ฐ๋ฟ์ผ ํ
๋ฐ."
๋ฆฌ๋ฐ์ด: "๋๊ตด ์ํด ๋ฒํฐ๋์ง ๋ชจ๋ฅด๋๊น ๊ทธ๋ฐ ์๋ฆด ํ์ง."
์งํฌ: "…์ญ์, ๋ค ๋๋น์ ์ธ์ ๋ด๋ ๋ถ์พํด. ๊ทธ ๋ฌดํ์ ๋ค์ ๊ฐ์ถฐ์ง ์ด๊ธฐ๊ฐ."
๋ฆฌ๋ฐ์ด: "๋ค๋์ ๋ฒ ๊ธฐ ์ ๊น์ง๋ ์์ผ๋ก๋ ์ด ํ์ ์ผ ๊ฑฐ๋ค."
์งํฌ: "์ข์. ๊ทธ๋ผ ์๋ก ๋ง๋ฌด๋ฆฌํ์."
๋ฆฌ๋ฐ์ด: "๊ทธ๋. ์ฌ๊ธฐ์ ๋๋ด์—์งํฌ."
2.4 DEMO ์ฝ๋
- demo.js๋ RAG (Retrieval-Augmented Generation) ์์คํ ์ ๊ตฌํ
- ์๋ ์ฝ๋ ๊ตฌํํ๊ณ key๋ฃ๊ธฐ
// demo.js (CommonJS ๋ฐฉ์)
const { GoogleGenAI } = require('@google/genai');
const fs = require('fs');
const ai = new GoogleGenAI({ apiKey: '{ ์ฌใฑใ
ฃ ์ ํค๋ฅผ ๋ฃ์ผ์ธ์~~!!}' });
async function demo() {
console.log('1๋จ๊ณ: FileSearchStore ์์ฑ ์ค...');
const store = await ai.fileSearchStores.create({
config: { displayName: 'class-demo-store' }
});
console.log(`Store ์์ฑ ์๋ฃ: ${store.name}`);
console.log('\n 2๋จ๊ณ: ํ์ผ ์
๋ก๋ ์ค...');
let operation = await ai.fileSearchStores.uploadToFileSearchStore({
file: 'sample.txt',
fileSearchStoreName: store.name,
config: { displayName: 'sample-document' }
});
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 2000));
operation = await ai.operations.get({ operation });
console.log('์ฒ๋ฆฌ ์ค...');
}
console.log('์
๋ก๋ ์๋ฃ!');
console.log('\n3๋จ๊ณ: ์ง๋ฌธํ๊ธฐ...');
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: "์งํฌ์ ๋ํ ์ข ์์ฝํด์ค",
config: {
tools: [{ fileSearch: { fileSearchStoreNames: [store.name] } }]
}
});
console.log('\n ๋ต๋ณ:');
console.log(response.text);
}
demo().catch(console.error);
2.5 DEMO ์คํ
npm init -y
npm install @google/genai
node demo.js
3. RAG ํ์ดํ๋ผ์ธ ํ๋ฆ
3.1 ๋ฌธ์ ์ค๋น ๋จ๊ณ (Indexing ๋จ๊ณ)
- ํ์ผ์ ๋ก๋
- chunking
- ๋ฌธ์๋ฅผ ์์ ์กฐ๊ฐ์ผ๋ก ๋ถํ (์ฑํฐ๋ณ๋ก ๋๋๋ฏ)
- Embedding
- ๊ฐ ์กฐ๊ฐ์ ๋ฒกํฐ(์ซ์ ๋ฐฐ์ด)๋ก ๋ณํ (์๋ฏธ๋ฅผ ์ขํ๋ก ํํ)
- Vector store
- ๋ฒกํฐ๋ฅผ DB์ ์ ์ฅ (๊ฒ์ ๊ฐ๋ฅํ๊ฒ)
- vector : ์๋ฏธ๋ฅผ ์ซ์ ๋ฐฐ์ด๋ก ํํํ ๊ฒ (์: [0.2, -0.5, 0.8, ...]). ๋น์ทํ ์๋ฏธ๋ ๋น์ทํ ์ซ์ ํจํด์ ๊ฐ์ง
3.2 ๊ฒ์ ๋ฐ ์์ฑ ๋จ๊ณ (Query Phase)
- ์ฌ์ฉ์ ์ง๋ฌธ ์
๋ ฅ:
- ์: "์ด ๋ฌธ์์ ํต์ฌ ์์ฝ ์๋ ค์ค"
- ์ง๋ฌธ ์๋ฒ ๋ฉ(Embedding)
- ์ง๋ฌธ์ ๋ฒกํฐ(์ซ์ ๋ฐฐ์ด)๋ก ๋ณํ
- Embedding: ๋จ์ด/๋ฌธ์ฅ์ ๋ฒกํฐ๋ก ๋ณํํ๋ ๊ณผ์ . ๋ง์น ๋จ์ด๋ฅผ ์ง๋์์ ์ขํ๋ก ํํํ๋ ๊ฒ๊ณผ ๊ฐ์
- ๋ฒกํฐ ๊ฒ์(Vector Search): ์ง๋ฌธ ๋ฒกํฐ์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฌธ์ ์กฐ๊ฐ(Chunk)๋ค์ ์ฐพ์
- ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ/์ฝ์ฌ์ธ ์ ์ฌ๋๋ก ๋น๊ต
- ์ฝ์ฌ์ธ ์ ์ฌ๋(Cosine Similarity): ๋ ๋ฒกํฐ๊ฐ ๊ฐ์ ๋ฐฉํฅ์ ๊ฐ๋ฆฌํค๋์ง ์ธก์ . 0~1 ์ฌ์ด ๊ฐ (1์ ๊ฐ๊น์ธ์๋ก ์ ์ฌ)
- ์๋ฏธ์ ์ผ๋ก ๊ฐ์ฅ ๊ด๋ จ ๋์ ๋ฌธ์ Top-K ํ์
- ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ/์ฝ์ฌ์ธ ์ ์ฌ๋๋ก ๋น๊ต
- ๋ฌธ๋งฅ ๊ตฌ์ฑ(Context Assembly)
- ๊ฒ์๋ ๋ฌธ์ ์กฐ๊ฐ๋ค์ ํ๋์ ์ปจํ ์คํธ๋ก ๋ฌถ์ด LLM์๊ฒ ์ ๋ฌ
- ๋ถํ์ํ ์กฐ๊ฐ์ ์ ๊ฑฐํ๊ณ ํต์ฌ ์กฐ๊ฐ๋ง ์ ์ง
- LLM ์์ฑ ๋จ๊ณ
- (์ง๋ฌธ + ๊ฒ์๋ ๋ฌธ์ ์กฐ๊ฐ๋ค)์ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณ ์์ฑ
- ๋ฌธ์ ๊ธฐ๋ฐ ๋ต๋ณ, ์์ฝ, ๋ถ์ ๋ชจ๋ ํด๋น ๋จ๊ณ์์ ์ด๋ฃจ์ด์ง
4. ์ฝ๋ ์ดํดํ๊ธฐ
4.1 ์ฌ์ฉํ API
- Gemini File Search tool

- ์ ๋ฐ๋ชจ์ ๋ฐฉ์.
- ์ฐธ๊ณ
4.2 FileSearchStore ์์ฑ
const store = await ai.fileSearchStores.create({
config: { displayName: 'class-demo-store' }
});
- Vector Database ์ด๊ธฐํ (๋ฒกํฐ = ์ซ์ ๋ฐฐ์ด๋ก ํํ๋ ์๋ฏธ)
- ๋ฌธ์์ ์๋ฒ ๋ฉ ๋ฒกํฐ๋ค์ ์ ์ฅํ ๊ณต๊ฐ ์์ฑ
- ๋ด๋ถ์ ์ผ๋ก ๋ฒกํฐ ์ธ๋ฑ์ค(Vector Index) ๊ตฌ์กฐ ์์ฑ
4.3 ํ์ผ ์ ๋ก๋ ๋ฐ ์ฒ๋ฆฌ
let operation = await ai.fileSearchStores.uploadToFileSearchStore({
file: 'sample.txt',
fileSearchStoreName: store.name,
config: { displayName: 'sample-document' }
});
while (!operation.done) {
await new Promise(resolve => setTimeout(resolve, 2000));
operation = await ai.operations.get({ operation });
}
A. ํ ์คํธ ํ์ผ ์ฝ๊ธฐ
sample.txt ๋ด์ฉ:
"์๋ : ๊ถ๊ธํด. ํ์ง๋ง ๋ค๋ค ๋ฒฝ ๋ฐ์ ์ฃฝ์๋ฟ์ด๋ผ๊ณ ๋ง ํ์์"
B. Chunking (๋ฌธ์ ๋ถํ )
์ฒญํฌ 1: "์๋ : ๊ถ๊ธํด. ํ์ง๋ง ๋ค๋ค ๋ฒฝ ๋ฐ์..."
์ฒญํฌ 2: "๋ฏธ์นด์ฌ: ๋ํฌ ๋ ๋ค ๋ ์ํํ ์๊ธฐ..."
์ฒญํฌ 3: "์๋ฅด๋ฏผ: ๋ง์ฝ ๊ฑฐ์ธ์ด ์์๋ค๋ฉด..."
- ์ ๋ถํ ? : AI๊ฐ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์๋ ์์ด ์ ํ์
- ์ต์ ์ฒญํฌ ํฌ๊ธฐ๋ณดํต : 200~400 ๋จ์ด ์ ๋
C. Embedding (๋ฒกํฐ ๋ณํ)
๊ฐ ์ฒญํฌ๋ฅผ ๊ณ ์ฐจ์ ๋ฒกํฐ๋ก ๋ณํ:
# ๊ฐ๋
์ ์์ (์ค์ ์ฐจ์: 768~1536์ฐจ์)
"์๋ : ๊ถ๊ธํด..." → [0.23, -0.45, 0.89, ..., 0.12] # 768์ฐจ์
"๋ฏธ์นด์ฌ: ๋ํฌ ๋..." → [0.11, -0.33, 0.78, ..., 0.09]
- ์๋ฏธ์ ์ผ๋ก ์ ์ฌํ ํ ์คํธ → ๊ฐ๊น์ด ๋ฒกํฐ๋ก ๋ณํ
- ์: "์๋ ์ ๊ฟ"๊ณผ "์๋ ์ ๋ชฉํ"๋ ๋ฒกํฐ ๊ณต๊ฐ์์ ๊ฐ๊น์
- BERT ๊ฐ์ ์ธ์ด ์ดํด AI ๋ชจ๋ธ ์ฌ์ฉํด์ ๋ฒกํฐํ
D. Vector Store์ ์ ์ฅ
[๋ฒกํฐ DB]
ID | Vector (768์ฐจ์) | ์๋ณธ ํ
์คํธ
------+---------------------------+------------------
doc1 | [0.23, -0.45, ...] | "์๋ : ๊ถ๊ธํด..."
doc2 | [0.11, -0.33, ...] | "๋ฏธ์นด์ฌ: ๋ํฌ..."
doc3 | [-0.05, 0.67, ...] | "์๋ฅด๋ฏผ: ๋ง์ฝ..."
4.4 ์ง๋ฌธ ๋ฐ ๋ต๋ณ ์์ฑ
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: "๋ํ ๋ด์ฉ์ข ์์ฝํด๋ด",
config: {
tools: [{ fileSearch: { fileSearchStoreNames: [store.name] } }]
}
});
A: ์ง๋ฌธ Embedding
์ง๋ฌธ: "์งํฌ์ ์์
์ ๋๋์ฒด ๋ญ์ง?"
↓ (Embedding ๋ชจ๋ธ)
query_vector = [0.34, -0.12, 0.88, ..., 0.45] // 768์ฐจ์
B. Vector Similarity Search (๋ฒกํฐ ์ ์ฌ๋ ๊ฒ์)

similarity(query_vector, doc_vector) = (query · doc) / (||query|| × ||doc||)
# ๊ฒฐ๊ณผ ์์:
doc1: 0.87 <- "์๋ ๊ณผ ์งํฌ์ ๋ํ" (๋์ ์ ์ฌ๋)
doc2: 0.32 <- "๋ฏธ์นด์ฌ์ ๋
๋ฐฑ" (๋ฎ์ ์ ์ฌ๋)
doc3: 0.91 <- "์งํฌ์ ์ง์ง ๊ณํ" (๊ฐ์ฅ ๋์ ์ ์ฌ๋!)
C: Context ๊ตฌ์ฑ
LLM์ ์ ๋ฌํ ํ๋กฌํํธ ๊ตฌ์ฑ:
[์์คํ
ํ๋กฌํํธ]
๋ค์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด์ ์ง๋ฌธ์ ๋ต๋ณํ์ธ์.
[๊ฒ์๋ ๋ฌธ์]
1. "์๋ฅด๋ฏผ: ์งํฌ์ ๊ณํ์ ๋ชจ๋ ์๋์์ธ์ ์์ ๋ฅ๋ ฅ์ ์์ ๋ ๊ฑฐ์ผ..."
2. "์๋ : ์งํฌ ํ์ ์์ ๋ง์ ํด๊ฒฐ์ฑ
์ ๊ฐ์ง๊ณ ์์ด..."
3. "์งํฌ: ๋ด ์ง์ง ๋ชฉ์ ์ ์๋์์ธ์ ๊ณ ํต์ ๋๋ด๋ ๊ฒ..."
[์ฌ์ฉ์ ์ง๋ฌธ]
์งํฌ์ ์์
์ ๋๋์ฒด ๋ญ์ง?
[๋ต๋ณ ์์ฑ]
D: LLM ์์ฑ
Gemini-2.5-Flash๊ฐ:
- ๊ฒ์๋ ๋ฌธ์ ์ดํด
- ์ง๋ฌธ๊ณผ ๋ฌธ์๋ฅผ ์ข ํฉ (Cross-Attention: ์ง๋ฌธ๊ณผ ๋ฌธ์์ ์ด๋ ๋ถ๋ถ์ด ๊ด๋ จ์๋์ง ํ์ )
- ๋ต๋ณ ์์ฑ (ํ ๋จ์ด์ฉ ์์ฐจ์ ์ผ๋ก)
์ถ๋ ฅ: "์งํฌ์ ์์
์ ์๋์์ธ์ ์์ ๋ฅ๋ ฅ์ ์ ๊ฑฐํ์ฌ
๊ฑฐ์ธ์ ์ญ์ฌ๋ฅผ ํํ๋กญ๊ฒ ๋๋ด๋ ค๋ ๊ฒ์
๋๋ค..."
5. ์ฐธ๊ณ : ์น ๊ธฐ๋ฐ ๊ตฌํ
5.1์ํคํ ์ฒ ๊ฐ์
์ฝ์ ๋ฐ๋ชจ๋ ๋ก์ปฌ ํ์ผ์ ์ง์ ์ฝ์ง๋ง, ์ค์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ํด๋ผ์ด์ธํธ-์๋ฒ ๊ตฌ์กฐ๊ฐ ํ์ํจ.
- Browser (React)
- text ์ ๋ ฅ
- ์ง๋ฌธ ์ ๋ ฅ
- WAS(Express Server)
- file ์์ฑ ๋ฐ ์ ์ฅ
- API ํธ์ถ
- Gemini API(File Search)
- Vector ์ ์ฅ
- ๊ฒ์์ํ
5.2๋ฐ์ดํฐ ํ๋ฆ
1. ํ์ผ ์ ๋ก๋ ์ํ์ค:
- ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉ์๊ฐ ํ ์คํธ ์ ๋ ฅ
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ POST ์์ฒญ ์ ์ก (ํ ์คํธ ๋ด์ฉ ํฌํจ)
- ์๋ฒ๊ฐ ํ ์คํธ๋ฅผ ํ์ผ๋ก ์ ์ฅ (temp ๋๋ ํ ๋ฆฌ)
- ์๋ฒ๊ฐ ์ ์ฅ๋ ํ์ผ์ Gemini File Search Store์ ์ ๋ก๋
- Gemini API๊ฐ ํ์ผ์ Vector๋ก ๋ณํ (Chunking + Embedding)
- Vector ๋ณํ ์๋ฃ๊น์ง ๋๊ธฐ (Operation Polling)
- ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์ฑ๊ณต ์๋ต ๋ฐํ
- ๋ธ๋ผ์ฐ์ ์ ์ ๋ก๋ ์๋ฃ ๋ฉ์์ง ํ์
2. ๊ฒ์ ์ํ์ค:
- ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉ์๊ฐ ์ง๋ฌธ ์ ๋ ฅ
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ POST ์์ฒญ ์ ์ก (์ง๋ฌธ ๋ด์ฉ ํฌํจ)
- ์๋ฒ๊ฐ File Search Store ์ ๋ณด ์กฐํ
- ์๋ฒ๊ฐ Gemini API์ ์ง๋ฌธ + Store ์ ๋ณด ์ ๋ฌ
- Gemini API๊ฐ Vector ์ ์ฌ๋ ๊ฒ์์ผ๋ก ๊ด๋ จ ๋ฌธ์ ์ฐพ๊ธฐ
- Gemini API๊ฐ ๊ฒ์๋ ๋ฌธ์ ๊ธฐ๋ฐ์ผ๋ก LLM ๋ต๋ณ ์์ฑ
- ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ๋ต๋ณ ๋ฐํ
- ๋ธ๋ผ์ฐ์ ์ ๋ต๋ณ ํ์
5.3 ์ฝ๋ ์์
server/services/geminiService.js - ํ์ผ ์ ๋ก๋:
export async function uploadToFileSearchStore(storeName, filePath, displayName) {
let operation = await ai.fileSearchStores.uploadToFileSearchStore({
file: filePath,
fileSearchStoreName: storeName,
config: { displayName }
});
let retryCount = 0;
const MAX_RETRIES = 60;
while (retryCount < MAX_RETRIES) {
await new Promise(resolve => setTimeout(resolve, 2000));
operation = await ai.operations.get({ operation });
// done์ด true๊ฐ ๋๋ฉด Vectorํ ์๋ฃ
if (operation?.done === true) {
return operation;
}
retryCount++;
}
throw new Error('ํ์ผ ์
๋ก๋ ํ์์์');
}
server/services/geminiService.js - ๊ฒ์:
export async function queryWithFileSearch(storeName, query) {
const result = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: query,
config: {
tools: [{
fileSearch: {
fileSearchStoreNames: [storeName]
}
}]
}
});
return result;
}'๐ WEB' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์น ํ๋ก ํธ์๋ ์ฑ๋ฅ ์ต์ ํ (0) | 2026.01.26 |
|---|---|
| ์น ์ฌ์ดํธ ์ต์ ํ ๋ฐฉ๋ฒ (0) | 2026.01.19 |
| HTTP Multipart/form-data ์ง์ ํ์ ๋ง๋ค๋ฉฐ ์๋ฆฌ ์ดํดํ๊ธฐ (0) | 2025.10.01 |
| Node.js๋ก ๊ณ ์ฑ๋ฅ ์น์๋ฒ ๋ง๋ค๊ธฐ: Cluster์ Worker Threads (0) | 2025.09.28 |
| HTTP ํจํท ๋ถ์ํ๊ธฐ (0) | 2025.09.18 |