본문 바로가기
🟣 AI & ML

LangServe를 이용해 LangChain 앱을 API로 이용하기

by 제리강 2024. 9. 7.

 

 
LangChain 으로 LLM 기반 Chain 객체를 만들면, 이를 API로 구성하여 앱에서 이용하거나 원격으로 접근하여 공용으로 사용하게 할 수 있습니다. 
Python 기반 백엔드를 API로 구성하려면 Flask, FastAPI로 직접 구성할 수 있겠지만 LangChain에서는 이미 LangServe라고 하여 간편히 배포할 수 있는 도구를 제공합니다.
 
LangServe 문서
 
LangServe는 이미 FastAPI 및 uvicorn을 기반으로 만들어져 있으므로, FastAPI에 익숙하다면 유사한 인터페이스로 이용할 수 있습니다. 본 예제에서는 OpenAI 언어 모델을 LangChain 객체로 변환한 간단한 구조의 API를 구성해볼 것입니다. 다음과 같이 langserve_server.py 라는 이름의 파일을 작성해봅시다.
 

from fastapi import FastAPI
from langchain_openai import ChatOpenAI
from langserve import add_routes

app = FastAPI(
    title="test_langserve_server"
)

model = ChatOpenAI(model="gpt-4o", openai_api_key="{사용자 API 키 입력}")

add_routes(
    app,
    model,
    path="/openai"
)

@app.get("/")
async def root():
    return {"message": "welcome to test_langserve_server"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("langserve_server:app", host="0.0.0.0", port=8000, reload=True)

 
이제 python langserve_server.py 를 실행하여 서버를 배포면, 설정한 host:port 주소(또는 localhost:8000)로 접속하여 root 함수에 에 설정한 메시지를 확인할 수 있습니다.
 

 
그런데, 콘솔을 확인하니 다음과 같은 오류가 발생하고 있습니다.
 

 
 
FastAPI는 입력 변수를 검증할 때 pydantic 라이브러리를 이용하는데, 현재 LangServe는 최신 버전의 pydantic 과 호환되지 않는 것 같습니다. 콘솔에 언급된 대로 pydantic을 1.10.13 버전으로 낮춰야겠습니다. 이러한 오류는 추후 업데이트가 되면 사라질 수 있습니다. pydantic 버전을 변경한 후, 다시 python langserve_server.py 를 실행하면 다음과 같이 정상적으로 배포가 될 것입니다.
 

 
 
이제 API 문서를 확인해봅시다. host:port 주소 뒤에 /docs 를 붙여 접속해봅시다(예: 0.0.0.0:8000/docs). 
 
 

 
 
배포한 LangChain 객체에 실행할 수 있는 기능들이 나타납니다. invoke와 같은 익숙한 기능들이 보입니다. 참고로, 위에서 언급한 pydantic 버전 변경을 하지 않으면 초록색으로 표시된 POST 기능들이 표시되지 않을 수 있습니다. 이제, 클라이언트 측에서 이 API로 요청을 보내 답변을 받아봅시다. 다음과 같이 requests 모듈을 이용해 간단히 요청을 수행할 수 있습니다.
post 란에 host, port, 설정한 chain 객체명(add_routes에서 path로 설정한 이름) 및 요청할 기능(invoke)을 조합하여 쿼리와 함께 요청을 보냅니다.

 

 

from IPython.display import display, Markdown
import requests

response = requests.post(
    "http://0.0.0.0:8000/openai/invoke",
    json={"input":'사용자 질문'}
)
display(Markdown(response.json()['output']['content']))

 

 
요청에 대한 응답이 잘 오는 것을 알 수 있습니다. 요청은 다양한 형태로 수행할 수 있습니다. LangServe의 RemoteRunnable 옵션을 이용하여, 아예 chain 객체로 받아올 수도 있습니다.

 

 

from langserve import RemoteRunnable
chain = RemoteRunnable("http://0.0.0.0:8000/openai/")
display(Markdown(chain.invoke("사용자 질문").content))

 

 

댓글