Skip to main content

pstone — Profit Stone Telemetry SDK

고객 AI 앱에 설치하는 in-process 관측 SDK입니다.
OpenTelemetry로 LLM·도구 호출을 수집해 Profit Stone SaaS Ingest API로 보내고, Backend가 Workspace API Key로 workspace_id를 붙여 ClickHouse에 저장합니다.

Sentry를 붙이듯, 앱에 패키지를 설치하고 init에 API Key만 넣으면 됩니다.

from pstone import pstone

pstone.init("psk_live_...")

상태: 0.1.2 Alpha — Python MVP (python/). JS(@profitstone/pstone)·Java는 scaffold.

설계 문서: docs/sdk-design.md


목차

  1. 설치
  2. 빠른 시작
  3. API Key
  4. 환경 변수
  5. OpenAI / Anthropic 계측
  6. 옵션
  7. 수동 Span
  8. flush / shutdown
  9. 데이터 흐름
  10. 로컬 개발
  11. PyPI 배포

설치

일반 (배포 후)

pip install pstone

OpenAI / Anthropic 계측을 쓰려면 해당 SDK도 앱에 설치되어 있어야 합니다.

pip install pstone openai anthropic
# 또는 extras (패키지 배포 설정에 따름)
pip install "pstone[openai,anthropic]"

개발 (이 레포)

cd profitstone_sdk
make python-sync
make python-test

또는 python/ 디렉터리에서:

cd python
uv sync
uv run pytest

빠른 시작

  1. Profit Stone Dashboard에서 Workspace API Key를 발급합니다.
  2. 앱 시작 시점에 pstone.init을 한 번 호출합니다 (Sentry init과 동일).
  3. 기존 OpenAI / Anthropic 호출 코드는 그대로 둡니다. init이 설치된 라이브러리를 자동 계측합니다.
import os
from openai import OpenAI
from pstone import pstone

# 1) SDK 초기화 (앱 부팅 시 1회)
pstone.init(os.environ["PSTONE_API_KEY"])

# 2) 평소처럼 AI 호출 — Span이 자동 수집되어 Ingest로 전송됨
client = OpenAI()
resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)

# 3) 프로세스 종료 전 (선택) 미전송 Span flush
pstone.flush()

Anthropic도 동일합니다.

from anthropic import Anthropic
from pstone import pstone

pstone.init("psk_live_...")

client = Anthropic()
msg = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello"}],
)

API Key

항목 설명
발급 위치 Dashboard → Workspace → API Keys
스코프 Workspace 단위 (backend-design.md)
전달 pstone.init("psk_...") 또는 환경 변수 PSTONE_API_KEY
서버 처리 Backend가 키를 검증하고 workspace_id를 찾아 ClickHouse에 함께 저장

SDK는 workspace_id를 직접 보내지 않습니다. 키만 보내면 됩니다.

from pstone import pstone

# 인자로 전달
pstone.init("psk_live_xxxxxxxx")

# 또는 환경 변수만 설정한 뒤
# export PSTONE_API_KEY=psk_live_xxxxxxxx
pstone.init()

키를 소스코드·로그·이슈에 커밋하지 마세요.


환경 변수

변수 필수 설명
PSTONE_API_KEY 권장 Workspace API Key (init 인자 생략 시 사용)
PSTONE_INGEST_URL 선택 Ingest 베이스 URL (기본 https://api.profitstone.ai)
PSTONE_SERVICE_NAME 선택 OTel service.name (기본 pstone-app)

실제 전송 경로는 {PSTONE_INGEST_URL}/v1/ingest/traces 입니다.

로컬 Backend에 붙일 때:

export PSTONE_API_KEY=psk_test_...
export PSTONE_INGEST_URL=http://localhost:8000
pstone.init(ingest_url="http://localhost:8000")

OpenAI / Anthropic 계측

자동 (권장)

pstone.init(..., instrument=True) (기본값)이면, 프로세스에 openai / anthropic 패키지가 설치되어 있을 때 chat / messages API를 패치합니다.

  • OpenAI: chat.completions.create (및 parse가 있으면 함께)
  • Anthropic: messages.create
  • OpenAI-compatible (예: Perplexity 등 OpenAI 클라이언트 + 커스텀 base_url): OpenAI 계측 경로를 그대로 탑니다.

명시적 wrap

글로벌 패치 대신 클라이언트만 감쌀 수 있습니다.

from openai import OpenAI
from anthropic import Anthropic
from pstone import pstone

pstone.init("psk_live_...", instrument=False)

openai_client = pstone.wrap_openai(OpenAI())
anthropic_client = pstone.wrap_anthropic(Anthropic())

수집되는 주요 속성

OpenTelemetry gen_ai.* 계열:

Attribute 예
gen_ai.system openai, anthropic
gen_ai.request.model gpt-4o-mini
gen_ai.prompt 메시지 직렬화 (redaction 적용 가능)
gen_ai.completion 응답 텍스트
gen_ai.usage.input_tokens 입력 토큰
gen_ai.usage.output_tokens 출력 토큰

계측 코드는 원본 API 예외를 바꾸지 않습니다. Span 기록 실패는 조용히 무시되어 앱 핫 패스를 보호합니다.


옵션

pstone.init(
    "psk_live_...",
    ingest_url="https://api.profitstone.ai",
    service_name="my-ai-app",
    capture_content=True,   # 프롬프트·completion 수집
    redact=True,            # 이메일·전화번호 등 기본 PII 마스킹
    instrument=True,        # 자동 패치 on/off
    instrument_openai=True,
    instrument_anthropic=True,
)
옵션 기본 설명
capture_content True 프롬프트/completion을 Span에 넣을지
redact True 기본 PII 마스킹
instrument True 자동 계측 전체 on/off
instrument_openai True OpenAI 패치
instrument_anthropic True Anthropic 패치
use_batch True BatchSpanProcessor (테스트에선 False 권장)

민감 프롬프트를 보내지 않으려면:

pstone.init("psk_live_...", capture_content=False)

수동 Span

자동 계측 밖(커스텀 HTTP 등)에서는 헬퍼를 직접 쓸 수 있습니다.

from pstone.span import start_llm_span, record_llm_response

with start_llm_span(
    name="custom.llm",
    system="perplexity",
    model="sonar",
    prompt=[{"role": "user", "content": "hi"}],
) as span:
    # ... 호출 ...
    record_llm_response(
        span,
        completion="...",
        input_tokens=10,
        output_tokens=20,
    )

flush / shutdown

메서드 용도
pstone.flush() 대기 중인 Span을 Ingest로 강제 전송
pstone.shutdown() flush + 계측 해제 + TracerProvider 종료

배치 전송이므로, 짧은 CLI/스크립트는 종료 전에 flush()를 호출하세요.

try:
    # ...
finally:
    pstone.flush()
    pstone.shutdown()

데이터 흐름

고객 앱
  pstone.init(API Key)
  → OpenTelemetry Tracer + OTLP/HTTP Exporter
  → AI API 호출 시 Span 기록
  → POST {INGEST_URL}/v1/ingest/traces
       Authorization: Bearer <API Key>

profitstone_backend
  → API Key 검증 → workspace_id 해석
  → ClickHouse에 span + workspace_id 저장

SDK는 DB에 직접 붙지 않습니다. HTTPS Ingest만 사용합니다.


로컬 개발

# 레포 루트
make python-sync
make python-test
make python-build

# 또는 python/ 에서
cd python
uv sync
uv run pytest
uv build

테스트는 InMemorySpanExporter로 Ingest 없이 Span 속성만 검증합니다.

관련 문서:

문서 경로
SDK 설계 ../docs/sdk-design.md
아키텍처 ../../profitstone_docs/개발문서/architecture.md
Backend ../../profitstone_backend/docs/backend-design.md
에이전트 맵 ../AGENTS.md

PyPI 배포

pip install pstone이 되려면 PyPI에 업로드해야 합니다.

# 1) 토큰 설정 (레포 루트, 최초 1회)
cp .env.example .env
# .env 에 UV_PUBLISH_TOKEN=pypi-... 입력

# 2) 배포 (Python만 — JS/Java와 독립)
make python-publish

# 또는 python/ 에서
cd python && make publish

성공 직후부터 사용자가 pip install pstone을 사용할 수 있습니다.
절차 상세: ../docs/sdk-design.md §13.


라이선스

MIT

Release files for pstone 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pstone 0.1.3
File Size Uploaded
pstone-0.1.3.tar.gz 117.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pstone 0.1.3
File Interpreter ABI Platform
pstone-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 135.1 kB

Release files / pstone-0.1.3.tar.gz

Download URL pstone-0.1.3.tar.gz
Size 117.5 kB
Tags Source
SHA-256 checksum
How to use checksums
627f9407df83a71a57554422fe63848ae5940a81686fa2ac2812075a43e1ab2e
BLAKE2b-256 checksum
How to use checksums
5b7eac5198cf03a0a94fedf9c3e70f91d564bad8761d1b90aafcc970b477323a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pstone-0.1.3-py3-none-any.whl

Download URL pstone-0.1.3-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0d051db716ed1d62569aa06f7898f255b187cf1ab2ce2da02140f76425754b2
BLAKE2b-256 checksum
How to use checksums
105dbea9837e4341f57521cf155dd32d6ec1e2d74f2ec3959d5ec35f08c3cb23
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page