lily_fast_api / docs /API_REFERENCE.md
gbrabbit's picture
Fresh start for HF Spaces deployment
526927a
|
Raw History Blame Contribute Delete
10.4 kB
# Lily LLM API μ°Έμ‘° λ¬Έμ„œ
## πŸ“‹ κ°œμš”
Lily LLM APIλŠ” λ‹€μ–‘ν•œ μ–Έμ–΄ λͺ¨λΈμ„ μ§€μ›ν•˜λŠ” RESTful API μ„œλ²„μž…λ‹ˆλ‹€. ν…μŠ€νŠΈ 생성, λ©€ν‹°λͺ¨λ‹¬ 처리, RAG(Retrieval-Augmented Generation) κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.
## πŸ”— κΈ°λ³Έ 정보
- **Base URL**: `http://localhost:8001`
- **API λ¬Έμ„œ**: `http://localhost:8001/docs`
- **ReDoc λ¬Έμ„œ**: `http://localhost:8001/redoc`
## πŸ” 인증
### JWT 토큰 인증
```bash
# 둜그인
curl -X POST "http://localhost:8001/auth/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=your_username&password=your_password"
# 응닡
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer"
}
```
### 보호된 μ—”λ“œν¬μΈνŠΈ μ‚¬μš©
```bash
curl -X GET "http://localhost:8001/auth/me" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
## πŸ€– AI λͺ¨λΈ κ΄€λ ¨
### 1. λͺ¨λΈ λͺ©λ‘ 쑰회
```http
GET /models
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"available_models": [
{
"model_id": "polyglot-ko-1.3b-chat",
"display_name": "Polyglot Korean 1.3B Chat",
"model_type": "text",
"description": "ν•œκ΅­μ–΄ νŠΉν™” ν…μŠ€νŠΈ 생성 λͺ¨λΈ"
},
{
"model_id": "kanana-1.5-v-3b-instruct",
"display_name": "Kanana 1.5 v3B Instruct",
"model_type": "multimodal",
"description": "λ©€ν‹°λͺ¨λ‹¬ 이미지+ν…μŠ€νŠΈ 처리 λͺ¨λΈ"
}
],
"current_model": "polyglot-ko-1.3b-chat"
}
```
### 2. ν…μŠ€νŠΈ 생성
```http
POST /generate
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"prompt": "μ•ˆλ…•ν•˜μ„Έμš”, AI에 λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”.",
"model_id": "polyglot-ko-1.3b-chat",
"max_length": 200,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": true
}
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"generated_text": "μ•ˆλ…•ν•˜μ„Έμš”! AI(인곡지λŠ₯)λŠ” μΈκ°„μ˜ ν•™μŠ΅λŠ₯λ ₯κ³Ό μΆ”λ‘ λŠ₯λ ₯을 인곡적으둜 κ΅¬ν˜„ν•œ 컴퓨터 μ‹œμŠ€ν…œμž…λ‹ˆλ‹€...",
"model_name": "polyglot-ko-1.3b-chat",
"processing_time": 2.34,
"tokens_generated": 45
}
```
### 3. λ©€ν‹°λͺ¨λ‹¬ 생성 (이미지 + ν…μŠ€νŠΈ)
```http
POST /generate-multimodal
```
**μš”μ²­ (multipart/form-data):**
```
prompt: "이 이미지에 λŒ€ν•΄ μ„€λͺ…ν•΄μ£Όμ„Έμš”"
model_id: "kanana-1.5-v-3b-instruct"
max_length: 200
temperature: 0.7
image_files: [파일1, 파일2, ...]
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"generated_text": "이 μ΄λ―Έμ§€λŠ” μ•„λ¦„λ‹€μš΄ μžμ—° 풍경을 λ³΄μ—¬μ€λ‹ˆλ‹€...",
"model_name": "kanana-1.5-v-3b-instruct",
"processing_time": 15.67,
"images_processed": 2
}
```
## πŸ“„ λ¬Έμ„œ 처리 (RAG)
### 1. λ¬Έμ„œ μ—…λ‘œλ“œ
```http
POST /document/upload
```
**μš”μ²­ (multipart/form-data):**
```
file: [PDF/DOC/DOCX/PPTX 파일]
user_id: "user123"
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"document_id": "doc_123456",
"filename": "sample.pdf",
"file_type": "pdf",
"file_size": 1024000,
"pages": 15,
"chunks": 45,
"upload_time": "2025-08-04T10:30:00Z"
}
```
### 2. RAG 쿼리
```http
POST /rag/generate
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"query": "인곡지λŠ₯의 λ―Έλž˜μ— λŒ€ν•΄ μ•Œλ €μ£Όμ„Έμš”",
"user_id": "user123",
"max_length": 300,
"temperature": 0.7
}
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"response": "인곡지λŠ₯의 λ―Έλž˜λŠ” 맀우 λ°μŠ΅λ‹ˆλ‹€. ν˜„μž¬ λ¬Έμ„œμ— λ”°λ₯΄λ©΄...",
"sources": [
{
"document_id": "doc_123456",
"page": 5,
"chunk": "AI 기술의 λ°œμ „ λ°©ν–₯..."
}
],
"confidence": 0.85,
"processing_time": 3.45
}
```
### 3. ν•˜μ΄λΈŒλ¦¬λ“œ RAG (이미지 + λ¬Έμ„œ)
```http
POST /rag/generate-hybrid
```
**μš”μ²­ (multipart/form-data):**
```
query: "이 이미지와 κ΄€λ ¨λœ λ¬Έμ„œ λ‚΄μš©μ„ μ°Ύμ•„μ£Όμ„Έμš”"
user_id: "user123"
image_files: [이미지 νŒŒμΌλ“€]
max_length: 300
temperature: 0.7
```
## πŸ’¬ μ±„νŒ… 및 μ„Έμ…˜ 관리
### 1. μ‚¬μš©μž 생성
```http
POST /user/create
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"user_id": "user123",
"username": "ν…ŒμŠ€νŠΈμ‚¬μš©μž",
"email": "test@example.com"
}
```
### 2. μ±„νŒ… μ„Έμ…˜ 생성
```http
POST /session/create
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"user_id": "user123",
"session_name": "AI 상담 μ„Έμ…˜"
}
```
### 3. λ©”μ‹œμ§€ μΆ”κ°€
```http
POST /chat/message
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"session_id": "session_123",
"user_id": "user123",
"message_type": "text",
"content": "μ•ˆλ…•ν•˜μ„Έμš”!"
}
```
### 4. μ±„νŒ… 기둝 쑰회
```http
GET /chat/history/{session_id}
```
## πŸ”„ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…
### 1. λ¬Έμ„œ 처리 μž‘μ—…
```http
POST /tasks/document/process
```
**μš”μ²­ νŒŒλΌλ―Έν„°:**
```json
{
"file_path": "/uploads/document.pdf",
"user_id": "user123"
}
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"task_id": "task_123456",
"status": "PENDING",
"message": "λ¬Έμ„œ 처리 μž‘μ—…μ΄ μ‹œμž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€."
}
```
### 2. μž‘μ—… μƒνƒœ 확인
```http
GET /tasks/{task_id}
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"task_id": "task_123456",
"status": "SUCCESS",
"result": {
"document_id": "doc_123456",
"chunks": 45
},
"progress": 100
}
```
## πŸ“Š λͺ¨λ‹ˆν„°λ§
### 1. μ„±λŠ₯ λͺ¨λ‹ˆν„°λ§ μ‹œμž‘
```http
POST /monitoring/start
```
### 2. μ„±λŠ₯ μƒνƒœ 쑰회
```http
GET /monitoring/status
```
**응닡 μ˜ˆμ‹œ:**
```json
{
"current_metrics": {
"cpu_percent": 25.5,
"memory_percent": 68.2,
"memory_used_mb": 8192.0,
"disk_usage_percent": 45.0
},
"performance_stats": {
"avg_response_time": 1.23,
"avg_inference_time": 2.45,
"total_requests": 1250,
"success_rate": 98.5
},
"system_health": {
"status": "healthy",
"recommendations": []
}
}
```
### 3. μ‹œμŠ€ν…œ 건강 μƒνƒœ
```http
GET /monitoring/health
```
## πŸ”Œ WebSocket
### μ—°κ²°
```javascript
const ws = new WebSocket('ws://localhost:8001/ws/user123');
ws.onopen = function() {
console.log('WebSocket 연결됨');
};
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('λ©”μ‹œμ§€ μˆ˜μ‹ :', data);
};
```
### λ©”μ‹œμ§€ 전솑
```javascript
ws.send(JSON.stringify({
type: 'chat',
message: 'μ•ˆλ…•ν•˜μ„Έμš”!',
session_id: 'session_123'
}));
```
## 🚨 였λ₯˜ μ½”λ“œ
| μ½”λ“œ | 의미 | ν•΄κ²° 방법 |
|------|------|-----------|
| 400 | 잘λͺ»λœ μš”μ²­ | μš”μ²­ νŒŒλΌλ―Έν„° 확인 |
| 401 | 인증 μ‹€νŒ¨ | 토큰 확인 |
| 403 | κΆŒν•œ μ—†μŒ | κΆŒν•œ 확인 |
| 404 | λ¦¬μ†ŒμŠ€ μ—†μŒ | URL 확인 |
| 422 | 검증 μ‹€νŒ¨ | μš”μ²­ 데이터 ν˜•μ‹ 확인 |
| 500 | μ„œλ²„ 였λ₯˜ | μ„œλ²„ 둜그 확인 |
| 503 | μ„œλΉ„μŠ€ λΆˆκ°€ | μ„œλΉ„μŠ€ μƒνƒœ 확인 |
## πŸ“ 예제 μ½”λ“œ
### Python ν΄λΌμ΄μ–ΈνŠΈ
```python
import requests
import json
class LilyLLMClient:
def __init__(self, base_url="http://localhost:8001"):
self.base_url = base_url
self.token = None
def login(self, username, password):
response = requests.post(f"{self.base_url}/auth/login",
data={"username": username, "password": password})
if response.status_code == 200:
self.token = response.json()["access_token"]
return True
return False
def generate_text(self, prompt, model_id="polyglot-ko-1.3b-chat"):
headers = {"Authorization": f"Bearer {self.token}"} if self.token else {}
data = {
"prompt": prompt,
"model_id": model_id,
"max_length": 200,
"temperature": 0.7
}
response = requests.post(f"{self.base_url}/generate",
data=data, headers=headers)
return response.json()
def upload_document(self, file_path, user_id):
headers = {"Authorization": f"Bearer {self.token}"} if self.token else {}
with open(file_path, 'rb') as f:
files = {'file': f}
data = {'user_id': user_id}
response = requests.post(f"{self.base_url}/document/upload",
files=files, data=data, headers=headers)
return response.json()
# μ‚¬μš© 예제
client = LilyLLMClient()
if client.login("username", "password"):
result = client.generate_text("μ•ˆλ…•ν•˜μ„Έμš”!")
print(result["generated_text"])
```
### JavaScript ν΄λΌμ΄μ–ΈνŠΈ
```javascript
class LilyLLMClient {
constructor(baseUrl = 'http://localhost:8001') {
this.baseUrl = baseUrl;
this.token = null;
}
async login(username, password) {
const response = await fetch(`${this.baseUrl}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=${username}&password=${password}`
});
if (response.ok) {
const data = await response.json();
this.token = data.access_token;
return true;
}
return false;
}
async generateText(prompt, modelId = 'polyglot-ko-1.3b-chat') {
const headers = this.token ?
{'Authorization': `Bearer ${this.token}`} : {};
const formData = new FormData();
formData.append('prompt', prompt);
formData.append('model_id', modelId);
formData.append('max_length', '200');
formData.append('temperature', '0.7');
const response = await fetch(`${this.baseUrl}/generate`, {
method: 'POST',
headers,
body: formData
});
return await response.json();
}
}
// μ‚¬μš© 예제
const client = new LilyLLMClient();
client.login('username', 'password').then(async (success) => {
if (success) {
const result = await client.generateText('μ•ˆλ…•ν•˜μ„Έμš”!');
console.log(result.generated_text);
}
});
```
## πŸ”§ μ„€μ •
### ν™˜κ²½ λ³€μˆ˜
```bash
# μ„œλ²„ μ„€μ •
HOST=0.0.0.0
PORT=8001
LOG_LEVEL=INFO
# λ°μ΄ν„°λ² μ΄μŠ€
DATABASE_URL=sqlite:///app/data/lily_llm.db
# Redis
REDIS_URL=redis://localhost:6379
# Celery
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0
# λ³΄μ•ˆ
SECRET_KEY=your-secret-key
JWT_SECRET_KEY=your-jwt-secret-key
```
## πŸ“š μΆ”κ°€ λ¦¬μ†ŒμŠ€
- [FastAPI λ¬Έμ„œ](https://fastapi.tiangolo.com/)
- [Celery λ¬Έμ„œ](https://docs.celeryproject.org/)
- [Redis λ¬Έμ„œ](https://redis.io/documentation)
- [LangChain λ¬Έμ„œ](https://python.langchain.com/)