본문으로 건너뛰기

[Open WebUI] 공유 채팅 목록에서 불필요한 JSON 역직렬화를 제거하여 응답 속도 개선

PR 링크: open-webui/open-webui#21614 상태: Merged | 변경: +25 / -14

들어가며

Open WebUI의 GET /chats/shared 엔드포인트는 공유된 채팅 목록을 반환합니다. 기존 구현에서는 전체 Chat 행을 로드한 후, 대화 이력 전체가 담긴 대용량 JSON 블롭까지 역직렬화했습니다. 하지만 실제로 응답에 필요한 필드는 id, title, share_id, updated_at, created_at 5개뿐이었습니다. 이 PR은 SQLAlchemy의 with_entities()를 사용하여 필요한 컬럼만 SELECT하도록 변경합니다.

핵심 코드 분석

Before: 전체 Chat 행 로드 후 변환

def get_shared_chat_list_by_user_id(
    self, ..., db: Optional[Session] = None,
) -> list[ChatModel]:
    # ... 쿼리 구성 ...
    all_chats = query.all()
    return [ChatModel.model_validate(chat) for chat in all_chats]

# 라우터에서 다시 변환
chat_list = [
    SharedChatResponse(**chat.model_dump())
    for chat in Chats.get_shared_chat_list_by_user_id(...)
]

After: 필요한 컬럼만 프로젝션

def get_shared_chat_list_by_user_id(
    self, ..., db: Optional[Session] = None,
) -> list[SharedChatResponse]:
    # ... 쿼리 구성 ...
    query = query.with_entities(
        Chat.id, Chat.title, Chat.share_id,
        Chat.updated_at, Chat.created_at,
    )
    all_chats = query.all()
    return [
        SharedChatResponse(
            id=chat[0], title=chat[1], share_id=chat[2],
            updated_at=chat[3], created_at=chat[4],
        )
        for chat in all_chats
    ]

# 라우터는 반환값을 그대로 사용
return Chats.get_shared_chat_list_by_user_id(user.id, ...)

왜 이게 좋은가

  1. 대용량 JSON 역직렬화 제거: 대화 이력이 수천 개의 메시지를 포함할 수 있으므로, 이 JSON 블롭을 로드하지 않는 것만으로도 메모리와 CPU 사용량이 크게 줄어든다.
  2. 이중 변환 제거: 기존에는 ChatModel.model_validate() 후 다시 SharedChatResponse로 변환하는 이중 작업이 있었는데, 이를 단일 단계로 줄였다.
  3. DB I/O 최소화: SELECT 대상 컬럼을 줄이면 네트워크 전송량과 DB 부하가 모두 감소한다.

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글