1. 랭체인 이미지 인식 후 처리 마무리

2. fastAPI로 프로젝트 구조 실습

1. 랭체인 이미지 인식 후 처리 마무리
2. fastAPI로 프로젝트 구조 실습
This commit is contained in:
2026-06-15 18:08:35 +09:00
parent d6be22857b
commit ccfdac1286
59 changed files with 3144 additions and 133 deletions
+9
View File
@@ -0,0 +1,9 @@
from langchain_ibm import WatsonxEmbeddings
from backend.config.settings import settings
watson_embedding = WatsonxEmbeddings(
model_id="ibm/granite-embedding-278m-multilingual",
url=f"{settings.watsonx_url}",
api_key=f"{settings.watsonx_api_key}",
project_id=f"{settings.watsonx_project_id}",
)
+13
View File
@@ -0,0 +1,13 @@
from langchain_ibm import ChatWatsonx
from backend.config.settings import settings
watson_llm = ChatWatsonx(
model_id="ibm/granite-4-h-small",
url=f"{settings.watsonx_url}",
api_key=f"{settings.watsonx_api_key}",
project_id=f"{settings.watsonx_project_id}",
max_tokens=2000,
params={
"temperature": 0
}
)
@@ -0,0 +1,11 @@
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file="backend/.env", extra="ignore")
# 사용할 모델
watsonx_api_key: str = Field(alias="WATSONX_API_KEY")
watsonx_project_id: str = Field(alias="WATSONX_PROJECT_ID")
watsonx_url: str = Field(alias="WATSONX_URL")
settings = Settings()
+16
View File
@@ -0,0 +1,16 @@
from fastapi import FastAPI
from starlette.staticfiles import StaticFiles
from backend.routers.page_router import router as page_router
from backend.routers.api_router import router as api_router
app = FastAPI()
app.include_router(page_router)
app.include_router(api_router)
# static 폴더 지정
app.mount("/static", StaticFiles(directory="backend/static"), name="static")
# http://127.0.0.1:8000/item/1 + GET
# @app.get("/item/{item_id}")
# async def read_item(item_id):
# return {"item_id" : item_id}
@@ -0,0 +1,25 @@
from fastapi import APIRouter, Request, UploadFile
from backend.services.llm_service import question_and_answer
from backend.schemas.basic_schema import QuestionRequest
from backend.services.rag_service import upload_document
router = APIRouter(prefix="/api")
# http://127.0.0.1:8000/api/question
@router.post("/question")
async def question(req:QuestionRequest):
answer = question_and_answer(req.question)
return {"message" : answer}
# http://127.0.0.1:8000/api/rag/upload
@router.post("/rag/upload")
async def fileUpload(file:UploadFile):
# 서비스 호출
return upload_document(file)
# http://127.0.0.1:8000/api/rag/question
@router.post("/rag/question")
async def question():
pass
@@ -0,0 +1,15 @@
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
router = APIRouter()
templates = Jinja2Templates(directory="backend/templates")
# http://127.0.0.1:8000
@router.get("/")
async def home(request : Request):
return templates.TemplateResponse(request = request, name="index.html")
@router.get("/rag")
async def rag(request : Request):
return templates.TemplateResponse(request = request, name="rag.html")
@@ -0,0 +1,5 @@
from pydantic import BaseModel
class QuestionRequest(BaseModel):
question : str
@@ -0,0 +1,8 @@
from backend.ai.llm import watson_llm
# LLM 모델 통신
# 데이터베이스 통신
def question_and_answer(question):
response = watson_llm.invoke(question)
return response.content
@@ -0,0 +1,6 @@
# pdf 업로드 => 분할 => 인덱스 생성
def upload_document(file):
pass
# 질문 => 유사도 검색 => 문서 => llm 답변 생성
@@ -0,0 +1,44 @@
document.querySelector("button").addEventListener("click", ask)
async function ask() {
// 사용자가 질문 입력 시 질문을 서버로 전송
const question = document.querySelector('#question').value
const response = await fetch("/api/question", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({question : question})
})
// 전송 후 answer 도착 시 answer 화면에 보여주기
const answer = await response.json()
document.querySelector('#answer').textContent = answer.message
}
// 파일 업로드
document.querySelector("#uploadBtn").addEventListener("click", uploadFile)
async function uploadFile()
{
const fileInput = document.querySelector("#file");
// 첨부파일 정보 가져오기
const file = fileInput.files[0];
if(!file)
{
alert("파일을 선택해주세요.");
return;
}
// form 만들어 전송
const formData = new FormData()
formData.append("file", file)
const response = await fetch("/api/reg/question", {
method: "POST",
body: formData
})
// 전송 후 answer 도착 시 answer 화면에 보여주기
const answer = await response.json()
document.querySelector('#answer').textContent = answer.message
}
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>HOME</h1>
<ul>
<a href="/rag">RAG</a>
</ul>
<div>
<input type="text" name="question" id="question">
<button type="submit">질문</button>
</div>
<div id="answer"></div>
<script src="{{ url_for('static', path='js/index.js')}}"></script>
</body>
</html>
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>RAG</h2>
<div>
<input type="file" name="file" id="file">
<button id="uploadBtn">업로드</button>
</div>
<hr>
<div id="result"></div>
<script src="{{ url_for('static', path='js/index.js')}}"></script>
</body>
</html>