Featured Post

개발자 외주 계약서 사인하기 전, Claude로 독소조항 걸러내는 현실적인 방법

Claude - 계약서 검토 관련 이미지

지난달에 태국 치앙마이에 잠깐 머물면서 일하고 있었어요. 아침에 카페 가서 시원한 땡모반 하나 시켜놓고, 노트북 열고, “아 오늘은 꽤 괜찮은 하루겠는데?” 싶었거든요. 그런데 메일함에 외주 계약서 초안이 하나 들어와 있더라고요. 그 순간부터 마음이 좀 무거워졌습니다. 뭐랄까, 개발자는 복잡한 장애 로그나 난해한 비동기 버그는 몇 시간씩 붙잡고 보면서도, 계약서에 나오는 “갑은 을의 지식재산권을…” 이런 문장 앞에서는 이상하게 눈이 흐려지잖아요.

저도 예전에는 그랬어요. “뭐 별일 있겠어” 하고 대충 넘긴 적도 있었고요. 그런데 외주 몇 번 해보면 알게 됩니다. 계약서 한 줄이 생각보다 무섭다는 걸요. 잘못 사인하면 내가 원래 가지고 있던 공통 코드까지 애매하게 묶일 수도 있고, “무상 유지보수”라는 이름으로 끝도 없는 수정 요청을 받을 수도 있어요. 그렇다고 계약서 받을 때마다 변호사 검토를 맡기자니 비용도 부담스럽고, 일정도 빠듯하고요.

그래서 저는 작년부터 외주 계약서나 API 이용 약관을 볼 때 Claude를 꽤 적극적으로 쓰고 있습니다. 물론 Claude가 변호사를 대신할 수는 없어요. 이건 정말 분명히 말하고 싶습니다. 다만 계약서에 숨어 있는 위험한 문장을 먼저 걸러내는 1차 필터로는 정말 쓸 만합니다. 특히 Claude 3.5 Sonnet은 긴 문서의 맥락을 잡는 능력이 좋아서, 개발자 입장에서 찜찜한 조항을 짚어낼 때 도움을 많이 받았어요.

오늘은 제가 실제로 쓰고 있는 방식 그대로 이야기해볼게요. 그냥 “Claude에게 계약서 넣고 물어보세요” 같은 뻔한 이야기는 아닙니다. 제가 만든 폴더 구조, API 호출 코드, 프롬프트, 실제로 잡아낸 독소조항 예시, 그리고 쓰면서 조심해야 할 부분까지 편하게 풀어보겠습니다.

계약서 파일을 그냥 던지지 않고, 작은 프로젝트처럼 관리하는 이유

처음에는 저도 Claude 웹 화면에 계약서 내용을 복사해서 붙여넣었어요. 빠르고 편하니까요. 그런데 몇 번 하다 보니 문제가 생기더라고요. 어떤 계약서는 외주 개발 계약이고, 어떤 건 API 제휴 계약이고, 또 어떤 건 유지보수 계약인데 매번 같은 방식으로 물어보면 답변 품질이 들쭉날쭉했습니다.

그래서 아예 작은 프로젝트 폴더를 만들어두고, 계약서 유형별로 프롬프트를 관리하기 시작했어요. 개발자답게 말하자면, 계약서 검토도 재현 가능하게 만든 거죠. 나중에 비슷한 계약서가 들어와도 같은 기준으로 다시 돌려볼 수 있고, 이전 결과와 비교하기도 좋습니다.

contract-reviewer/
├── config/
│   └── settings.py          # API 키와 Claude 모델 설정
├── prompts/
│   ├── system_prompt.txt    # IT 계약 검토용 역할 설정
│   └── review_template.txt  # 계약서 분석 질문 템플릿
├── contracts/
│   ├── 2024_freelance_agreement_draft.txt  # 검토할 외주 계약서
│   └── reference_standard_contract.txt      # 비교용 표준 계약서
├── outputs/
│   └── review_report.html   # 분석 결과 리포트
├── main.py                  # Claude API 호출 스크립트
└── requirements.txt

여기서 제가 제일 중요하게 보는 파일은 prompts/system_prompt.txtreference_standard_contract.txt입니다. 그냥 “이 계약서 문제 있는지 봐줘”라고 물으면 Claude도 꽤 일반적인 이야기를 합니다. “상호 협의가 필요합니다”, “법률 전문가와 상담하세요” 같은 답이 주로 나오죠. 틀린 말은 아닌데, 우리가 원하는 건 그런 말이 아니잖아요.

저는 가능하면 과학기술정보통신부나 공공기관에서 제공하는 표준계약서, 또는 예전에 변호사 검토를 거쳤던 안전한 계약서 샘플을 참고용으로 같이 넣습니다. 그러면 Claude가 “이 조항은 일반적인 표준 계약서보다 을에게 불리하다”는 식으로 훨씬 구체적으로 말해줘요. 이 차이가 꽤 큽니다.

Claude API로 계약서 분석 리포트 뽑는 간단한 코드

웹 화면에서 바로 써도 되지만, 저는 반복해서 검토해야 하는 문서가 많을 때는 API로 돌리는 편입니다. 특히 HTML 리포트로 저장해두면 나중에 다시 열어보기 편해요. 클라이언트와 조율할 때도 “이 부분은 위험도가 높아서 이렇게 바꾸면 어떨까요?” 하고 정리해서 말하기 좋고요.

아래 코드는 제가 쓰는 방식에서 핵심만 덜어낸 예시입니다. 실제로는 API 키를 환경변수로 빼고, 파일명도 날짜별로 저장하게 해두는 편이에요. 그래도 흐름은 거의 같습니다.

import os
import anthropic

def analyze_contract(contract_path, prompt_path, system_prompt_path):
    with open(contract_path, "r", encoding="utf-8") as f:
        contract_content = f.read()

    with open(prompt_path, "r", encoding="utf-8") as f:
        prompt_template = f.read()

    with open(system_prompt_path, "r", encoding="utf-8") as f:
        system_prompt = f.read()

    client = anthropic.Anthropic(
        api_key=os.getenv("ANTHROPIC_API_KEY")
    )

    user_message = prompt_template.format(
        contract=contract_content
    )

    message = client.messages.create(
        model="claude-3-5-sonnet-20240620",
        max_tokens=4000,
        temperature=0.2,
        system=system_prompt,
        messages=[
            {
                "role": "user",
                "content": user_message
            }
        ]
    )

    return message.content[0].text


if __name__ == "__main__":
    result = analyze_contract(
        contract_path="contracts/2024_freelance_agreement_draft.txt",
        prompt_path="prompts/review_template.txt",
        system_prompt_path="prompts/system_prompt.txt"
    )

    with open("outputs/review_report.html", "w", encoding="utf-8") as f:
        f.write(result)

여기서 temperature는 낮게 잡는 걸 추천합니다. 저는 보통 0.2 정도로 둡니다. 계약서 검토는 창의적인 글쓰기가 아니니까요. 답변이 너무 자유분방해지면 오히려 불안합니다. 안정적으로, 같은 기준으로, 차분하게 분석해주는 게 더 좋습니다.

그리고 API 키를 코드에 직접 박아두는 건 피하는 게 좋아요. 예전에 급하게 테스트하다가 키를 그대로 커밋할 뻔한 적이 있었습니다. 그때 식은땀이 좀 났어요. GitHub에 올라가면 정말 귀찮아집니다. 저는 지금은 무조건 환경변수로 관리합니다.

프롬프트는 “변호사처럼 봐줘”보다 훨씬 구체적이어야 합니다

Claude를 잘 쓰려면 결국 프롬프트가 중요합니다. 이건 코딩할 때도 그렇고, 계약서 볼 때도 똑같아요. “전문가처럼 검토해줘”라고 하면 답이 그럴듯하긴 한데, 정작 내 상황에 딱 맞는 이야기가 잘 안 나옵니다. 저는 프롬프트에 제 상황을 꽤 노골적으로 적는 편이에요.

예를 들면 이런 식입니다.

너는 대한민국 IT 스타트업, 프리랜서 개발 계약, 소프트웨어 외주 분쟁을 많이 다뤄본 IT 전문 변호사다.

계약을 검토할 때는 반드시 을, 즉 개발자 입장에서 본다.
특히 아래 항목을 집중적으로 확인한다.

1. 소스코드와 지식재산권 귀속 범위
2. 기존에 보유하고 있던 공통 라이브러리와 템플릿 코드의 소유권 문제
3. 무상 유지보수 기간과 범위
4. 기능 추가를 버그 수정처럼 요구할 가능성
5. 검수 지연으로 잔금 지급이 늦어질 가능성
6. 지체상금이나 손해배상 조항이 과도한지 여부
7. 계약 해지 시 이미 개발한 산출물의 대금 정산 방식

답변은 다음 형식으로 작성한다.

  • 위험 조항 원문
  • 왜 위험한지
  • 실제로 어떤 문제가 생길 수 있는지
  • 개발자에게 유리한 수정 문구
  • 클라이언트에게 부드럽게 전달할 협상 문장

제가 이 프롬프트를 좋아하는 이유는 단순합니다. Claude가 법률적인 위험만 말하는 게 아니라, 실제 협상에서 어떻게 말하면 덜 싸우고 넘어갈 수 있는지까지 도와주거든요. 사실 외주 계약은 법적으로 이기는 것도 중요하지만, 관계를 너무 망치지 않는 것도 중요합니다. 돈 받고 일해야 하니까요. 기분 나쁘게 들이받으면 계약 자체가 깨질 수도 있고요.

제가 꼭 넣는 검토 항목들

    • 지식재산권 귀속 범위: 프로젝트를 위해 새로 만든 코드만 넘기는 건지, 내가 예전부터 쓰던 보일러플레이트나 공통 유틸리티까지 넘어가는지 꼭 봅니다.
    • 유지보수 범위: “무상 하자보수”라는 말이 있으면 기간, 범위, 예외 조건을 봐야 합니다. 이게 흐리면 기능 추가까지 무료로 해달라는 이야기가 나옵니다.
    • 검수 조건: “갑의 검수 완료 후 잔금 지급”만 있으면 위험합니다. 검수 기한이 없으면 잔금이 질질 밀릴 수 있어요.
    • 지체상금: 일정이 늦어졌을 때 배상금이 너무 과한지 봅니다. 개발 지연 원인이 클라이언트의 자료 미제공이나 의사결정 지연일 수도 있거든요.
    • 계약 해지: 중간에 계약이 깨졌을 때 이미 만든 작업물에 대한 비용을 어떻게 정산하는지 확인합니다. 이거 없으면 정말 피곤해집니다.

실제로 Claude가 잡아낸 독소조항 예시

얼마 전에 받은 외주 계약서에 꽤 익숙한 문장이 있었어요. “을은 인도일로부터 1년간 무상으로 하자보수를 제공한다.” 처음 보면 그럴 수도 있겠다 싶습니다. 그런데 개발 외주를 해본 분들은 아실 거예요. 하자보수라는 말이 얼마나 넓게 해석될 수 있는지요.

클라이언트 입장에서는 “버튼 하나만 추가하면 되는 거 아니에요?”라고 말할 수 있습니다. 그런데 그 버튼 하나 때문에 권한 체크, 데이터베이스 컬럼, 관리자 화면, 테스트 케이스까지 다 바뀌는 경우가 많잖아요. 겉으로는 작은 수정인데 속은 신규 개발인 경우가 정말 많습니다.

계약서 초안 문구 Claude가 짚어낸 위험 수정 제안 문구
을은 본 계약에 따라 인도한 결과물에 대해 인도일로부터 1년간 무상으로 하자보수를 제공한다. 하자보수의 의미가 모호합니다. 단순 버그 수정뿐 아니라 기획 변경, 화면 추가, 기능 개선까지 무상 요청으로 이어질 가능성이 있습니다. 1년이라는 기간도 프리랜서 개발자에게는 부담이 큽니다. 을은 인도일로부터 3개월간 무상 하자보수를 제공한다. 단, 무상 하자보수는 합의된 요구사항 정의서와 설계 명세서에 비추어 발생한 오동작에 한정하며, 신규 기능 추가 또는 기획 변경은 별도 견적과 계약에 따른다.
본 계약과 관련하여 을이 제작한 모든 소스코드 및 지식재산권은 인도와 동시에 갑에게 귀속된다. “모든 소스코드”라는 표현이 너무 넓습니다. 개발자가 기존에 보유하고 있던 공통 모듈, 템플릿, 내부 라이브러리까지 갑에게 귀속된다고 해석될 여지가 있습니다. 본 프로젝트를 위해 신규로 개발된 산출물의 사용권 및 필요한 범위의 권리는 갑에게 이전한다. 단, 을이 계약 전부터 보유하고 있던 라이브러리, 프레임워크, 템플릿, 공통 유틸리티의 소유권은 을에게 남으며, 갑은 본 프로젝트 운영 목적에 한해 비독점적으로 사용할 수 있다.
잔금은 갑의 최종 검수 완료 후 지급한다. 검수 기한이 없습니다. 갑이 검수를 미루면 잔금 지급도 무기한 밀릴 수 있습니다. 개발자는 결과물을 납품하고도 돈을 기다리는 상황이 생깁니다. 갑은 을의 최종 산출물 인도일로부터 7영업일 이내에 검수 결과를 통지한다. 해당 기간 내 서면 이의 제기가 없을 경우 검수는 완료된 것으로 본다.

이런 식으로 나오면 마음이 훨씬 정리됩니다. 그냥 “찜찜한데?”에서 끝나는 게 아니라, 왜 찜찜한지 말로 설명할 수 있게 되거든요. 협상할 때도 감정이 아니라 문장으로 이야기할 수 있습니다. 이게 생각보다 큰 차이를 만듭니다.

바이브 코딩처럼 쓰면 편하지만, 법률 문서는 조금 더 조심해야 합니다

요즘 개발할 때 바이브 코딩 많이 하잖아요. 저도 합니다. 빠르게 만들고, AI에게 구조 잡아달라고 하고, 테스트 코드도 초안 뽑고요. 솔직히 생산성이 올라가는 건 맞습니다. 그런데 계약서 검토만큼은 너무 분위기에 맡기면 안 됩니다.

Claude가 말투도 차분하고, 답변도 그럴듯해서 가끔 “아, 이 정도면 됐네” 싶은 순간이 있어요. 그런데 바로 그때가 위험합니다. AI는 법률 전문가가 아니고, 최신 판례나 실제 법률 해석을 완벽하게 보장하지 않습니다. 특히 한국 법령의 세부 조문이나 업계 관행은 틀릴 수 있어요.

그럴듯하게 틀리는 답변을 조심해야 합니다

Claude가 가끔 존재하지 않는 법 조항이나 애매한 판례를 실제처럼 말할 때가 있습니다. 영어로는 Hallucination이라고 하죠. 계약서 검토에서는 이게 꽤 치명적일 수 있어요. “민법상 당연히 무효입니다” 같은 말을 했는데 실제로는 그렇게 단순하지 않은 경우도 있습니다.

저는 그래서 Claude에게 이렇게 다시 묻습니다.

방금 답변에서 언급한 법률적 근거가 실제 조문에 기반한 것인지 확인해줘.
가능하면 조문 번호를 제시하고, 조문이 불확실한 경우에는 불확실하다고 표시해줘.
판례나 법령을 단정하지 말고, 계약 협상 관점에서 안전한 표현으로 다시 정리해줘.

그리고 정말 중요한 계약이면 국가법령정보센터에서 한 번은 직접 확인합니다. 시간이 오래 걸리는 것도 아니에요. 조문 번호 하나 검색해보는 데 몇 분이면 됩니다. 이 정도 확인은 해야 마음이 편합니다.

계약서 원문을 그대로 올리는 것도 조심해야 합니다

계약서에는 생각보다 민감한 정보가 많이 들어 있습니다. 회사명, 담당자 이름, 이메일, 전화번호, 사업자등록번호, 금액, 지급 일정, 심지어 서버 접속 정보가 별첨에 들어가 있는 경우도 봤어요. 이걸 아무 생각 없이 외부 LLM에 올리는 건 좋은 습관이 아닙니다.

저는 Claude에 넣기 전에 최소한 아래 정도는 바꿉니다.

    • 회사명은 갑 A사, 제 이름은 을 B개발자처럼 바꿉니다.
    • 실제 금액은 총 계약금 1,000만 원처럼 범주화해서 넣습니다.
    • 이메일, 전화번호, 주소, 사업자등록번호는 지웁니다.
    • 서버 주소, API 키, 내부 시스템명은 반드시 삭제합니다.
    • 소스코드가 포함된 별첨은 전체를 넣지 않고, 권리 귀속과 관련된 문장만 추려 넣습니다.

이렇게 해도 분석 품질은 크게 떨어지지 않습니다. Claude가 봐야 하는 건 개인 정보가 아니라 조항의 구조와 문장의 위험성이니까요. 보안은 조금 귀찮아도 습관으로 만들어두는 게 좋습니다.

클라이언트에게 수정 요청할 때는 말투가 은근히 중요합니다

계약서에서 위험한 조항을 찾았다고 해서 바로 “이 조항은 독소조항입니다. 삭제해주세요.”라고 보내면 분위기가 꽤 딱딱해집니다. 상대방도 자기 회사 표준 계약서라고 생각하고 보냈을 가능성이 높거든요. 괜히 방어적으로 나올 수 있습니다.

그래서 저는 Claude에게 분석만 시키지 않고, 상대방에게 보낼 문장도 같이 만들어달라고 합니다. 이게 은근히 도움이 많이 돼요.

아래 수정 요청을 클라이언트에게 보낼 이메일 문장으로 바꿔줘.
공격적으로 들리지 않게 해줘.
계약을 거절하는 느낌이 아니라, 프로젝트 범위를 명확히 해서 양쪽 모두 오해를 줄이자는 톤으로 작성해줘.

그러면 보통 이런 느낌의 문장이 나옵니다.

안녕하세요.
계약서 검토 중 몇 가지 범위를 조금 더 명확히 하면 좋을 것 같아 의견드립니다.

특히 무상 하자보수 조항의 경우, 추후 버그 수정과 기능 추가의 범위가 서로 다르게 해석될 수 있을 것 같아
요구사항 정의서 기준의 오동작 수정으로 범위를 정리하면 양쪽 모두 일정과 비용을 더 안정적으로 관리할 수 있을 것 같습니다.

아래와 같이 문구를 조정해보면 어떨까요?

이 정도 톤이면 상대방도 크게 기분 나빠하지 않습니다. 사실 계약서는 싸우려고 쓰는 문서가 아니라, 나중에 싸우지 않으려고 쓰는 문서잖아요. 저는 이 관점을 되게 중요하게 봅니다.

계약서 사인하기 전에 제가 꼭 보는 체크리스트

Claude로 한 번 돌렸다고 끝은 아닙니다. 저는 최종 사인 전에 커피 한 잔 들고 아래 항목을 다시 봅니다. 개발 배포 전에 체크리스트 보는 것과 비슷해요. 사람은 늘 놓치니까요.

    • 요구사항 정의서가 별첨으로 들어가 있는가?
      이게 없으면 결과물 범위가 끝없이 늘어날 수 있습니다.
    • 검수 기한이 명시되어 있는가?
      “검수 완료 후 지급”만 있으면 잔금이 늦어질 수 있습니다. 저는 보통 인도 후 7영업일 이내를 선호합니다.
    • 무상 유지보수 기간과 범위가 분명한가?
      버그 수정인지, 기능 추가인지, 운영 지원인지 구분되어 있어야 합니다.
    • 기존에 보유한 코드와 라이브러리의 권리가 보호되는가?
      이 부분은 개발자에게 정말 중요합니다. 한 번 잘못 넘기면 다음 프로젝트에도 영향을 줍니다.
    • 클라이언트의 자료 제공 지연이 일정에 반영되는가?
      자료를 늦게 줬는데 납기 지연 책임은 개발자가 지는 구조면 억울합니다.
    • 분쟁 관할 법원이 너무 멀지 않은가?
      사소해 보이지만 막상 분쟁이 생기면 이동 거리도 스트레스입니다.
    • 수정 요청 메일의 톤이 너무 날카롭지 않은가?
      좋은 계약은 문장뿐 아니라 관계에서도 만들어집니다.

제가 느낀 가장 현실적인 사용 방식

Claude는 계약서를 대신 책임져주는 도구가 아닙니다. 이건 분명합니다. 그런데 개발자 입장에서 계약서를 읽는 부담을 줄여주는 도구로는 꽤 훌륭합니다. 특히 혼자 일하는 프리랜서나 작은 팀에서는 계약서 검토에 쓸 시간이 늘 부족하잖아요. 그럴 때 Claude가 먼저 위험 조항을 표시해주면, 어디를 집중해서 봐야 할지 감이 잡힙니다.

저는 이제 계약서를 받으면 바로 사인하지 않습니다. 일단 텍스트로 정리하고, 민감정보를 지우고, Claude에게 한 번 돌립니다. 위험도가 높은 조항을 뽑아보고, 수정 문구를 만들고, 정말 중요한 부분은 법령이나 전문가에게 다시 확인합니다. 이 흐름만 만들어도 마음이 꽤 안정돼요.

개발자에게 계약서는 조금 낯선 영역입니다. 그래도 피하면 안 되는 영역이기도 해요. 좋은 코드를 짜는 것도 중요하지만, 내가 만든 코드와 내 시간을 지키는 것도 그만큼 중요합니다. 나이가 들수록 이런 생각이 더 강해지더라고요. 예전에는 그냥 열심히 만들면 된다고 생각했는데, 이제는 열심히 만든 걸 제대로 보호하는 것도 실력이라고 봅니다.

이 글은 외주 계약서를 자주 받는 프리랜서 개발자, 사이드 프로젝트로 돈을 벌기 시작한 1인 개발자, 그리고 아직 법무팀이 없는 초기 스타트업 파운더에게 특히 도움이 될 것 같습니다. 변호사 검토가 필요한 큰 계약이라면 꼭 전문가에게 맡기세요. 다만 그 전에 Claude로 한 번 걸러보면, 상담할 때 질문도 훨씬 또렷해지고 불안도 많이 줄어듭니다.

다들 억울하게 손해 보지 않았으면 좋겠어요. 좋은 클라이언트 만나서, 좋은 조건으로, 제값 받고 일하는 개발자가 많아졌으면 합니다. 계약서에 도장 찍기 전에 딱 한 번만 더 천천히 보세요. 가능하면 Claude도 옆에 앉혀두고요.


👨‍💻

작성자: 20년 경력 IT 전문 아키텍트

실무 개발과 아키텍처 설계를 거쳐 현재는 AI 바이브 코딩과 개발 자동화를 연구하고 있습니다. 직접 삽질하며 깨달은 실전 꿀팁과 에러 극복 사례만 투명하게 공유합니다.

댓글