Gemini API ๋ชจ๋ฒ ์ฌ๋ก: ๊ณ ์ฑ๋ฅ AI ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ
Gemini API ๋ชจ๋ฒ ์ฌ๋ก: ๊ณ ์ฑ๋ฅ AI ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ
Google Gemini API๋ ๊ฐ๋ฐ์์๊ฒ ๊ฐ๋ ฅํ AI ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์ BananaImg ํ๋ซํผ์ ๊ฐ๋ฐํ๋ฉด์ ์ถ์ ํ ์ค์ ๊ฒฝํ์ ๊ณต์ ํฉ๋๋ค.
Gemini API ๊ฐ์
๋ชจ๋ธ ์ ํ ์ ๋ต
| ๋ชจ๋ธ | ์ฌ์ฉ ์ฌ๋ก | ๋น์ฉ | ์๋ |
|---|---|---|---|
| Gemini Pro | ๋ณต์กํ ์์ , ๊ณ ํ์ง ์ถ๋ ฅ | ๋์ | ๋ณดํต |
| Gemini Pro Vision | ์ด๋ฏธ์ง ์ดํด ๋ฐ ์์ฑ | ๋์ | ๋ณดํต |
| Gemini Flash | ๋น ๋ฅธ ์๋ต, ๊ฐ๋จํ ์์ | ๋ฎ์ | ๋น ๋ฆ |
์ฑ๋ฅ ์ต์ ํ ํ
1. ์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ
// ๊ถ์ฅํ์ง ์์: ์ง๋ ฌ ์์ฒญ
for (const prompt of prompts) {
const result = await generateImage(prompt);
results.push(result);
}
// ๊ถ์ฅ: ๋ณ๋ ฌ ์์ฒญ
const results = await Promise.all(
prompts.map(prompt => generateImage(prompt))
);2. ์ค๋งํธ ์บ์ฑ ์ ๋ต
class GeminiCache {
constructor(ttl = 3600) {
this.cache = new Map();
this.ttl = ttl * 1000;
}
async get(key, generator) {
const cached = this.cache.get(key);
if (cached && Date.now() - cached.time < this.ttl) {
return cached.value;
}
const value = await generator();
this.cache.set(key, { value, time: Date.now() });
return value;
}
}3. ์คํธ๋ฆผ ์๋ต ์ฒ๋ฆฌ
async function* streamGeneration(prompt) {
const stream = await gemini.generateContentStream(prompt);
for await (const chunk of stream) {
yield chunk.text();
}
}
// ์คํธ๋ฆผ ์๋ต ์ฌ์ฉ
for await (const text of streamGeneration(prompt)) {
updateUI(text); // ์ค์๊ฐ UI ์
๋ฐ์ดํธ
}๋น์ฉ ์ต์ ํ ์ ๋ต
1. ํ ํฐ ์ฌ์ฉ ์ต์ ํ
์ ๋ ฅ ํ ํฐ ๊ฐ์:
// ์ต์ ํ ์ : ์ฅํฉํ ํ๋กฌํํธ
const prompt = `
Please generate an image of a cat.
The cat should be sitting.
The cat should be orange.
The background should be a garden.
`;
// ์ต์ ํ ํ: ๊ฐ๊ฒฐํ ํ๋กฌํํธ
const prompt = "Orange cat sitting in garden";2. ๋ชจ๋ธ ๋ค์ด๊ทธ๋ ์ด๋ ์ ๋ต
async function intelligentGenerate(prompt, complexity) {
// ์์
๋ณต์ก์ฑ์ ๋ฐ๋ผ ๋ชจ๋ธ ์ ํ
const model = complexity > 0.7
? 'gemini-pro'
: 'gemini-flash';
return await gemini[model].generate(prompt);
}3. ๊ฒฐ๊ณผ ์ฌ์ฌ์ฉ
// ์ฌ์์ฑ ๋์ ๋ณํ ์์ฑ
async function generateVariations(baseResult) {
const variations = [];
const seeds = [1, 2, 3, 4];
for (const seed of seeds) {
variations.push(
modifyResult(baseResult, { seed })
);
}
return variations;
}์ค๋ฅ ์ฒ๋ฆฌ ๋ชจ๋ฒ ์ฌ๋ก
1. ์ฌ์๋ ๋ฉ์ปค๋์ฆ
async function robustGenerate(prompt, maxRetries = 3) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await gemini.generate(prompt);
} catch (error) {
lastError = error;
if (error.code === 'RATE_LIMIT') {
await sleep(Math.pow(2, i) * 1000); // Exponential backoff
} else if (error.code === 'INVALID_PROMPT') {
throw error; // Non-retryable error
}
}
}
throw lastError;
}2. ํด๋ฐฑ ์ ๋ต
async function generateWithFallback(prompt) {
try {
// ๊ธฐ๋ณธ ๋ชจ๋ธ ์๋
return await gemini.pro.generate(prompt);
} catch (error) {
console.warn('Primary model failed, using fallback');
try {
// ๋ฐฑ์
๋ชจ๋ธ๋ก ๋ค์ด๊ทธ๋ ์ด๋
return await gemini.flash.generate(prompt);
} catch (fallbackError) {
// ๊ธฐ๋ณธ ์๋ต ๋ฐํ
return getDefaultResponse();
}
}
}๋ณด์ ๊ณ ๋ ค ์ฌํญ
1. ์ฝํ ์ธ ํํฐ๋ง
class ContentFilter {
constructor() {
this.bannedWords = new Set([...]);
this.sensitivePatterns = [...];
}
validate(prompt) {
// ๊ธ์ง๋ ๋จ์ด ํ์ธ
for (const word of this.bannedWords) {
if (prompt.toLowerCase().includes(word)) {
throw new Error('Inappropriate content detected');
}
}
// ๋ฏผ๊ฐํ ํจํด ํ์ธ
for (const pattern of this.sensitivePatterns) {
if (pattern.test(prompt)) {
return this.sanitize(prompt);
}
}
return prompt;
}
}2. ์๋ ์ ํ
class RateLimiter {
constructor(maxRequests = 60, window = 60000) {
this.requests = [];
this.maxRequests = maxRequests;
this.window = window;
}
async acquire() {
const now = Date.now();
// ๋ง๋ฃ๋ ์์ฒญ ์ ๋ฆฌ
this.requests = this.requests.filter(
time => now - time < this.window
);
if (this.requests.length >= this.maxRequests) {
const oldestRequest = this.requests[0];
const waitTime = this.window - (now - oldestRequest);
await sleep(waitTime);
return this.acquire();
}
this.requests.push(now);
}
}๋ชจ๋ํฐ๋ง ๋ฐ ๋๋ฒ๊น
1. ์ฑ๋ฅ ์ถ์
class PerformanceMonitor {
async track(operation, fn) {
const start = performance.now();
const result = await fn();
const duration = performance.now() - start;
this.log({
operation,
duration,
timestamp: new Date(),
success: true
});
return result;
}
getStatistics() {
return {
avgResponseTime: this.calculateAverage(),
p95ResponseTime: this.calculatePercentile(95),
successRate: this.calculateSuccessRate()
};
}
}2. ๋ก๊น
class GeminiLogger {
log(level, message, metadata = {}) {
const logEntry = {
timestamp: new Date().toISOString(),
level,
message,
...metadata,
environment: process.env.NODE_ENV
};
if (level === 'error') {
this.sendToMonitoring(logEntry);
}
console.log(JSON.stringify(logEntry));
}
}์ฌ์ฉ์ ๊ฒฝํ ์ต์ ํ
1. ์งํ ์ํฉ ํผ๋๋ฐฑ
async function generateWithProgress(prompt, onProgress) {
onProgress({ stage: 'validating', progress: 0 });
await validatePrompt(prompt);
onProgress({ stage: 'generating', progress: 30 });
const result = await gemini.generate(prompt);
onProgress({ stage: 'processing', progress: 70 });
const processed = await postProcess(result);
onProgress({ stage: 'complete', progress: 100 });
return processed;
}2. ์์ธก์ ๋ก๋ฉ
class PredictiveLoader {
async preload(userBehavior) {
const likelyPrompts = this.predictNextPrompts(userBehavior);
// ์บ์ ์๋ฐ
for (const prompt of likelyPrompts) {
this.cache.warm(prompt);
}
}
}ํตํฉ ๋ชจ๋ฒ ์ฌ๋ก
1. ํ๊ฒฝ ๊ตฌ์ฑ
// config/gemini.js
export const geminiConfig = {
development: {
apiKey: process.env.GEMINI_DEV_KEY,
model: 'gemini-flash',
maxRetries: 5,
timeout: 30000
},
production: {
apiKey: process.env.GEMINI_PROD_KEY,
model: 'gemini-pro',
maxRetries: 3,
timeout: 15000
}
};2. ์์กด์ฑ ์ฃผ์
class GeminiService {
constructor(config, cache, logger) {
this.config = config;
this.cache = cache;
this.logger = logger;
this.client = new GeminiClient(config);
}
async generate(prompt, options = {}) {
const cacheKey = this.getCacheKey(prompt, options);
return await this.cache.get(cacheKey, async () => {
this.logger.log('info', 'Generating content', { prompt });
return await this.client.generate(prompt, options);
});
}
}ํ ์คํธ ์ ๋ต
1. ๋จ์ ํ ์คํธ
describe('GeminiService', () => {
it('should cache repeated requests', async () => {
const service = new GeminiService(mockConfig);
const result1 = await service.generate('test prompt');
const result2 = await service.generate('test prompt');
expect(result1).toBe(result2);
expect(mockClient.generate).toHaveBeenCalledTimes(1);
});
});2. ํตํฉ ํ ์คํธ
describe('Gemini Integration', () => {
it('should handle rate limits gracefully', async () => {
const promises = Array(100).fill(null).map(() =>
service.generate('test')
);
const results = await Promise.allSettled(promises);
const successful = results.filter(r => r.status === 'fulfilled');
expect(successful.length).toBeGreaterThan(0);
});
});์์ฝ
Gemini API ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ง์คํฐํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ด ํฅ์๋ ๋ฟ๋ง ์๋๋ผ ์ด์ ๋น์ฉ๋ ํฌ๊ฒ ์ ๊ฐ๋ฉ๋๋ค. ํต์ฌ ํฌ์ธํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ค๋งํธ ๋ชจ๋ธ ์ ํ
- ํจ์จ์ ์ธ ์บ์ฑ ์ ๋ต
- ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ
- ์ธ๋ถ์ ์ธ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
- ์ฐ์ํ ์ฌ์ฉ์ ๊ฒฝํ
BananaImg์์๋ ์ด๋ฌํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ํ๋ซํผ์ ๋ชจ๋ ๊ตฌ์์ ํตํฉํ์ฌ ์ฌ์ฉ์์๊ฒ ๋น ๋ฅด๊ณ ์์ ์ ์ด๋ฉฐ ๊ณ ํ์ง์ AI ์ด๋ฏธ์ง ์์ฑ ์๋น์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
AI ๊ฐ๋ฐ ์ค์ ๊ฒฝํ์ ๋ ๋ง์ด ์์๋ณด๋ ค๋ฉด ๋ธ๋ก๊ทธ๋ฅผ ๊ณ์ ํ๋ก์ฐํ์ธ์!
์ด ๊ธฐ์ฌ ๊ณต์ ํ๊ธฐ
๊ด๋ จ ๊ธฐ์ฌ
Nano Banana ๊ธฐ์ : Google์ AI ์ด๋ฏธ์ง ๋ชจ๋ธ ์๋ ๋ฐฉ์
Nano Banana ๋ค์ ์๋ ๊ธฐ์ ์ ํ์ํ์ธ์. Google์ Gemini 2.5 Flash๊ฐ ๋งฅ๋ฝ์ ์ดํด์ ๋ํํ ํธ์ง์ผ๋ก AI ์ด๋ฏธ์ง ์์ฑ์ ๊ฐํํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ์ธ์.
Nano Banana vs Nano Banana Pro: ์๋ฒฝํ ๋น๊ต ๊ฐ์ด๋
Nano Banana์ Nano Banana Pro์ ์ฃผ์ ์ฐจ์ด์ ์ ์์๋ณด์ธ์. ๊ธฐ๋ฅ, ํด์๋, ํ ์คํธ ๋ ๋๋ง, ๊ฐ๊ฒฉ์ ๋น๊ตํ์ฌ ์ฌ๋ฐ๋ฅธ AI ์ด๋ฏธ์ง ๋ชจ๋ธ์ ์ ํํ์ธ์.
ํ๋กฌํํธ ์์ง๋์ด๋ง์ ๊ธฐ์ ๊ณผ ๊ณผํ
ํ๋กฌํํธ ์์ง๋์ด๋ง์ ํต์ฌ ๊ธฐ๋ฒ์ ๋ง์คํฐํ๊ณ AI๊ฐ ๋น์ ์ ์ฐฝ์ ์๋๋ฅผ ์๋ฒฝํ๊ฒ ์ดํดํ๋๋ก ๋ง๋์ธ์.