Python으로 Open WebUI Ollama API 호출해서 면담 요약하기

Open webui ollama - python

이제 진짜 실전 코딩입니다.

1,2,3부에서 우리는

  • 맥북에 Ollama 설치하고 모델(Qwen·Llama3·EXAONE 등) 받고,
  • Docker로 Open WebUI Ollama 컨테이너를 띄우고,
  • Open WebUI Ollama 설정에서 한국어 시스템 프롬프트와 JWT 토큰까지 확인했죠.

이제 4부에서는

Python 스크립트에서 Open WebUI 의 /api/chat/completions 엔드포인트를 직접 불러

조직문화 면담 텍스트를 요약해 보는 것”

까지 한 번에 가봅니다.

1. 왜 굳이 Open WebUI Ollama API를 Python에서 써야 할까?

UI에서 직접 채팅하면 되는데,

굳이 코드를 짜서 Open WebUI API를 호출하는 이유는 뭘까요?

1-1. 반복 작업을 자동화하기 위해

  • 조직문화 진단처럼 면담이 수십·수백 건 쌓이는 경우,
  • 매번 Open WebUI 화면에 붙여 넣고 요약 받고…
    → 사람이 손으로 하긴 너무 비효율적입니다.

Python으로 Open WebUI Ollama API를 쓰면

  • interview_001.txt, interview_002.txt … 파일들을
    한 번에 읽어 와서 일괄 요약 → 결과를 폴더·DB에 저장
  • “어제 새로 들어온 면담만” 골라서 Open WebUI 에 던지는 자동 작업도 가능

1-2. 나중에 Django·Flask 같은 웹시스템과 자연스럽게 연결

이번 4부에서 만드는 Python 코드가

그대로 5부의 장고 뷰/서비스 코드로 옮겨 갈 겁니다.

즉, 한번 잘 만들어 놓은 Open WebUI 클라이언트는

  • 단독 스크립트
  • 주기 실행 배치 작업
  • Django 백엔드 서비스

어디에든 그대로 박아 넣을 수 있는 재사용 가능한 모듈이 됩니다.

2. Open WebUI API 구조 다시 한 번 짚고 가기

Open WebUI 는 기본적으로 OpenAI ChatCompletion 호환 API를 제공합니다.

  • 엔드포인트
POST http://localhost:3000/api/chat/completions
  • 헤더
Authorization: Bearer <JWT 또는 API 키>
Content-Type: application/json
  • 바디 구조
{
  "model": "qwen2.5:7b",
  "messages": [
    { "role": "system", "content": "역할 정하기" },
    { "role": "user", "content": "사용자 질문" }
  ]
}
  • 응답 구조(요약)
{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "여기에 Open WebUI Ollama가 생성한 요약 텍스트"
      }
    }
  ]
}

즉, Python에서는 requests 라이브러리로

이 주소에 JSON 하나 던지고,

돌아온 JSON에서 choices[0].message.content만 뽑으면 끝입니다.

3. JWT 토큰 값 준비하기

이미 3부에서 확인했지만, 한 번 더 정리해볼게요.

  1. 브라우저에서 http://localhost:3000 접속
  2. 우측 상단 프로필 아이콘 → 설정(Setting) → 계정(Account)
  3. 아래쪽에 JWT 토큰 영역이 있고, 점선으로 가려진 값 + 눈 아이콘 + 복사 버튼이 보입니다.
  4. 눈 아이콘(보기) 클릭 → 전체 토큰 값이 노출
  5. 복사 버튼을 눌러 이 문자열을 클립보드에 복사해 둡니다.

이 JWT 토큰이 Open WebUI API 인증용 비밀키 역할을 합니다.

⚠️ 꼭 .env 에 넣고, 깃에는 올리지 않도록 주의!

Open WebUI Ollama가 로컬이라도, 습관을 안전하게 가져가는 게 좋습니다.

4. Python에서 Open WebUI Ollama API 첫 호출 – “안녕?” 테스트

우선 아주 간단한 테스트부터 해볼게요.

Open WebUI Ollama에 “안녕?” 보내고, 잘 응답하는지 확인하는 수준입니다.

4-1. .env 파일 만들기

프로젝트 폴더에 .env 파일 하나 만들고

OPENWEBUI_BASE_URL=http://localhost:3000

OPENWEBUI_API_KEY=여기에_JWT_토큰_값_붙여넣기

OPENWEBUI_DEFAULT_MODEL=qwen2.5:7b

4-2. 파이썬 코드 – 최소 예제

test_openwebui_client.py 같은 이름으로 파일 하나 만들고

import os
import json
import requests
from dotenv import load_dotenv

# .env 읽기
load_dotenv()

OPENWEBUI_BASE_URL = os.getenv("OPENWEBUI_BASE_URL", "http://localhost:3000")
OPENWEBUI_API_KEY = os.getenv("OPENWEBUI_API_KEY", "")
OPENWEBUI_DEFAULT_MODEL = os.getenv("OPENWEBUI_DEFAULT_MODEL", "qwen2.5:7b")


def call_openwebui_ollama(prompt: str) -> str:
    """Open WebUI Ollama /api/chat/completions 간단 호출."""
    url = f"{OPENWEBUI_BASE_URL}/api/chat/completions"

    headers = {
        "Authorization": f"Bearer {OPENWEBUI_API_KEY}",
        "Content-Type": "application/json",
    }

    payload = {
        "model": OPENWEBUI_DEFAULT_MODEL,
        "messages": [
            {
                "role": "system",
                "content": "너는 한국어로만 답변하는 친절한 AI 비서야."
            },
            {
                "role": "user",
                "content": prompt,
            },
        ],
    }

    resp = requests.post(url, headers=headers, json=payload, timeout=60)
    resp.raise_for_status()
    data = resp.json()

    # 디버깅이 필요하면 전체 응답을 찍어볼 수 있다.
    # print(json.dumps(data, ensure_ascii=False, indent=2))

    return data["choices"][0]["message"]["content"]


if __name__ == "__main__":
    answer = call_openwebui_ollama("Open WebUI Ollama 조합이 뭐야? 세 줄로 설명해줘.")
    print("=== Open WebUI Ollama 응답 ===")
    print(answer)

터미널에서

pip install python-dotenv requests

python test_openwebui_client.py
  • 에러 없이
    === Open WebUI Ollama 응답 ===
    아래에 한국어 설명이 쭉 출력되면
    → Python ↔ Open WebUI Ollama ↔ Ollama ↔ LLM 모델
    전체 파이프라인이 제대로 연결된 상태입니다.

5. 조직문화 면담 텍스트 요약

Ollama summarizing

이제 진짜 실전입니다.

Open WebUI API를 이용해서 면담 전문 한 건을 요약해볼게요.

5-1. 요약 함수 설계

openwebui_summarizer.py 같은 파일로 분리해두면

나중에 Django에서 그대로 import 해서 쓰기 좋습니다.

import os
import requests
from dotenv import load_dotenv

load_dotenv()

OPENWEBUI_BASE_URL = os.getenv("OPENWEBUI_BASE_URL", "http://localhost:3000")
OPENWEBUI_API_KEY = os.getenv("OPENWEBUI_API_KEY", "")
OPENWEBUI_DEFAULT_MODEL = os.getenv("OPENWEBUI_DEFAULT_MODEL", "qwen2.5:7b")


class OpenWebUISummarizer:
    """Open WebUI Ollama 기반 요약 도우미 클래스."""

    def __init__(self):
        if not OPENWEBUI_API_KEY:
            raise ValueError("OPENWEBUI_API_KEY가 설정되지 않았습니다.")

    @property
    def _headers(self):
        return {
            "Authorization": f"Bearer {OPENWEBUI_API_KEY}",
            "Content-Type": "application/json",
        }

    def _post_chat(self, payload: dict) -> dict:
        url = f"{OPENWEBUI_BASE_URL}/api/chat/completions"
        resp = requests.post(url, headers=self._headers, json=payload, timeout=120)
        resp.raise_for_status()
        return resp.json()

    def summarize_interview(self, text: str, model: str | None = None) -> str:
        """조직문화 면담 전문을 요약해서 반환."""
        model_name = model or OPENWEBUI_DEFAULT_MODEL

        system_prompt = """
        너는 조직문화 전문가이자 요약 전문 AI야.
        모든 답변은 한국어(존댓말)로만 작성해야 한다.
        아래 면담 내용을 읽고, 조직문화 관점의 핵심을 구조화해서 요약해줘.

        형식:
        1. 인터뷰 개요 (2~3줄)
        2. 긍정적인 조직문화 요소 (3~5개 bullet)
        3. 우려되는 조직문화 요소 / 리스크 (3~5개 bullet)
        4. 시사점 및 개선 제안 (2~4줄)
        """

        user_content = f"""
        아래는 한 명에 대한 조직문화 면담(인터뷰) 전체 기록입니다.

        --- 인터뷰 전문 시작 ---
        {text}
        --- 인터뷰 전문 끝 ---

        위 형식에 맞춰 자연스럽게 요약해 주세요.
        실제 보고서에 바로 붙여 넣을 수 있도록 문장을 정리해 주세요.
        """

        payload = {
            "model": model_name,
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_content},
            ],
        }

        data = self._post_chat(payload)
        return data["choices"][0]["message"]["content"]

5-2. 사용 예시 – 텍스트 파일 하나 요약하기

if __name__ == "__main__":
    from pathlib import Path

    # 예: data/interviews/interview_001.txt
    text_path = Path("data/interviews/interview_001.txt")
    raw_text = text_path.read_text(encoding="utf-8")

    summarizer = OpenWebUISummarizer()
    summary = summarizer.summarize_interview(raw_text)

    print("=== 요약 결과 ===")
    print(summary)

이렇게 하면 interview_001.txt에 들어 있는 긴 면담 전문을

Open WebUI → Qwen2.5 조합으로 요약해서

콘솔에 출력하게 됩니다.

6. 텍스트가 너무 길 때 – 청크 나누기 + 메타 요약 패턴

Chunk split image

현실에서는 조직문화 면담이 1~2시간씩 이어지다 보니

텍스트가 상당히 길 수 있습니다.

Open WebUI Ollama에 한 번에 던지기 부담스러울 만큼 길다면:

  1. 면담 전문을 일정 길이 기준으로 청크(chunk) 로 나누고,
  2. 각 청크를 Open WebUI Ollama로 1차 요약,
  3. 1차 요약들을 다시 한 번 Open WebUI Ollama에 던져 최종 요약을 만들어냅니다.

6-1. 간단 청크 함수

def chunk_text(text: str, max_chars: int = 3000) -> list[str]:
    """대충 글자 수 기준으로 텍스트를 끊어 주는 간단 청크 함수."""
    chunks: list[str] = []
    current = ""

    for line in text.splitlines(keepends=True):
        if len(current) + len(line) > max_chars:
            chunks.append(current)
            current = ""
        current += line

    if current.strip():
        chunks.append(current)

    return chunks

6-2. 청크 요약 + 메타 요약을 Open WebUI Ollama로 수행

def summarize_long_interview(text: str) -> str:
    summarizer = OpenWebUISummarizer()

    chunks = chunk_text(text, max_chars=3000)
    partial_summaries: list[str] = []

    # 1차: 청크별 부분 요약
    for idx, chunk in enumerate(chunks, start=1):
        print(f"[DEBUG] Open WebUI Ollama로 부분 요약 {idx}/{len(chunks)} 진행 중...")
        summary_i = summarizer.summarize_interview(
            chunk
        )
        partial_summaries.append(f"[부분 요약 {idx}]\n{summary_i}\n")

    # 2차: 부분 요약들을 하나의 최종 요약으로
    bundle_text = "\n".join(partial_summaries)

    system_prompt = """
    너는 여러 개의 부분 요약들을 읽고,
    중복을 제거하고 핵심만 남겨 하나의 최종 요약을 만드는 전문가야.
    형식은 이전과 동일하게 유지하고, 표현은 더 간결하게 다듬어줘.
    """

    payload = {
        "model": OPENWEBUI_DEFAULT_MODEL,
        "messages": [
            {"role": "system", "content": system_prompt},
            {
                "role": "user",
                "content": f"아래 [부분 요약]들을 읽고 하나의 최종 요약본을 만들어줘.\n\n{bundle_text}",
            },
        ],
    }

    data = summarizer._post_chat(payload)
    final_summary = data["choices"][0]["message"]["content"]
    return final_summary

이 패턴을 쓰면

  • 면담이 아무리 길어도
    Open WebUI Ollama가 처리 가능한 덩어리로 쪼갠 뒤 다시 합치는 구조라 꽤 안정적으로 결과를 얻을 수 있습니다.

나중에 장고에서 이 함수를 그대로 가져다가

“면담 1건 요약 버튼”이나 “부서별 일괄 요약” 기능으로 붙이면 됩니다.

7. 실무에서 자주 쓰게 될 Open WebUI Ollama API 활용 패턴

Open WebUI Ollama API를 한 번 붙여놓으면,

요약 말고도 이런 작업에 그대로 재활용할 수 있습니다.

  1. 번역 + 요약 동시 수행
    • “영문 보고서를 한국어로 번역하면서, 마지막에는 5줄 요약을 붙여줘.”
  2. 키워드/태그 추출
    • “이 면담에서 반복적으로 등장하는 키워드를 10개 뽑아줘.”
  3. 감성·위험도 레이블링
    • “조직문화 관점에서 이 응답은 긍정/중립/우려 중 어디에 가까운지 선택하고 이유를 써줘.”

이 모든 로직이 결국

Open WebUI Ollama API에 프롬프트만 바꿔서 던지는 것이기 때문에,

  • 포맷을 잘 잡아두면
  • 나중에 장고 모델 메서드나 Celery 작업으로 옮기기도 쉬워집니다.

8. 4부 마무리 – 이제 Open WebUI Ollama는 “도구”가 아니라 “엔진”

이번 4부에서는

  1. .env에 Open WebUI Ollama JWT 토큰과 URL을 넣고,
  2. Python requests로 /api/chat/completions에 직접 요청을 보내고,
  3. 간단한 “안녕?” 테스트로 Open WebUI Ollama 통신을 확인한 뒤,
  4. 조직문화 면담 전문을 요약하는 전용 클래스를 만들고,
  5. 긴 텍스트를 처리하기 위한 청크→부분 요약→최종 요약 패턴까지 살펴봤습니다.

이제부터 Open WebUI Ollama는 단순한 “챗봇 UI”가 아니라,

“파이썬·장고 등에서 마음껏 호출할 수 있는 로컬 LLM 엔진”

으로 인식하시면 됩니다.

이제 마지막 5부에서는 이 Open WebUI Ollama 요약 엔진을

실제 Django 조직문화 관련 웹시스템에 붙이는 이야기를 정리해볼 거예요.

유사한 게시물