Skip to main content

xsoft_comply Python SDK

xsoft comply 공식 Python SDK · PyPI 배포. AI 기본법 대응 AI 거버넌스 플랫폼의 감사기록을 남기는 클라이언트 라이브러리입니다.

설치

0) 가상환경(venv) 먼저 — externally-managed-environment 에러 예방

Ubuntu 23.04+ · Debian 12+ · Fedora 38+ 등 최신 배포판의 시스템 파이썬은 PEP 668 로 잠겨 있어 pip install 이 다음 메시지로 멈춥니다.

error: externally-managed-environment
× This environment is externally managed

시스템 파이썬을 건드리지 말고 가상환경에 설치하세요(권장).

# 1) venv 만들기 (python3-venv 가 없다면: sudo apt install python3-venv)
python3 -m venv ~/venv

# 2) venv 의 pip 으로 설치 — activate 없이 경로로 직접 불러도 됩니다
~/venv/bin/pip install --upgrade pip

# 3) 실행도 같은 venv 로
~/venv/bin/python -c "import xsoft_comply; print(xsoft_comply.__version__)"

셸에 붙여 쓰려면 source ~/venv/bin/activate 후 pip·python 을 그대로 쓰면 됩니다 (빠져나올 때는 deactivate).

venv 를 만들 수 없는 환경(컨테이너 베이스 이미지 등)에서만 마지막 수단으로 pip install --break-system-packages ... 를 씁니다. 시스템 패키지와 충돌할 수 있어 권장하지 않습니다.

1) 설치 방법 — PyPI 정식 배포 (표준)

xsoft-comply 는 PyPI 에 정식 배포되어 있습니다. 아래가 표준 설치 경로입니다.

이 배포본 = 1.0.1 (LICENSE 동봉). pip install xsoft-comply 는 최신 게시본을 설치합니다. 배포 파일의 무결성 확인값(sha256)은 버전별로 릴리스 노트(RELEASES.md)에 기재합니다. README 는 배포 파일 안에 포함되므로 자기 버전의 확인값을 여기에 적지 않습니다.

~/venv/bin/pip install xsoft-comply

소스에서 직접(개발·수정 목적) 설치하려면:

# 저장소 루트에서
~/venv/bin/pip install -e sdk/python

★ 안전하게 설치하기 (권장)

이 SDK 는 고객사 서버 안에서 실행됩니다. 공급망 공격(타이포스쿼팅·계정 탈취)을 막으려면 이름을 정확히 쓰고 해시를 고정하시기 바랍니다.

# ① 정확한 배포 이름 = xsoft-comply  (import 이름은 xsoft_comply)
#    비슷한 이름(xsoftcomply · xsoft-compliance 등)은 당사 배포본이 아닙니다.
# ② 해시 고정 = 아래 예시대로 requirements.txt 파일을 직접 만들어 적어두고
#    --require-hashes 로 설치합니다 (이 파일은 패키지에 동봉되지 않습니다).
~/venv/bin/pip install --require-hashes -r requirements.txt

아래 내용을 담은 requirements.txt 를 직접 생성합니다(확인값은 릴리스 노트의 값을 그대로 복사):

# <확인값> 자리에는 릴리스 노트(RELEASES.md)에 기재된 해당 버전의 sha256 값을 넣습니다.
xsoft-comply==1.0.1 \
    --hash=sha256:<whl 파일의 확인값> \
    --hash=sha256:<tar.gz 파일의 확인값>

각 버전의 배포 파일 sha256 은 RELEASES.md 에 적어 둡니다. 이 README 자체가 배포 파일 안에 들어가므로 여기에 자기 확인값을 적으면 적는 순간 그 값이 틀려집니다 — 그래서 확인값 기록은 패키지 밖 파일에 둡니다.

참고로, 이벤트의 occurred_at(발생 시각)과 event_id(이벤트 식별자)는 언제나 SDK 가 스스로 만들며, 이를 바깥에서 덮어쓰는 파라미터는 배포 패키지에 없습니다.

설치 후 확인:

~/venv/bin/python -c "import xsoft_comply; print(xsoft_comply.__version__)"

당사가 지키는 것 — 외부 의존성 0(표준 라이브러리만), 설치 시 실행되는 코드 없음 (setup.py·.pth 없음). import 만으로는 네트워크를 열지 않습니다 (init() 을 호출해야 백그라운드 전송 작업이 시작됩니다).

외부 의존성 없음(표준 라이브러리만). Python 3.9 이상.

빠른 시작

import xsoft_comply as xc

xc.init(
    api_key="xsk_live_...",            # API 키 (대시보드에서 발급)
    endpoint="https://your-domain.com/api/v1",
    log_llm_content=False,             # 기본값 · 원문 미전송
)

with xc.session(agent_id="support-bot") as s:
    s.llm_call(
        model="gpt-4o-mini",
        provider="openai",
        tokens_in=512,
        tokens_out=128,
        latency_ms=820,
    )
    s.tool_call(tool="crm.lookup", status="ok", latency_ms=12)
    s.data_access(resource="customer_profile", scope="read", record_count=1)
    s.decision(decision="escalate", options=3, confidence=0.72)
    s.human_review(human_review="approved", reviewer_role="manager")
    s.action(action="ticket.create", status="ok")

세션 컨텍스트를 벗어나면 session_end 이벤트가 자동으로 기록 대기열에 추가됩니다.

저절로 남는 것과 직접 적는 것

구분 저절로 남습니다 직접 적으셔야 합니다
세션 session_start · session_end (세션 컨텍스트가 처리) —
이벤트 — LLM 호출 · 도구 호출 · 데이터 조회 · 업무 처리 · 판단 · 사람 검토
프레임워크 연동 LangChain · OpenAI Agents SDK 의 주요 실행 판단 · 사람 검토 · 업무별 metadata

이벤트 6종

이벤트 언제 기록됩니까 메서드
session_start 세션이 시작될 때 세션 컨텍스트가 자동 처리
llm_call LLM 을 호출했을 때 s.llm_call(...)
tool_call 외부 도구·API 를 호출했을 때 s.tool_call(...)
data_access 데이터를 조회했을 때 s.data_access(...)
action 실제 처리·업무를 실행했을 때 s.action(...) · s.decision(...) · s.human_review(...)
session_end 세션이 끝날 때 세션 컨텍스트가 자동 처리

조항 증적 (제31~36조)

event_type 은 6종입니다 — session_start · llm_call · tool_call · data_access · action · session_end.

decision() · human_review() 는 메서드로 그대로 사용합니다. 내부에서 action + 조항 증적(제34조 고영향 책무)으로 조립되어 전송됩니다 → 기존 코드는 그대로 동작합니다. 달라지는 것은 «당사 서버가 이 기록을 어떤 조항으로 분류해 보관하는가» 뿐입니다.

with xc.session(agent_id="loan-bot") as s:
    # 한 이벤트에 여러 조항 증적을 담을 수 있습니다(배열)
    s.action("loan.approve", status="ok", evidence=[
        xc.evidence_block(34, supervisor_id="sup-1", decision_basis="심사 기준표 v3"),
        xc.evidence_block(31, ai_generated_label="labeled", label_method="watermark",
                          output_id="out-99"),
    ])

    # 운영 중 기록이 아닌 «선언» 성격의 값도 같은 경로로 보냅니다.
    # 선언 정보도 일반 이벤트 경로로 기록하여 변경 이력을 함께 관리합니다.
    s.evidence(32, source="declared", evidence_key="model-2026",
               model_id="m-100", model_version="1.2",
               risk_management_policy_ref="RM-2026-01")
  • evidence_key 는 같은 선언을 반복 전송해도 하나의 증적으로 관리하기 위한 중복 방지 키입니다. 생략하면 이벤트마다 새 키가 되어 매번 새 증적이 됩니다.
  • 수집 항목은 조항별 허용 항목명만 받습니다. 오타·정의되지 않은 이름은 경고 후 제외(drop) 됩니다(이벤트 자체는 거부되지 않습니다).
  • 값에 원문(prompt/response)이나 판정어("준수/위반")를 넣지 마십시오.

값 규칙·형식 제약 — 타입이 틀리면 해당 필드가 저장되지 않습니다 (★ 중요)

각 수집 항목은 정해진 타입이 있습니다. 타입이 맞지 않는 값은 서버가 해당 항목만 제외합니다(drop). 이벤트는 202(접수)로 응답되고 제외 사유는 응답에 나타나지 않으므로, 접수에 성공해도 감사 시점에 해당 항목이 비어 있을 수 있습니다. 전송 전 dry_run=True·validate() 로 확인하시기 바랍니다.

타입 허용 값 맞지 않으면 예시
텍스트(text) 아무 문자열(500자 초과 시 잘림) 숫자·객체도 문자열로 변환 supervisor_id="sup-1"
숫자(numeric) 숫자·숫자 문자열 그 밖의 문자 → 제외 confidence=0.68
정수(bigint) 정수·정수 문자열 소수는 내림 · 숫자 아님 → 제외 evidence_document_id=123
참/거짓(boolean) true/false·"true"/"false" 1·"yes" → 제외 control_applied=true
날짜(date) 해석 가능한 날짜(YYYY-MM-DD 저장) 형식 불명 → 제외 submission_date="2026-02-10"
  • null·빈 문자열 = 제외. 값이 없으면 넣지 마십시오.
  • 산업별(로봇·음성·자율주행·의료·채용·금융) 계측 예시·전송 흐름은 설치 및 사용 설명서(PDF) 참조.

수집 항목 (조항별)

evidence_block(조항, **항목) 또는 s.evidence(조항, ...) 에 넣는 수집 항목입니다. 조항마다 허용된 항목명이 정해져 있으며, 여기에 없는 이름은 경고 후 저장되지 않습니다(이벤트 자체는 거부하지 않습니다).

본 SDK 는 항목의 필수 여부를 판정하지 않습니다. 어떤 항목을 언제 전송할 것인지는 이용사업자가 정합니다. 전송되지 않은 항목은 비어 있는 상태로 보관되며, 이를 미준수로 해석하지 않습니다.

본 목록은 「인공지능 발전과 신뢰 기반 조성 등에 관한 기본법」 제31조부터 제36조까지 및 같은 법 시행령 제23조부터 제29조까지가 요구하는 사실을 수집하기 위한 항목입니다.

제31조 인공지능 투명성 확보 의무 — 15개

수집 항목 타입 의미 근거
prior_notice_provided boolean 사전 고지 이행 여부 법 §31①
disclosure_method text 고지 방법 영 §23①1~4
disclosure_version text 적용한 고지 문구의 버전 영 §23①
ai_generated_label text 생성 결과물 표시 이행 여부 법 §31②
label_method text 표시 방법 영 §23②1~2
machine_readable_label text 기계판독 표시 시 안내 제공 여부 영 §23②2 후단
synthetic_media text 실제와 구분이 어려운 결과물 해당 여부 법 §31③
label_visibility text 이용자가 명확히 인식할 수 있는 방식 여부 법 §31③
accessibility_method text 쉽게 확인할 수 있는 방법 영 §23③1
audience_consideration text 주된 이용자의 조건 고려 영 §23③2
artistic_relaxation boolean 예술적·창의적 표현물 완화 적용 여부 법 §31③ 후단
exemption_type text 적용 예외 유형 영 §23④1~3
exemption_basis text 예외로 본 근거 영 §23④
output_id text 대상 결과물 식별 법 §31②③
media_type text 결과물 매체 종류 법 §31③

제32조 인공지능 안전성 확보 의무 — 24개

수집 항목 타입 의미 근거
training_compute numeric 학습 누적 연산량 영 §24①1
frontier_technology_status text 최첨단 기술 적용 여부 영 §24①2
frontier_technology_basis text 그 판단의 근거 영 §24①2
broad_serious_impact_status text 광범위·중대한 영향 우려 여부 영 §24①3
broad_serious_impact_basis text 그 판단의 근거 영 §24①3
model_id text 대상 모델 식별 법 §32①
model_version text 모델 버전 법 §32①
risk_management_policy_ref text 위험관리체계 문서 참조 법 §32①2
submission_status text 이행 결과 제출 여부 법 §32②
submission_date date 제출일 법 §32②
risk_id text 위험 건 식별 법 §32①1
risk_signal_source text 위험을 식별한 경로 법 §32①1
risk_lifecycle_stage text 위험이 발생한 수명주기 단계 법 §32①1
risk_type text 위험 구분 법 §32①1
risk_level text 위험 평가 결과 법 §32①1
risk_action text 위험 완화 조치 법 §32①1
risk_status text 위험 처리 상태 법 §32①1
incident_id text 안전사고 건 식별 법 §32①2
incident_detection_source text 사고 감지 경로 법 §32①2
incident_type text 사고 구분 법 §32①2
incident_severity text 사고 심각도 법 §32①2
incident_action text 사고 대응 조치 법 §32①2
incident_status text 사고 처리 상태 법 §32①2
incident_close_reason text 사고 종결 사유 법 §32①2

제34조 고영향 인공지능과 관련한 사업자의 책무 — 38개

수집 항목 타입 의미 근거
risk_mgmt_ref text 위험관리방안 문서 참조 법 §34①1
control_applied boolean 통제 실행 여부 법 §34①1
control_type text 통제 구분 법 §34①1
control_outcome text 통제 결과 법 §34①1
control_version text 적용된 통제 규칙의 버전 법 §34①1
explanation_policy_ref text 설명 방안 문서 참조 법 §34①2
decision_basis text 최종결과 도출에 활용된 주요 기준 법 §34①2
training_data_reference text 학습용데이터 개요 참조 법 §34①2
explanation_available boolean 설명 제공 가능 여부 법 §34①2
explanation_delivery_status text 설명 전달 결과 법 §34①2
user_protection_policy_ref text 이용자 보호 방안 문서 참조 법 §34①3
user_protection_action text 이용자 보호 조치 법 §34①3
protection_reason text 보호 조치 사유 법 §34①3
protection_outcome text 보호 조치 결과 법 §34①3
oversight_policy_ref text 사람 관리·감독 체계 문서 참조 법 §34①4
supervisor_id text 관리·감독자 식별 법 §34①4
supervisor_name text 관리·감독자 성명 영 §27①4
supervisor_contact text 관리·감독자 연락처 영 §27①4
supervisor_role text 관리·감독자 직책 법 §34①4
intervention_trigger text 개입 조건 법 §34①4
intervention_authority text 개입 권한 및 범위 법 §34①4
oversight_required boolean 사람 검토 필요 여부 법 §34①4
oversight_request_status text 사람 검토 요청 상태 법 §34①4
oversight_handover_status text 검토 대상 인계 상태 법 §34①4
reviewer_id text 검토자 식별 법 §34①4
reviewer_role text 검토자 직책 법 §34①4
review_status text 검토 진행 상태 법 §34①4
review_result text 검토 결과 법 §34①4
human_override text 사람에 의한 변경 여부 법 §34①4
override_reason text 변경 사유 법 §34①4
evidence_document_id bigint 조치 근거 문서 참조 법 §34①5
document_version text 보관 문서의 버전 법 §34①5
retention_status text 문서 5년 보관 상태 영 §27②
publication_status text 주요 내용 게시 여부 영 §27①
publication_url text 게시 위치 영 §27①
committee_matter text 위원회 심의·의결 사항 법 §34①6
alt_compliance_basis text 다른 법령에 따른 조치로 갈음하는 근거 법 §34③ · 영 §27⑤
downstream_exemption boolean 중대한 기능 변경이 없어 이행한 것으로 보는 경우 영 §27③

제33조 · 제35조 · 제36조 — 수집 항목 없음

조항 사유
제33조 고영향 인공지능의 확인 제공 전 사전 검토 및 정부 확인 요청은 호출 시점마다 발생하지 않습니다. 관리 화면 및 문서 등록 경로에서 관리합니다.
제35조 고영향 인공지능 영향평가 영향평가의 내용은 시행령 제28조제1항이 정하는 바에 따라 영향평가서에 포함됩니다. 문서 등록 경로에서 관리합니다.
제36조 국내대리인 지정 국내대리인의 지정 및 신고는 회사 단위의 사실입니다. 회사 설정 화면에서 관리합니다.

★ 위 세 조항의 항목을 SDK 로 전송하면 허용된 항목명에 없으므로 경고 후 저장되지 않습니다.

전송 전 로컬 확인

xc.init(..., dry_run=True)     # ① 네트워크 전송 없음. 전송 데이터·조항 연결·수집 항목·가림 결과를 콘솔에 출력
report = xc.validate(evt)      # ② 조항별 수집 항목 전송 «사실» 집계 (판단 아님)
print(xc.preview())            # ③ 이벤트 1건의 전송 내용을 로컬에서 확인
python -m xsoft_comply.preview   # 설치 확인용 이벤트 1건 출력

validate() 는 「수집 항목 N개 중 M개가 전송되었다」는 사실만 반환합니다. 준수 또는 위반 여부를 판단하지 않습니다(변호사법 제109조).

블록마다 반환하는 값 =

키 뜻
field_total · field_filled 그 조항의 수집 항목 수 · 그중 값이 전송된 수
field_empty 전송되지 않은 수집 항목 이름
unknown_fields 허용된 항목명에 없어 저장되지 않을 이름(오타 확인용)

★ field_empty 에 이름이 많다는 것은 미준수를 뜻하지 않습니다. 어떤 항목을 전송할 것인지는 이용사업자가 자신의 시스템에서 정하며, 해당 사실이 발생하지 않은 항목은 비어 있는 것이 정상입니다.

LangChain 연동

from langchain_openai import ChatOpenAI

handler = xc.langchain_handler()
llm = ChatOpenAI(callbacks=[handler])

with xc.session(agent_id="lc-agent") as s:
    response = llm.invoke("안녕하세요")

langchain 또는 langchain-core 가 설치돼 있으면 BaseCallbackHandler 를 상속합니다. 없으면 LangChain 의존성 없이 사용할 수 있는 기본 Python 객체로 동작합니다.

OpenAI Agents SDK 연동

import asyncio
import xsoft_comply as xc
from agents import Agent, Runner, function_tool

@function_tool
def lookup_order(order_id: str) -> str:
    return f"주문 {order_id} 상태 = 배송중"

agent = Agent(name="order-bot", model="gpt-4o-mini", tools=[lookup_order])
xc.instrument(agent)                     # 에이전트 연동 설정(AgentHooks)

async def main():
    with xc.session(agent_id="order-bot"):
        await Runner.run(
            agent, "주문번호 A-1024 상태 알려줘.",
            hooks=xc.agents_run_hooks(),  # 실행 알림 처리기 등록(작업 인계까지 기록)
        )

asyncio.run(main())

기록 항목 = 에이전트 시작·종료, 도구 호출(이름·소요시간), LLM 호출(모델·토큰 수), 작업 인계. 원문(입력·출력)은 전송하지 않고 길이만 남깁니다. 두 처리기를 함께 써도 중복 기록을 방지합니다(이미 연동된 에이전트는 실행 알림 처리기가 건너뜁니다).

이벤트 종류별 로그 토글

xc.init(..., log_events={"tool_call": False, "data_access": False})

비활성화한 이벤트 유형에는 순번(seq)을 부여하지 않으므로, 이벤트 순서 검증의 연속성이 유지됩니다. session_start · session_end 는 끌 수 없습니다(끄면 실행 흐름 기록 자체가 성립하지 않습니다).

정책 기반 실행 차단

rules = [
    {"id": "no-mass-delete", "when": {"tool": "crm.delete_all"},
     "effect": "block", "reason": "대량 삭제는 사람 승인 후에만"},
    {"id": "export-warn", "when_re": {"tool": r"^crm\.export"}, "effect": "warn"},
]
xc.init(..., policy=rules)              # policy_enforce=False 면 기록만 하고 차단하지 않습니다

with xc.session(agent_id="support-bot") as s:
    outcome = s.run_tool("crm.delete_all", delete_everything)
    if outcome.blocked:
        ...                              # 도구를 **실행하지 않은** 상태입니다

차단은 예외를 발생시키지 않습니다. outcome.blocked 로 알려주고, 감사기록에는 policy_result="blocked" · metadata.policy_rule 이 남습니다. s.check("tool_call", tool="…") 로 평가만 할 수도 있습니다.

전자서명 (ed25519 · 의존성 0)

xc.init(..., sign=True)                 # 키가 없으면 로컬에 생성해 소유자만 읽고 쓸 수 있는 권한(0600)으로 보관을 시도합니다
print(xc.signing_public_key())          # 감사인에게 전달할 공개키(개인키는 반환 경로 없음)

서명 대상 = trace_id·seq·event_id·type·occurred_at·라벨 필드·metadata 해시·직전 서명. 보관된 기록만 보고 검증할 수 있고, 값이 한 글자만 달라져도 검증에 실패합니다. 서명은 백그라운드 전송 작업에서 수행합니다(호출 스레드의 부담을 늘리지 않습니다).

서명 주체는 SDK(고객 프로세스 안) 입니다 — 서버가 대신 서명하는 「서버 서명」 이 아니라 클라이언트 전자서명(ed25519) 입니다. 개인키는 고객 서버 밖으로 나가지 않고, 당사는 공개키로 검증만 합니다.

보관기간(retention)

xc.init(..., retention_days=3650)       # 기본 1825일(5년) · 추가 보관 옵션 사용 시 그에 맞춰 설정합니다

이벤트 부가정보(metadata)에 _retain_until(만료일)이 남습니다. 만료분 정리는 운영측 도구가 수행합니다.

_retain_until 은 한국 날짜(KST) 기준입니다. 이 값은 절대시각이 아니라 사람이 읽는 날짜이며, 한국 시각으로 같은 날 기록된 이벤트는 만료일도 같아야 하기 때문입니다. occurred_at·전자서명 시각 같은 절대시각은 UTC 입니다.

수동 flush / 종료

xc.flush(timeout=5.0)   # 대기열이 빌 때까지 최대 5초 대기
xc.shutdown()           # 백그라운드 전송 작업 정지

프로세스 종료 시 atexit 처리기가 자동으로 최대 2초 동안 전송 완료를 시도합니다.

서버리스에서는 flush_on_return 을 쓰십시오

서버리스는 응답을 반환한 뒤 컨테이너를 멈춥니다. 백그라운드 전송 작업도 함께 멈추므로, 큐에 남아 있던 이벤트가 전송되지 않을 수 있습니다. 오류도 남지 않습니다.

import xsoft_comply as xc

@xc.flush_on_return
def handler(event, context):
    with xc.session(agent_id="my-agent") as s:
        ...
    return {"statusCode": 200}
  • 핸들러가 값을 돌려주기 직전에 큐를 비웁니다.
  • flush 가 실패해도 핸들러의 반환값과 예외는 그대로 통과합니다.
  • xc.is_serverless() 로 현재 환경이 서버리스로 보이는지 확인할 수 있습니다.

유실 계측 — dropped 와 failed 를 함께 확인하십시오

중요한 운영 위험은 이벤트 누락입니다. 그래서 전송되지 않은 이벤트를 두 갈래로 나눠 셉니다. 원인이 다르면 조치도 다르기 때문입니다.

xc.dropped_events()   # 대기열 초과로 누락된 건수
xc.failed_events()    # 서버 거부로 전송되지 않은 건수
함수 언제 늘어납니까 무엇을 확인해야 합니까
dropped_events() SDK 내부 대기열이 가득 차 제외했을 때 max_queue 를 키우거나 flush_interval 을 줄입니다
failed_events() 서버가 400·401·403·413 등으로 거부했을 때 API 키 · 요금제 · 전송 본문 크기를 확인합니다
  • 두 값과 로컬 임시 보관(스풀) 상태를 함께 확인하십시오. 스풀에 보관 중인 건(403 PLAN_REQUIRED · 429 · 5xx)은 재전송 대상 이라 두 카운터에 잡히지 않습니다.
  • 세는 단위는 이벤트 건수 입니다(전송 묶음 수가 아닙니다). 한 번의 전송 요청에 여러 건이 실립니다.
if xc.dropped_events() or xc.failed_events():
    log.error("감사기록 누락 가능 — 대기열 초과 %d건 · 서버 거부 %d건",
              xc.dropped_events(), xc.failed_events())

증상별 확인 순서

증상 먼저 확인할 것
패키지 import 실패 가상환경 경로 · 설치한 이름(xsoft-comply) · Python 3.9 이상
운영 화면에 기록이 없음 API 키 · endpoint · 세션 종료 또는 flush() 호출 · 요금제 권한
dropped_events() 증가 큐 용량(max_queue)과 flush 주기 · 일시적인 대량 전송 여부
failed_events() 증가 API 키 · 요금제 · 배치 본문 크기 · 서버 응답 코드
서버리스에서 마지막 기록이 없음 반환 직전 flush() 또는 @xc.flush_on_return 사용 여부

애플리케이션 영향 최소화 설계

xsoft comply SDK 는 호출 스레드에서 네트워크 전송을 하지 않도록 설계했습니다. 다음 8가지 동작 원칙을 따릅니다.

1. 모든 공개 함수는 예외를 호출자에게 전달하지 않습니다

init() · session() · s.llm_call() 등 모든 공개 함수는 최상위 try/except BaseException 으로 감쌉니다. KeyboardInterrupt · SystemExit 만 다시 발생시킵니다(프로세스 종료 신호를 차단하지 않기 위해).

# SDK 내부 구조 (단순화)
def llm_call(self, ...):
    try:
        evt = build_event(...)
        buffer.put(evt)   # 대기 없이 즉시 반환
    except (KeyboardInterrupt, SystemExit):
        raise
    except BaseException:
        pass              # 오류를 호출자에게 전달하지 않습니다

2. 호출 스레드는 네트워크 전송을 하지 않습니다

이벤트 기록은 queue.put_nowait() 만 실행합니다. 대기열이 가득 차면 가장 오래된 항목을 먼저 제외하고 새 항목을 넣습니다. 대기 없음.

고객 스레드  →  put_nowait(event)  →  [대기열]  →  백그라운드 전송 작업  →  전송 요청

3. 전송은 백그라운드 스레드(daemon thread) 1개가 담당합니다

threading.Thread(daemon=True) 로 생성됩니다. 이 스레드는 Python 인터프리터가 종료될 때 함께 종료되므로 고객 프로세스 종료를 지연시키지 않습니다.

4. 전송 대기 제한 시간: 연결 2초 / 응답 3초

urllib.request 에 합산 5초 제한 시간을 설정합니다. requests · httpx 등 외부 라이브러리 의존성이 없습니다.

5. 전송 실패 시 로컬 임시 보관 → 재시도 간격 조정

연결 거부 · 서버 오류 · 시간 초과 등 네트워크 장애 시:

  1. 이벤트를 ~/.xsoft_comply/spool/events.jsonl 에 줄 단위로 추가 기록합니다
  2. 재시도 간격을 점차 늘려 대기합니다 (1초 → 2초 → 4초 → 8초 → 최대 30초)
  3. 대기 후 재전송을 시도합니다

6. 임시 보관 파일 상한 (기본 32 MB)

임시 보관 폴더의 총 크기가 32 MB 를 초과하면 오래된 파일부터 삭제합니다. 디스크 쓰기 실패도 예외를 호출자에게 전달하지 않습니다.

7. init() 전에 이벤트를 기록해도 중단되지 않습니다

대기열이 준비되지 않은 상태에서 이벤트 기록은 아무 작업 없이 즉시 반환됩니다.

8. 프로세스 종료 시 자동 전송 시도 (최대 2초)

import atexit
atexit.register(_atexit_handler)   # init() 최초 호출 시 1회 등록

def _atexit_handler():
    flush(timeout=2.0)             # 2초 후 반드시 반환

프로세스가 정상 종료될 때 대기열에 남은 이벤트의 전송을 최대 2초 동안 시도합니다. 2초 안에 완료되지 않아도 프로세스 종료를 지연시키지 않습니다.


원문을 당사 수집 API 로 전송하지 않는 기본 설계

content= 인자로 원문(prompt/response)을 넘겨도 원문 자체는 당사 수집 API 로 전송되지 않습니다. 대신 content_len (길이) 과 content_sha256_8 (sha256 앞 8자) 만 부가정보에 포함됩니다.

원문(prompt/response)은 설계상 전송·보관되지 않습니다. 근거는 조항 표준필드로 남습니다.

다음 부가정보(metadata) 키가 있으면 SDK 에서 자동 제거하고, 제거된 키의 개수를 기록합니다: prompt, response, messages, content, input, output 등 21개. 다만 부가정보의 다른 키에 담긴 값까지 원문인지 판별하지는 못하므로, 부가정보와 조항 증적에는 원문·민감정보를 입력하지 마십시오.

개인정보 처리 원칙

1. 적용 범위

본 SDK 가 당사 수집 API 로 전송하는 값은 ① 부가정보(metadata) 와 ② 조항 증적(evidence) 두 가지이며, 개인정보 처리 방식이 서로 다릅니다.

구분 무엇인가 개인정보 처리
부가정보(metadata) 이용자가 이벤트에 자유롭게 덧붙이는 값. 항목을 당사가 정하지 않습니다 ★ 자동으로 가립니다(제2항)
조항 증적(evidence) 법 제31조부터 제36조까지가 요구하는 값. 항목명과 형식을 당사가 정합니다 ★ 가리지 않습니다(제3항)

2. 부가정보(metadata) — 자동 가림 대상

부가정보는 이용자가 무엇이든 담을 수 있는 자리이므로, 개인정보가 의도치 않게 포함될 수 있습니다. 이에 본 SDK 는 전송 전 이용자 서버에서 다음 형식의 값을 자동으로 가립니다.

대상 형식 처리 결과
주민등록번호 ******-*******
휴대전화번호 010-****-****
전자우편주소 u***@example.com
카드번호(16자리) 1234-****-****-5678

가림이 한 건이라도 발생한 경우 metadata._pii_masked 값이 true 로 기록됩니다.

본 항의 가림은 이용자 보호를 위한 예비적 조치이며, 이용자가 부가정보에 개인정보를 담지 않을 책임을 대신하지 않습니다.

3. 조항 증적(evidence) — ★ 가리지 않습니다

본 SDK 는 조항 증적에 포함된 값을 가리지 않으며, 이용자는 해당 값을 가리지 않은 원문 그대로 전송하여야 합니다.

이는 관계 법령이 해당 항목의 게시를 요구하기 때문입니다.

인공지능 기본법 시행령 제27조제1항제4호 — 인공지능사업자는 해당 고영향 인공지능을 관리·감독하는 사람의 성명 및 연락처를 사무소·사업장 또는 인터넷 홈페이지 등에 게시해야 한다.

가려진 값(예: 홍**)은 위 조항이 요구하는 성명에 해당하지 않습니다. 이용자가 임의로 가려 전송한 경우 해당 값은 감사 대응 자료로서의 효력을 상실할 수 있으며, 이로 인하여 발생하는 불이익에 대하여 당사는 책임을 지지 않습니다.

4. 당사 서비스 화면에서의 표시

당사는 제3항에 따라 수집한 값을 원문으로 보관하되, 이용자 화면에는 다음 항목 일부를 가린 형태로만 표시합니다.

항목 화면 표시
supervisor_id · supervisor_name · supervisor_contact · reviewer_id 가운데를 가려 표시합니다 (예: 홍**)
supervisor_role · reviewer_role 직책·역할에 해당하므로 가리지 않습니다

가림은 당사 서버에서 수행되며, 가리기 전의 값은 이용자 화면(브라우저)으로 전달되지 않습니다. 감사 대응 자료로 제공되는 증적 묶음에는 원문 그대로 포함됩니다.

5. 항목의 필수 여부

본 SDK 는 각 항목의 필수 여부를 판정하지 않습니다. 전송되지 않은 항목은 감사 대응 자료에 **「미기록」**으로 사실대로 표기됩니다.

라이선스

MIT

Metadata

Release files for xsoft-comply 1.0.1

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

Source distribution (sdist)

Source distribution for xsoft-comply 1.0.1
File Size Uploaded
xsoft_comply-1.0.1.tar.gz 92.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xsoft-comply 1.0.1
File Interpreter ABI Platform
xsoft_comply-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 173.2 kB

Release files / xsoft_comply-1.0.1.tar.gz

Download URL xsoft_comply-1.0.1.tar.gz
Size 92.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5a77aa3947b989a978f13b340fb0b4405b68ebdfab9c9b791ef1f68279a9f5b5
BLAKE2b-256 checksum
How to use checksums
94853f5ccac7e6309759386f444e230012b36a35475dbde7096087d1fc670600
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / xsoft_comply-1.0.1-py3-none-any.whl

Download URL xsoft_comply-1.0.1-py3-none-any.whl
Size 81.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7f9a21c37f8b3e2d95bb7f2613716ec3152d84df09ff35f2a12c0314aeaaa5e0
BLAKE2b-256 checksum
How to use checksums
d5665a8b4bf934728cfc06d101b6c87a769ccb5b674493496b110f6c3eb7d775
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

1.0.2

2 release files

This release

1.0.1 This release

2 release files

1.0.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