Skip to main content

Standalone LLM library with support for multiple providers

Project description

pyhub-llm

다양한 LLM 제공업체를 위한 통합 Python 라이브러리입니다. OpenAI, Anthropic, Google, Ollama 등의 API를 일관된 인터페이스로 사용할 수 있습니다.

📚 문서

✨ CHEATSHEET - 수준별 완전한 가이드

pyhub-llm의 모든 기능을 수준별로 나누어 정리했습니다:

📊 OBSERVABILITY - 모니터링 및 추적 가이드

LLM 애플리케이션의 성능 모니터링과 디버깅을 위한 완전한 가이드:

  • 🔍 LangSmith 통합: 평가 지표 추적 및 디버깅
  • 📈 OpenTelemetry 지원: 표준 관측성 프레임워크
  • 최소 오버헤드: 비활성화 시 성능 영향 없음
  • 🔧 간편한 설정: 환경변수 기반 자동 설정
  • 🔗 다중 백엔드: LangSmith와 OpenTelemetry 동시 지원

주요 기능

  • 🔌 통합 인터페이스: 모든 LLM 제공업체를 동일한 방식으로 사용
  • 🚀 간편한 전환: 코드 변경 없이 모델 전환 가능
  • 💾 캐싱 지원: 응답 캐싱으로 비용 절감 및 성능 향상
  • 🔄 스트리밍 지원: 실시간 응답 스트리밍
  • 🛠️ 도구/함수 호출: Function calling 지원
  • 📷 이미지 처리: 이미지 설명 및 분석 기능
  • 비동기 지원: 동기/비동기 모두 지원
  • 🔗 체이닝: 여러 LLM을 연결하여 복잡한 워크플로우 구성
  • 💾 대화 히스토리 백업: 대화 내역을 외부 저장소에 백업 및 복원
  • 📊 관측성: LangSmith와 OpenTelemetry 통합으로 성능 모니터링 및 디버깅

설치

전체 설치

pip install 'pyhub-llm[all]'

특정 제공업체만 설치

# OpenAI만
pip install "pyhub-llm[openai]"

# Anthropic만
pip install "pyhub-llm[anthropic]"

# Google만 (google-genai 라이브러리 사용)
pip install "pyhub-llm[google]"

# Ollama만
pip install "pyhub-llm[ollama]"

# 관측성 기능 (LangSmith + OpenTelemetry)
pip install "pyhub-llm[observability]"

# 모든 기능 (제공업체 + 관측성 포함)
pip install "pyhub-llm[all]"

개발 환경 설치

# 저장소 클론
git clone https://github.com/pyhub-kr/pyhub-llm.git
cd pyhub-llm

# 개발 환경 설치
pip install -e ".[dev,all]"
# 혹은 make install

빠른 시작

환경변수 설정

각 프로바이더를 사용하려면 해당 API 키를 환경변수로 설정해야 합니다:

Linux/macOS (Bash)

export OPENAI_API_KEY="your-openai-api-key"
export ANTHROPIC_API_KEY="your-anthropic-api-key"
export GOOGLE_API_KEY="your-google-api-key"
export UPSTAGE_API_KEY="your-upstage-api-key"

Windows (PowerShell)

$env:OPENAI_API_KEY="your-openai-api-key"
$env:ANTHROPIC_API_KEY="your-anthropic-api-key"
$env:GOOGLE_API_KEY="your-google-api-key"
$env:UPSTAGE_API_KEY="your-upstage-api-key"

참고:

  • API 키는 각 프로바이더의 웹사이트에서 발급받을 수 있습니다 (API 키 설정 섹션 참조)
  • Ollama는 로컬에서 실행되므로 API 키가 필요 없습니다
  • Ollama는 디폴트로 http://localhost:11434 주소를 사용합니다. UPSTAGE_BASE_URL 환경변수나 OllamaLLM(base_url="...") 인자를 통해 변경하실 수 있습니다.

모델별 직접 사용

각 프로바이더를 사용하려면 해당 라이브러리를 먼저 설치해야 합니다:

# OpenAI 사용시
pip install "pyhub-llm[openai]"

# Anthropic 사용시
pip install "pyhub-llm[anthropic]"

# Google 사용시
pip install "pyhub-llm[google]"

# Ollama 사용시 (로컬 실행)
pip install "pyhub-llm[ollama]"

# 이미지 기능 사용시 (Pillow 포함)
pip install "pyhub-llm[image]"

# 모든 기능 설치
pip install "pyhub-llm[all]"
from pyhub.llm import OpenAILLM, AnthropicLLM, GoogleLLM, OllamaLLM

# OpenAI (OPENAI_API_KEY 환경변수 필요)
openai_llm = OpenAILLM(model="gpt-4o-mini")
reply = openai_llm.ask("안녕하세요!")

# API 키 직접 전달
openai_llm = OpenAILLM(model="gpt-4o-mini", api_key="your-api-key")

# Anthropic (ANTHROPIC_API_KEY 환경변수 필요)
claude_llm = AnthropicLLM(model="claude-3-5-haiku-latest")
reply = claude_llm.ask("안녕하세요!")

# Google (GOOGLE_API_KEY 환경변수 필요)
gemini_llm = GoogleLLM(model="gemini-1.5-flash")
reply = gemini_llm.ask("안녕하세요!")

# Ollama (로컬 실행, API 키 불필요, 기본 URL: http://localhost:11434)
ollama_llm = OllamaLLM(model="mistral")
reply = ollama_llm.ask("안녕하세요!")

기본 사용법

from pyhub.llm import LLM

# LLM 인스턴스 생성
llm = LLM.create("gpt-4o-mini")

# 질문하기
reply = llm.ask("Python의 장점은 무엇인가요?")
print(reply.text)

더 많은 예시와 고급 사용법은 초급 가이드를 참고하세요.

Ollama 로컬 모델 사용

Ollama는 로컬에서 LLM을 실행할 수 있는 오픈소스 도구입니다. API 키가 필요 없고, 데이터가 외부로 전송되지 않아 개인정보 보호에 유리합니다.

Ollama 설치

macOS

# Homebrew 사용
brew install ollama

# 또는 공식 설치 프로그램 다운로드
curl -fsSL https://ollama.ai/install.sh | sh

Linux

# 설치 스크립트 실행
curl -fsSL https://ollama.ai/install.sh | sh

# 또는 Docker 사용
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

Windows

# PowerShell에서 실행
iex (irm https://ollama.ai/install.ps1)

# 또는 공식 웹사이트에서 설치 프로그램 다운로드
# https://ollama.ai/download/windows

모델 다운로드 및 실행

# Ollama 서비스 시작 (필요한 경우)
ollama serve

# Mistral 모델 다운로드
ollama pull mistral

# 다른 인기 모델들
ollama pull llama3.3
ollama pull gemma2
ollama pull qwen2

# 모델 목록 확인
ollama list

# 모델 직접 실행 (테스트용)
ollama run mistral

pyhub-llm에서 Ollama 사용

from pyhub.llm import OllamaLLM

# 기본 사용법
llm = OllamaLLM(model="mistral")
reply = llm.ask("Python으로 웹 스크래핑하는 방법을 알려주세요")
print(reply.text)

# 스트리밍으로 실시간 응답 받기
for chunk in llm.ask("긴 이야기를 들려주세요", stream=True):
    print(chunk.text, end="", flush=True)

# 이미지와 함께 질문하기
reply = llm.ask(
    "이 이미지에 무엇이 보이나요?",
    files=["image.jpg"]
)

# PDF 파일 처리 (자동으로 이미지로 변환됨)
reply = llm.ask(
    "이 PDF 문서를 요약해주세요",
    files=["document.pdf"]  # 자동으로 고품질 이미지로 변환
)

# 비동기 사용
async def async_example():
    reply = await llm.ask_async("비동기로 질문합니다")
    return reply.text

# 커스텀 설정
llm = OllamaLLM(
    model="mistral",
    temperature=0.7,
    max_tokens=2000,
    base_url="http://localhost:11434"  # 커스텀 Ollama 서버
)

Ollama 장점

  • 🔒 개인정보 보호: 모든 데이터가 로컬에서 처리
  • 💰 비용 절감: API 호출 비용 없음
  • ⚡ 빠른 응답: 네트워크 지연 없음
  • 🌐 오프라인 사용: 인터넷 연결 불필요
  • 🎛️ 완전한 제어: 모델 파라미터 자유 조정

지원 모델

  • Llama 계열: llama3.3, llama3.1, llama3.2
  • Mistral: mistral, mixtral
  • Gemma: gemma2, gemma3
  • Qwen: qwen2, qwen2.5
  • 기타: phi3, codellama, vicuna 등

참고: PDF 파일 처리 시 Ollama는 자동으로 고품질 이미지로 변환하여 처리합니다. 한국어 텍스트 보존을 위해 600 DPI로 변환됩니다.

주요 기능 예제

1. 스트리밍 응답

from pyhub.llm import OpenAILLM

# 실시간으로 응답 받기
llm = OpenAILLM(model="gpt-4o-mini")
for chunk in llm.ask("긴 이야기를 들려주세요", stream=True):
    print(chunk.text, end="", flush=True)

2. 출력 포맷팅 (NEW! 🎨)

from pyhub.llm import OpenAILLM, display

llm = OpenAILLM(model="gpt-4o-mini")

# 마크다운 렌더링과 함께 스트리밍
response = llm.ask("파이썬 함수 작성법을 알려주세요", stream=True)
display(response)  # 자동으로 마크다운 렌더링!

# 또는 Response 객체의 print() 메서드 사용
response = llm.ask("안녕하세요")
response.print(markdown=True)

# 일반 텍스트로 출력
response.print(markdown=False)

3. 이미지 생성 (NEW! 🎨)

from pyhub.llm import OpenAILLM

# DALL-E 3로 이미지 생성
llm = OpenAILLM(model="dall-e-3")
reply = llm.generate_image(
    "A beautiful sunset over mountains",
    size="1024x1792",  # 세로 형식
    quality="hd"       # 고품질
)

# 이미지 저장
path = reply.save("sunset.png")  # 또는 reply.save() 로 자동 파일명
print(f"Saved to: {path}")

# BytesIO에 저장 (NEW!)
from io import BytesIO
buffer = BytesIO()
reply.save(buffer)
buffer.seek(0)  # 읽기 위해 처음으로

# Django ImageField 통합 (v0.9.1+)
from django.db import models
class MyModel(models.Model):
    image = models.ImageField(upload_to='generated/')

# 간단하게 ImageField에 저장
instance = MyModel(image=reply.to_django_file())
instance.save()

# 이미지 표시 (Jupyter)
reply.display()

# PIL로 변환 (Pillow 필요)
img = reply.to_pil()
img.thumbnail((512, 512))
img.save("thumbnail.png")

# 비동기 처리
import asyncio

async def generate_multiple():
    tasks = [
        llm.generate_image_async(f"Image {i}") 
        for i in range(3)
    ]
    images = await asyncio.gather(*tasks)
    
    # 병렬 저장
    save_tasks = [img.save_async(f"img_{i}.png") for i, img in enumerate(images)]
    await asyncio.gather(*save_tasks)

4. 파일 처리 (이미지 및 PDF)

from pyhub.llm import OpenAILLM

llm = OpenAILLM(model="gpt-4o-mini")

# 이미지 설명
reply = llm.ask("이 이미지를 설명해주세요", files=["photo.jpg"])

# PDF 요약
reply = llm.ask("이 문서를 요약해주세요", files=["document.pdf"])

5. 도구/함수 호출

from pyhub.llm import OpenAILLM

# 간단한 함수를 도구로 사용
def get_weather(city: str) -> str:
    """도시의 날씨 정보를 가져옵니다."""
    return f"{city}의 날씨는 맑음입니다."

llm = OpenAILLM(model="gpt-4o-mini")
reply = llm.ask("서울 날씨 알려줘", tools=[get_weather])

📖 더 많은 고급 기능과 상세한 예시는 가이드 문서를 참고하세요:

  • 대화 히스토리 관리
  • 구조화된 출력 (Pydantic)
  • LLM 체이닝
  • 캐싱 전략
  • MCP 통합
  • 웹 프레임워크 통합 (FastAPI, Django)
  • 에러 처리 및 재시도
  • 대화 히스토리 백업 및 복원

5. 대화 히스토리 백업

from pyhub.llm import LLM
from pyhub.llm.history import InMemoryHistoryBackup

# 백업 저장소 생성
backup = InMemoryHistoryBackup(user_id="user123", session_id="session456")

# 백업이 활성화된 LLM 생성
llm = LLM.create("gpt-4o-mini", history_backup=backup)

# 대화 진행 (자동으로 백업됨)
llm.ask("Python의 장점은 무엇인가요?")
llm.ask("더 자세히 설명해주세요")

# 사용량 확인
usage = backup.get_usage_summary()
print(f"총 사용 토큰: {usage.input + usage.output}")

# SQLAlchemy로 영구 저장
from pyhub.llm.history import SQLAlchemyHistoryBackup
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine("sqlite:///chat_history.db")
Session = sessionmaker(bind=engine)
session = Session()

db_backup = SQLAlchemyHistoryBackup(session, user_id="user123", session_id="session456")
llm_with_db = LLM.create("gpt-4o-mini", history_backup=db_backup)

🔍 대화 히스토리 백업은 도구(Tool) 사용 내역도 자동으로 저장합니다. 자세한 사용법은 중급 가이드를 참고하세요.

6. 프롬프트 허브 (Hub) - LangChain Hub 호환 (NEW! 🎯)

from pyhub.llm import hub, OpenAILLM

# 인기 있는 프롬프트 가져오기
rag_prompt = hub.pull("rlm/rag-prompt")
react_prompt = hub.pull("hwchase17/react")

# RAG 프롬프트 사용
formatted = rag_prompt.format(
    context="파이썬은 1991년에 출시된 프로그래밍 언어입니다.",
    question="파이썬은 언제 출시되었나요?"
)
llm = OpenAILLM(model="gpt-4o-mini")
answer = llm.ask(formatted)

# 커스텀 프롬프트 생성 및 저장
from pyhub.llm.templates import PromptTemplate

custom_prompt = PromptTemplate(
    template="당신은 {role} 전문가입니다. {task}를 수행해주세요.",
    input_variables=["role", "task"]
)
hub.push("mycompany/expert-prompt", custom_prompt)

# 나중에 다시 사용
saved_prompt = hub.pull("mycompany/expert-prompt")

지원하는 내장 프롬프트:

  • rlm/rag-prompt - RAG (Retrieval Augmented Generation) 질문-답변
  • hwchase17/react - ReAct 에이전트 (도구 사용)
  • hwchase17/openai-functions-agent - OpenAI 함수 호출 에이전트
  • hwchase17/structured-chat-agent - 구조화된 JSON 출력 에이전트

API 키 설정

필요한 API 키

각 프로바이더를 사용하려면 해당 API 키가 필요합니다:

설정 방법

1. 환경 변수로 설정

export OPENAI_API_KEY="your-openai-key"
export ANTHROPIC_API_KEY="your-anthropic-key"
export GOOGLE_API_KEY="your-google-key"

2. 코드에서 직접 전달

from pyhub.llm import OpenAILLM, AnthropicLLM, GoogleLLM

# API 키를 직접 전달
llm = OpenAILLM(api_key="your-api-key")
llm = AnthropicLLM(api_key="your-api-key")
llm = GoogleLLM(api_key="your-api-key")

CLI 사용법

# 대화형 채팅
pyhub-llm chat --model gpt-4o-mini

# 단일 질문
pyhub-llm ask "Python과 Go의 차이점은?"

# 파일과 함께 질문
pyhub-llm ask "이 코드를 리뷰해주세요" --file main.py

🔧 더 많은 CLI 옵션과 사용법은 초급 가이드를 참고하세요.

고급 기능

Stateless 모드

반복적인 독립 작업(분류, 정보 추출 등)을 수행할 때 불필요한 대화 히스토리 누적을 방지하는 모드입니다.

from pyhub.llm import LLM

# Stateless 모드로 LLM 생성
classifier = LLM.create("gpt-4o-mini", stateless=True)

# 각 요청이 독립적으로 처리되며 히스토리가 저장되지 않음
for text in customer_queries:
    reply = classifier.ask(
        f"고객 문의 의도 분류: {text}",
        choices=["환불", "배송", "문의", "불만"]
    )
    print(f"{text} -> {reply.choice}")
    # 히스토리가 누적되지 않아 API 비용 절감

Stateless 모드의 특징:

  • 대화 히스토리를 전혀 저장하지 않음
  • use_history=True를 지정해도 무시됨
  • clear() 메서드가 아무 동작도 하지 않음
  • 반복 작업에서 메모리 사용량과 API 비용 절감

일반 모드와의 비교:

# 일반 모드 (히스토리 누적)
normal_llm = LLM.create("gpt-4o-mini")
normal_llm.ask("분류1", choices=["A", "B"])  # 2개 메시지 저장
normal_llm.ask("분류2", choices=["C", "D"])  # 4개 메시지 저장 (이전 대화 포함)

# Stateless 모드 (히스토리 없음)
stateless_llm = LLM.create("gpt-4o-mini", stateless=True)
stateless_llm.ask("분류1", choices=["A", "B"])  # 0개 메시지
stateless_llm.ask("분류2", choices=["C", "D"])  # 0개 메시지 (독립 처리)

개발

테스트 실행

# 모든 테스트
make test

# 특정 테스트
make test tests/test_openai.py

# 커버리지 포함 테스트
make test-cov
# 또는
make cov

# 커버리지 HTML 리포트 보기
make test-cov-report

# 특정 파일만 커버리지 테스트
make cov tests/test_optional_dependencies.py

# pytest 직접 실행
pytest --cov=src/pyhub/llm --cov-report=term --cov-report=html

코드 품질 검사

# 포맷팅 및 린팅
make format
make lint

# 타입 체크
mypy src/

빌드 및 배포

# 패키지 빌드
make build

# PyPI 배포 (권한 필요)
make release

기여하기

  1. 이 저장소를 포크합니다
  2. 기능 브랜치를 생성합니다 (git checkout -b feature/amazing-feature)
  3. 변경사항을 커밋합니다 (git commit -m 'Add amazing feature')
  4. 브랜치에 푸시합니다 (git push origin feature/amazing-feature)
  5. Pull Request를 생성합니다

기여 가이드라인

  • 모든 새 기능에는 테스트를 포함해주세요
  • 코드 스타일은 Black과 Ruff를 따릅니다
  • 타입 힌트를 사용해주세요
  • 문서를 업데이트해주세요

라이선스

이 프로젝트는 MIT 라이선스를 따릅니다. 자세한 내용은 LICENSE 파일을 참조하세요.

문제 해결

일반적인 문제

Q: API 키 오류가 발생합니다

# 해결 방법 1: 환경 변수 설정
import os
os.environ["OPENAI_API_KEY"] = "your-key"

# 해결 방법 2: 직접 전달
llm = OpenAILLM(api_key="your-key")

Q: 속도가 느립니다

# 캐시 인젝션으로 캐싱 활성화
from pyhub.llm.cache import MemoryCache
cache = MemoryCache()
llm = LLM.create("gpt-4o-mini", cache=cache)
reply = llm.ask("...")

# 더 빠른 모델 사용
llm = LLM.create("gpt-3.5-turbo")

Q: 메모리 사용량이 높습니다

# 대화 히스토리 제한
llm = LLM.create(
    "gpt-4o-mini",
    initial_messages=[]  # 히스토리 없이 시작
)

# 주기적으로 히스토리 정리
if len(llm) > 10:
    llm.clear()

알려진 이슈

OpenAI JSON Schema 구조화된 출력의 토큰 생성 이슈 (v0.8.0에서 개선)

OpenAI의 JSON Schema 구조화된 출력 모드(strict=true)에서 간헐적으로 무한 개행 문자나 제어 문자가 생성되는 문제가 보고되었습니다. 이는 GPT-4o-2024-08-06 모델에서 발견된 알려진 문제입니다.

증상:

# 무한 개행 문자 생성
{"choice": "\n\n\n\n\n..."}  # max_tokens까지 계속

# 제어 문자 포함
{"choice": "\u001cA/S\u001d0\u001d\u001d..."}

v0.8.0+ 개선사항:

  • strict: true 설정으로 스키마 준수 강화
  • choice_index 필드를 통한 안정적인 선택
  • 시스템 프롬프트 자동 생성 (choices 사용 시)
# 시스템 프롬프트 없이도 작동
llm = OpenAILLM()
reply = llm.ask("분류해주세요", choices=["환불/반품", "A/S요청"])
print(reply.choice)  # "환불/반품" 또는 "A/S요청"
print(reply.choice_index)  # 0 또는 1

이전 버전 해결 방법:

  1. 특수문자를 제거하거나 대체: "A/S요청""AS요청"
  2. 버전 0.7.1-0.7.x에서는 제어 문자가 부분적으로 필터링됩니다

자세한 내용은 Issue #22를 참조하세요.

링크

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyhub_llm-0.10.0-py3-none-any.whl (181.5 kB view details)

Uploaded Python 3

File details

Details for the file pyhub_llm-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: pyhub_llm-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 181.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for pyhub_llm-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cce1423c0b9205bf1195e4c6cf8f32f91efe603ed81c0672a55923a798b31afb
MD5 079c5fbfd9d6997cc7a8260e6047783b
BLAKE2b-256 fd8ea36fb6842b035e1b486c79e111a103d12c62d4bb5ba94c94d53e6ce2dfc4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page