로컬 환경에서 Gemma를 구동하여 NDA에 안전한 제안 범위 정의 도구(Proposal Scoper)를 만들었습니다
요약
NDA 안전성을 최우선으로 고려한 로컬 기반 제안 범위 정의 도구 'ScopeLock'을 개발했습니다. 이 도구는 오픈 가중치 Gemma 모델을 Ollama를 통해 사용자 기기 내에서 구동하여, 고객의 민감한 RFP 문서를 외부 유출 위험 없이 분석합니다. ScopeLock은 요구사항 추출, 결정론적 가격 책정, 범위 확장 방지 장치를 제공하며 개발자에게 안전하고 체계적인 워크플로우를 제시합니다.
핵심 포인트
- NDA 위반 위험을 제거하는 로컬 우선(local-first) 도구입니다.
- 오픈 가중치 Gemma 모델과 Ollama를 활용하여 구동됩니다.
- 요구사항 추출, 가격 책정, 범위 확장 방지 등 전문적인 기능을 제공합니다.
- 클라이언트 콘텐츠의 외부 유출이 원천적으로 차단됨을 증명합니다.
이 내용은 Hacktoberfest 오픈소스 AI 챌린지 2주차: 사이드 허슬(Side Hustle) 제출물입니다.
내가 만든 것
시간은 밤 10시 30분입니다. 잠재적인 기업 고객으로부터 엄격한 상호 비밀유지협약(Non-Disclosure Agreement, NDA) 하에 14페이지 분량의 제안요청서(RFP)가 이메일로 도착했습니다. 그들은 내일 오전 9시까지 고정 가격 제안과 마일스톤 계획을 요구합니다.
프리랜서 또는 부티크 에이전시 엔지니어로서, 당신은 다음과 같은 어려운 딜레마에 빠집니다.
- 위험한 지름길: 고객의 기밀 브리프를 상업용 클라우드 챗봇(OpenAI, Anthropic)에 붙여넣습니다. 30초 만에 초안 제안서를 얻을 수 있지만, 독점 제품 아키텍처나 임상 데이터를 제3자 서버에 유출함으로써 계약상의 중대한 위반(material breach of contract)을 저질렀을 수도 있습니다.
- 보수적인 고군분투: 다음 5시간 동안 모호한 텍스트 페이지들을 수동으로 검토하고, 시간 범위를 손으로 계산하며, "완벽하게 버그가 없고 무한히 확장 가능해야 한다(must be completely bug-free and scale infinitely)"와 같은 9페이지의 사소한 문구를 놓치지 않았기를 기도합니다. 이 한 문구가 세 달간의 무급 범위 확장(scope creep)으로 이어질 수 있습니다.
저는 이 딜레마를 해결하기 위해 ScopeLock을 만들었습니다.
ScopeLock은 프리랜서 개발자를 위해 설계된 NDA 안전(NDA-safe), 로컬 우선(local-first) 제안 범위 측정 도구입니다. 이는 오픈 가중치(open-weights)를 가진 Google Gemma 모델을 Ollama에서 구동하여 클라이언트 브리프(PDF, Markdown 또는 일반 텍스트)를 전적으로 사용자 기기 내에서 처리합니다. ScopeLock은 다음 항목들을 출력합니다:
- 원자적 기능 및 비기능 요구사항 (Atomic Functional & Non-Functional Requirements): 각 요구사항은 브리프의 문구 그대로 인용된 구절에 근거하여 제시됩니다.
- 결정론적 가격 책정 및 마일스톤 분석 (Deterministic Pricing & Milestone Breakdown): 오직 결정론적 코드(deterministic code)로 엄격하게 계산되며, 언어 모델이 돈 계산이나 산술 연산을 수행하는 것이 원천적으로 차단됩니다.
- 범위 확장 방지 장치 (Scope-Creep Guardrails): 위험하거나 모호한 고객 문구를 플래그 지정하고, 즉시 붙여넣을 수 있는 작업 명세서(Statement of Work, SOW) 보호 조항을 생성합니다.
- '견적 전 질문 목록' 이메일: 고정 견적을 확정하기 전에 중요한 기술적 미지 항목들을 명확히 할 수 있도록 돕습니다.
- 제로 고객 콘텐츠 외부 유출 증명 (Zero Client-Content Egress Proof): 자동화된 카나리아 테스트(canary test)를 통해 검증됩니다.
데모
🚀 라이브 웹 앱 (Vercel): [https://scope-lock-zeta.vercel.app/](https://scope-lock-zeta.vercel.app/)
- 💻 GitHub 저장소: https://github.com/Rish-51/ScopeLock
(참고: 정직한 공개를 위해, 호스팅된 쇼케이스는 데모 모드로 실행되며, 클라우드 추론 없이 로컬 Gemma 4가 생성한 실제 실행 트레이스를 충실히 재현합니다.)
빠른 시작: 명령어 3개로 로컬에서 실행하기
ScopeLock은 100% 오픈 소스이며 오프라인으로 작동합니다:
# 1. 모델을 로컬에 풀(pull)하기
ollama pull gemma4:e4b
...
CLI를 통해 직접 실행할 수도 있습니다:
python -m backend.cli sample_brief.pdf --rate 120 --currency USD --contingency 20
코드
전체 소스 코드는 Apache-2.0 라이선스 하에 공개되었습니다:
👉 GitHub: Rish-51/ScopeLock
저장소의 주요 파일들:
backend/tests/test_no_content_egress.py: 기밀 텍스트가 사용자의 장치를 벗어나지 않음을 증명하는 Egress Canary Test.backend/schemas/proposal.py: 구조화된 출력을 강제하는 Pydantic v2 스키마.backend/core/pricing.py&frontend/src/lib/pricing.ts: 골든 테스트 피처(golden test fixtures)를 갖춘 결정론적 가격 책정 엔진.backend/services/scoping_service.py: Sentry 스팬(spans)과 복구 루프(repair loop)를 갖춘 5단계 에이전트 파이프라인.
제가 이것을 만든 방법
1. 왜 거대한 단일 스키마보다 작고 제약된 호출 3개가 더 나은가
소규모 오픈 웨이트 모델(2B~9B 파라미터)은 요구사항, 위험 요소, 마일스톤 일정 및 재정 총액을 포함하는 단일 거대한 중첩 JSON 문서를 생성하도록 강제될 경우 종종 어텐션 저하(attention degradation) 또는 JSON 자르기(JSON truncation) 문제를 겪습니다.
대신, ScopeLock은 순차적인 5단계 파이프라인을 사용합니다:
- Step A (
chat gemma4:e4b [requirements]): 간략한 설명에서 요구사항과 정확한 하위 문자열을 추출합니다. - Step B (
chat gemma4:e4b [risks]): 기술적 위험 및 범위 확장(scope-creep) 위험에만 초점을 맞춥니다. - Step C (
chat gemma4:e4b [milestones]): 마일스톤 산출물과 정수 시간(integer hours)에만 초점을 맞춥니다. - Tool 1 (
execute_tool verify_quotes): 견적을 간략한 설명 텍스트와 결정론적으로 검증합니다. - Tool 2 (
execute_tool compute_pricing): 코드를 사용하여 돈과 예비비를 결정론적으로 계산합니다. - Step D (
chat gemma4:e4b [client_email]): 명확화 이메일을 초안 작성합니다.
Pydantic v2 제약 디코딩(constrained decoding)을 통해 작업을 원자적 단계로 분해함으로써, Gemma 4는 벤치마크 스위트 전반에 걸쳐 100% 첫 시도 스키마 유효성률을 달성했으며 수정 재시도는 0회였습니다.
2. 언어 모델에게 산술 계산을 맡기지 마세요
ScopeLock의 핵심 엔지니어링 규칙은 다음과 같습니다: 모델에게 가격, 총액 또는 백분율을 요청하지 않습니다.
대신, 모델은 요구사항에 범주형 complexity_tags (예: PAYMENTS, COMPLIANCE, AUTH, REALTIME)를 할당합니다. 그런 다음, 결정론적인 Python 및 TypeScript 엔진이 MAX 태그 규칙을 사용하여 마일스톤 가격을 계산합니다:
- 요구사항에
AUTH(1.25x)와PAYMENTS(1.40x)가 연결된 마일스톤은 조정된 승수(multiplier) 1.40x를 받습니다 (1.75x의 부풀려진 곱셈이 아님). - 조정된 시간 =
시간 * 승수. - 예비비(기본 20%)는 조정된 시간에 대해서만 엄격하게 계산됩니다.
- 저가 옵션은 예비비 0%의 미조정 기본 시간을 사용하며, 권장 고정 가격에는 전체 버퍼가 포함됩니다.
3. Ollama num_ctx 자르기 함정 해결하기
로컬 LLM 구동의 주요 함정 중 하나는 컨텍스트 잘림(context truncation)입니다: Ollama의 기본 컨텍스트 창은 4,096 토큰으로, 실제 기반 모델 아키텍처가 지원하는 것과 관계없이 고정되어 있습니다! 10페이지 분량의 RFP를 입력할 경우, Ollama는 오류를 발생시키지 않고 문서의 후반부를 조용히 버립니다.
ScopeLock은 다음을 통해 이 문제를 해결합니다:
- 모든 채팅 요청에서
SCOPELOCK_NUM_CTX를 명시적으로 16,384 토큰으로 설정합니다. - 파서에서 토큰을 추정합니다 (
chars / 4). 만약 브리프가num_ctx의 60%를 초과하면, ScopeLock은 마크다운 헤더나 페이지 구분선을 따라 문서를 분할하고, 각 청크(chunk)마다 Step A를 실행한 후, 자동 ID 재인덱싱(R1, R2, ...)이 적용된 코드로 요구사항을 병합합니다.
4. Sentry 에이전트 트레이싱 (메타데이터만)
관측 가능성(Observability)은 Sentry의 OpenTelemetry 기반 GenAI 수동 계측(OTel GenAI v1.28)을 사용하여 구현되었습니다:
- 루트 에이전트 스팬:
invoke_agent ScopeLock Scoper(opgen_ai.invoke_agent) - 채팅 스팬:
chat gemma4:e4b(opgen_ai.chat,gen_ai.usage.input_tokens,output_tokens,scopelock.load_ms, 및scopelock.attempt추적) - 도구 스팬:
execute_tool verify_quotes및execute_tool compute_pricing(opgen_ai.execute_tool)
제로 콘텐츠 개인정보 보호 보장(zero-content privacy guarantee)을 유지하기 위해:
send_default_pii = Falseinclude_local_variables = Falsemax_request_body_size = "never"- 방어적 스크러빙 후크(Defensive scrubbing hooks)는 모든
gen_ai.input.messages또는gen_ai.output.messages를 제거합니다. SENTRY_DSN이 비어 있을 때는 원격 측정(Telemetry)이 완전히 비활성화됩니다.
5. Egress Canary 증명
브리프 콘텐츠가 기기를 벗어나지 않음을 증명하기 위해, ScopeLock은 자동화된 에그레스 카나리 테스트(test_no_content_egress.py)를 포함합니다. 이는 고유 토큰(CANARY-SECRET-<uuid>)을 기밀 브리프에 주입하고, 메모리 내 캡처 전송(in-memory capturing transport)을 통해 거래 경로를 거치게 한 후, 카나리나 임의의 8단어 시퀀스가 원격 측정 페이로드에 나타나지 않음을 검증합니다.
Open Innovation은 왜 중요할까요?
- 영업 비밀 및 NDA 준수: 상업 프리랜서의 경우, 클라우드 기반 LLM은 고객 작업에 법적으로 사용하기 어려운 경우가 많습니다. 로컬에서 구동되는 오픈 웨이트(open-weights) 모델을 사용하면 프리랜서가 소송이나 고객 기밀 유출 위험 없이 최신 AI 기술을 활용할 수 있습니다.
- 확정적 경제성 (한계 비용 $0):
evals/results.md에서 측정했듯이, 저희의 5가지 평가 브리프를 실행하는 데 14,466 토큰이 사용되었습니다. 로컬 Gemma 4에서는 한계 토큰 비용이 $0.00이었습니다. 반면, 독점 폐쇄 API(GPT-4o 또는 Claude 3.5 Sonnet)의 경우 제안서 실행당 $0.08~$0.11이 발생합니다. 매월 50개의 RFP를 분석하는 활발한 에이전시에게 오픈 웨이트는 구독 오버헤드를 제거해 줍니다. - 하드웨어 접근성 사다리: 오픈 모델을 사용하면 하나의 거대한 클라우드 클러스터에 종속되지 않습니다. 저사양 노트북의 개발자는
gemma4:e2b(~1.6GB VRAM)를, 표준 노트북의 개발자는gemma4:e4b를, 그리고 워크스테이션은gemma4:12b까지 사용할 수 있으며, 이는 단 하나의 환경 변수 변경(SCOPELOCK_MODEL)으로 가능합니다.
나의 에이전트 세션
이 프로젝트는 Google Antigravity와 Gemini 3.8 Flash를 결합하여 구축되었습니다. 이 에이전트는 Pydantic 스키마의 골격화, 공유된 황금 테스트 케이스(golden test cases)를 사용한 확정적 가격 책정 엔진 작성, Sentry OpenTelemetry 스팬 구성, 그리고 egress 카나리 테스트 스위트 검증을 지원했습니다.
나의 첫 사용자
저는 Upwork 및 직접 고객의 RFQ에 자주 입찰하는 독립 풀스택 개발자인 Karan에게 ScopeLock을 공유했습니다.
저희는 커스텀 마켓플레이스를 위한 비정형화된 고객 메시지에 대해 ScopeLock을 테스트했습니다:
- 시간 절약(Time Saved): Karan은 마일스톤을 수동으로 읽고 매핑하는 데 보통 1.5시간에서 2시간이 걸린다고 언급했다. ScopeLock은 3.85초 만에 근거 기반(grounded) 제안서를 생성했다.
- 범위 확장 방지(Scope Creep Saved): ScopeLock은 "완벽하게 버그가 없고 무한히 확장 가능하다(completely bug-free and scale infinitely)"라는 구문을 플래그 지정하고, 동시 접속자 수를 5,000명으로 제한하는 SLA 조항을 생성했다. Karan은 다음과 같이 언급했다: "고정 가격 계약에서 '무한 확장'이 얼마나 위험한지 깨닫지 못하고 아마도 말로만 받아들였을 것이다."
- 지불 의사(Willingness to Pay): Karan은 사용자 지정 SOW(Statement of Work) 조항 라이브러리 및 내보내기 템플릿을 통합한 다운로드 가능한 데스크톱 팩에 대해 $29–$49의 일회성 비용을 기꺼이 지불할 것이라고 밝혔다.
상금 부문 (Prize Categories)
- Gemma 활용 최우수 ($200): Ollama를 통해 로컬에서 실행되는 Gemma 4가 다단계 스코핑 에이전트(multi-stage scoping agent)에 동력을 공급한다. 모델 계단(
e2b,e4b,12b) 전반에 걸쳐 100% 인용 근거 비율(quote grounding ratio)과 제로 API 비용으로 평가되었다. - Render 활용 최우수 ($200): ScopeLock 워크벤치는 SPA 리라이트(SPA rewrites) 및 실제 녹화 실행 데모 모드를 갖춘 정적 사이트 청사진(
render.yaml)으로 Render에 배포되었다. - Sentry Agent Tracing 활용 최우수 ($100): 엄격한 메타데이터 스크러빙 훅(metadata scrubbing hooks)과 로컬 인메모리 TraceRecorder를 갖춘 완전한 OpenTelemetry GenAI 스팬 계층 구조(
gen_ai.invoke_agent,gen_ai.chat,gen_ai.execute_tool).
챌린지 태그 및 발견 (Challenge Tags & Discovery)
devchallenge #hf26challenge #hacktoberfest #ai #opensource #gemma #ollama #sidehustle
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기