<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>연습장</title>
    <link>https://mrgoga.tistory.com/</link>
    <description>https://github.com/PracLee</description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 07:09:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>고가씨</managingEditor>
    <image>
      <title>연습장</title>
      <url>https://tistory1.daumcdn.net/tistory/4809714/attach/8b045bffbc4a41a58bfdb9c379aabbca</url>
      <link>https://mrgoga.tistory.com</link>
    </image>
    <item>
      <title>프로젝트 중간 회고 - 머리카락 제거 문제</title>
      <link>https://mrgoga.tistory.com/100</link>
      <description>&lt;h1&gt;Hair Removal로 접근했지만, 실제 문제는 Upper-Clothes Overwrite였다&lt;/h1&gt;
&lt;h2&gt;ControlNet 기반 이미지 생성 파이프라인에서 마스크 정의를 재설계한 기술 회고&lt;/h2&gt;
&lt;h2&gt;1. 문제 정의: Hair Removal 문제가 아니라 Garment Overwrite 문제였다&lt;/h2&gt;
&lt;p&gt;이번 작업의 시작점은 비교적 단순했다.&lt;br&gt;긴 머리카락이 상의 전면 일부를 가리고 있었고, 이를 자연스럽게 보정하는 것이 목표였다.&lt;br&gt;처음에는 이 문제를 &lt;strong&gt;hair removal&lt;/strong&gt;로 해석했다. 즉, 머리카락 영역을 추출한 뒤 해당 영역을 inpainting으로 제거하거나 복원하면 해결될 것이라고 판단했다.&lt;/p&gt;
&lt;p&gt;하지만 실제 디버깅 과정에서 확인한 것은, 이 문제를 hair removal로 정의하는 순간 파이프라인 전체가 잘못된 방향으로 흘러간다는 점이었다.&lt;/p&gt;
&lt;p&gt;이번 작업의 실제 목적은 다음에 더 가까웠다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;머리카락 자체를 정교하게 지우는 것&lt;/li&gt;
&lt;li&gt;머리카락 뒤에 있던 원래 옷을 그대로 복원하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 둘보다는,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;머리카락이 가린 상의 전면을 다시 생성해서&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;최종 결과에서 상의가 머리카락보다 앞에 있는 것처럼 보이게 만드는 것&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉, 이번 문제는 제거 중심의 task가 아니라&lt;br&gt;&lt;strong&gt;upper-clothes overwrite / garment front regeneration&lt;/strong&gt;에 가깝다.&lt;/p&gt;
&lt;p&gt;이 차이를 정확히 구분하지 못하면 segmentation, mask generation, conditioning, compositing이 모두 어긋나게 된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. 기존 파이프라인 구조: Hair-Centered Editing 관점의 흐름&lt;/h2&gt;
&lt;p&gt;당시 파이프라인은 전반적으로 hair-centered editing 구조에 가까웠다.&lt;br&gt;핵심 흐름은 대략 다음과 같았다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hair mask 생성&lt;/li&gt;
&lt;li&gt;필요 시 SAM2 기반 refinement&lt;/li&gt;
&lt;li&gt;face protect&lt;/li&gt;
&lt;li&gt;Stable Diffusion inpainting&lt;/li&gt;
&lt;li&gt;ControlNet conditioning&lt;/li&gt;
&lt;li&gt;후처리 및 합성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 구조는 “헤어 영역을 편집하거나 생성하는 작업”에는 잘 어울린다.&lt;br&gt;실제로 hair segmentation, hair boundary refinement, face identity preservation 같은 작업에서는 꽤 자연스러운 구조다.&lt;/p&gt;
&lt;p&gt;문제는 내가 해결하려는 대상이 더 이상 hair 자체가 아니었다는 점이다.&lt;br&gt;최종적으로 만들고 싶은 이미지는 &lt;strong&gt;머리카락이 없어진 상태의 상의 전면&lt;/strong&gt;이었고,&lt;br&gt;이를 위해서는 hair 영역 자체보다 &lt;strong&gt;상의 전면의 재생성 대상 정의&lt;/strong&gt;가 더 중요했다.&lt;/p&gt;
&lt;p&gt;즉, 기존 파이프라인은 구조적으로 다음 질문에 최적화돼 있었다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;“머리카락을 어디까지 수정할 것인가?”&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;하지만 실제로 내가 던져야 했던 질문은 이쪽이었다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;“어떤 상의 영역을 새로 그려야 머리카락이 없어진 것처럼 보일까?”&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;겉보기에는 유사하지만, 생성 파이프라인에서는 완전히 다른 질문이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. 초기 가정: Hair Mask만 정교하면 해결될 것이라는 착각&lt;/h2&gt;
&lt;p&gt;초기에는 비교적 직관적으로 생각했다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;머리카락 영역을 segmentation으로 정확하게 추출한다.&lt;/li&gt;
&lt;li&gt;해당 영역을 refinement한다.&lt;/li&gt;
&lt;li&gt;그 결과를 inpainting에 넣는다.&lt;/li&gt;
&lt;li&gt;ControlNet으로 구조를 보정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 접근은 표면적으로는 맞아 보인다.&lt;br&gt;실제로 이미지 위에 시각적으로 겹쳐져 있는 장애물이 머리카락이기 때문에,&lt;br&gt;그 영역만 정교하게 처리하면 문제가 해결될 것처럼 보이기 때문이다.&lt;/p&gt;
&lt;p&gt;하지만 이 접근에는 근본적인 한계가 있었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;머리카락을 제거하는 것과&lt;/li&gt;
&lt;li&gt;머리카락이 없어진 것처럼 보이는 상의를 만드는 것은&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;동일한 작업이 아니다.&lt;/p&gt;
&lt;p&gt;특히 긴 머리카락이 어깨선, 목선, 가슴 전면 일부를 넓게 가리고 있는 경우에는&lt;br&gt;단순한 hair removal이 아니라 &lt;strong&gt;가려진 의상 전면의 재구성&lt;/strong&gt;이 핵심이 된다.&lt;/p&gt;
&lt;p&gt;즉, “무엇을 삭제할 것인가” 중심의 마스킹은&lt;br&gt;“무엇을 다시 그릴 것인가” 중심의 생성 문제를 충분히 설명하지 못한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. 핵심 오류 1: Visible Clothing Mask를 그대로 생성 마스크로 사용한 점&lt;/h2&gt;
&lt;p&gt;트러블슈팅 과정에서 가장 먼저 드러난 핵심 문제는&lt;br&gt;&lt;strong&gt;현재 사용 중인 생성 마스크가 visible clothing mask에 가까웠다&lt;/strong&gt;는 점이다.&lt;/p&gt;
&lt;p&gt;실제로 확인한 마스크는 다음과 같은 특징을 보였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;상의 마스크가 머리카락 실루엣을 따라 움푹 파여 있음&lt;/li&gt;
&lt;li&gt;머리카락이 걸친 부분은 옷 영역에서 제외됨&lt;/li&gt;
&lt;li&gt;즉, “현재 화면에서 보이는 옷”만을 기준으로 정의됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 마스크는 segmentation 관점에서는 합리적이다.&lt;br&gt;왜냐하면 segmentation 모델은 일반적으로 &lt;strong&gt;보이는 영역&lt;/strong&gt;을 기준으로 클래스를 분리하기 때문이다.&lt;/p&gt;
&lt;p&gt;하지만 생성 관점에서는 이 마스크가 오히려 문제를 만든다.&lt;br&gt;이 마스크를 생성에 그대로 쓰면 모델은 다음처럼 해석하게 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;머리카락이 지나간 자리 자체는 구조적으로 유지해야 하는 영역&lt;/li&gt;
&lt;li&gt;옷은 그 경계를 피해 이어져야 하는 영역&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그 결과 상의 전면이 하나의 연속된 면으로 재생성되지 못하고,&lt;br&gt;머리카락 실루엣을 기준으로 움푹 파인 구조가 계속 유지된다.&lt;/p&gt;
&lt;p&gt;즉, visible mask는 “무엇이 지금 보이는가”를 알려줄 수는 있지만,&lt;br&gt;“무엇을 다시 그려야 하는가”를 정의해주지는 못한다.&lt;/p&gt;
&lt;p&gt;이번 작업에서 진짜 필요했던 것은&lt;br&gt;&lt;strong&gt;hair occlusion을 무시한 amodal upper-clothes front mask&lt;/strong&gt;였다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. 핵심 오류 2: Hair-Centered Mask Logic이 생성 목표를 제한한 점&lt;/h2&gt;
&lt;p&gt;기존 파이프라인의 핵심 로직은 hair-centered였다.&lt;br&gt;즉, 문제를 해석하는 기준점 자체가 hair mask에 맞춰져 있었다.&lt;/p&gt;
&lt;p&gt;이 구조에서는 자연스럽게 다음과 같은 흐름이 만들어진다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hair mask를 얼마나 정확히 뽑을 것인가&lt;/li&gt;
&lt;li&gt;hair boundary를 얼마나 정교하게 다듬을 것인가&lt;/li&gt;
&lt;li&gt;hair overlap을 얼마나 잘 분리할 것인가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;하지만 이번 작업에서 중요한 것은 hair 자체의 정밀한 추출이 아니었다.&lt;br&gt;오히려 필요한 것은 &lt;strong&gt;머리카락과 겹친 상체 영역을 상의 쪽 regenerate 대상으로 귀속시키는 것&lt;/strong&gt;이었다.&lt;/p&gt;
&lt;p&gt;즉, 중심 질문이 바뀌어야 했다.&lt;/p&gt;
&lt;h3&gt;기존 질문&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;hair를 어디까지 분리할 것인가&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;필요한 질문&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;상의 전면을 어디까지 다시 그릴 것인가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 차이가 중요했던 이유는, 생성 모델은 결국 마스크가 정의한 영역을 기준으로 이미지를 다시 만들기 때문이다.&lt;br&gt;중심이 hair면 hair edit으로 흐르고, 중심이 clothes면 clothes overwrite로 흐른다.&lt;/p&gt;
&lt;p&gt;이번 사례는 &lt;strong&gt;마스크 설계의 중심 객체가 바뀌면 태스크 해석 자체가 달라진다&lt;/strong&gt;는 점을 보여줬다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;6. 핵심 오류 3: ControlNet Conditioning이 원본 Hair Edge를 다시 살릴 가능성&lt;/h2&gt;
&lt;p&gt;초기에는 ControlNet을 사용하고 있었기 때문에, 구조 보정은 어느 정도 해결될 수 있을 것이라고 기대했다.&lt;br&gt;실제로 ControlNet은 pose, edge, depth 같은 구조 조건을 강하게 반영하는 데 유리하다.&lt;/p&gt;
&lt;p&gt;문제는 &lt;strong&gt;무슨 구조를 조건으로 넣고 있느냐&lt;/strong&gt;였다.&lt;/p&gt;
&lt;p&gt;edge 기반 conditioning을 사용할 경우, 원본 이미지에서 추출한 edge map에는 머리카락 실루엣도 함께 포함된다.&lt;br&gt;이 경우 내가 제거하고 싶었던 hair edge가 오히려 다시 생성 단계의 구조 조건으로 입력될 수 있다.&lt;/p&gt;
&lt;p&gt;즉, ControlNet은 구조를 보정해 주는 도구지만,&lt;br&gt;그 구조가 잘못 정의되어 있으면 오히려 문제를 강화한다.&lt;/p&gt;
&lt;p&gt;이번 사례에서 필요한 conditioning은 다음 성격에 가까워야 했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원본 hair edge를 그대로 보존하는 conditioning&lt;/li&gt;
&lt;li&gt;머리카락 경계를 유지하는 conditioning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 아니라,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;upper body silhouette 중심 conditioning&lt;/li&gt;
&lt;li&gt;clothes overwrite를 방해하지 않는 masked edge&lt;/li&gt;
&lt;li&gt;hair silhouette를 덜 강조하는 구조 조건&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;즉, ControlNet의 유무보다 중요한 것은&lt;br&gt;&lt;strong&gt;ControlNet이 어떤 구조를 “보존해야 할 것”으로 인식하고 있느냐&lt;/strong&gt;였다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;7. 핵심 오류 4: Post-Process를 메인 해결책처럼 바라본 점&lt;/h2&gt;
&lt;p&gt;후처리 단계는 흔히 마지막 품질 보정 장치처럼 느껴진다.&lt;br&gt;artifact cleanup, 경계 보정, 일부 잔상 제거 등에서 실제로 유효하기도 하다.&lt;/p&gt;
&lt;p&gt;하지만 이번 작업에서는 후처리를 메인 해결책처럼 바라보면 안 됐다.&lt;br&gt;왜냐하면 현재 문제는 단순 artifact 문제가 아니라 &lt;strong&gt;재생성 대상 정의 자체가 잘못된 상태&lt;/strong&gt;였기 때문이다.&lt;/p&gt;
&lt;p&gt;즉, 메인 generation이 다음처럼 잘못 되어 있으면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;regenerate mask가 hair silhouette를 따라 파여 있고&lt;/li&gt;
&lt;li&gt;conditioning이 hair edge를 보존하고 있고&lt;/li&gt;
&lt;li&gt;composite 목적이 hair editing 관점에 묶여 있으면&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;후처리로 해결 가능한 범위를 이미 넘어선다.&lt;/p&gt;
&lt;p&gt;후처리는 어디까지나 &lt;strong&gt;올바른 생성 결과를 조금 더 정리하는 단계&lt;/strong&gt;이지,&lt;br&gt;생성 방향이 틀어진 파이프라인을 역전시키는 단계는 아니다.&lt;/p&gt;
&lt;p&gt;이번 사례는 “후처리에서 어떻게든 잡겠지”라는 사고가 얼마나 위험한지도 보여줬다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;8. 해결 방향: Hair Removal에서 Upper-Clothes Overwrite로 파이프라인 재해석&lt;/h2&gt;
&lt;p&gt;문제를 다시 정의한 뒤, 해결 방향도 자연스럽게 달라졌다.&lt;br&gt;핵심은 파이프라인 전체를 hair removal 관점이 아니라 &lt;strong&gt;upper-clothes overwrite 관점&lt;/strong&gt;으로 다시 해석하는 것이다.&lt;/p&gt;
&lt;p&gt;구체적으로는 다음이 필요하다.&lt;/p&gt;
&lt;h3&gt;8.1 Regenerate Mask 재설계&lt;/h3&gt;
&lt;p&gt;최종 regenerate mask는 좁은 hair overlap 영역이 아니라,&lt;br&gt;&lt;strong&gt;상의 전면 전체 + 머리카락과 겹치는 상체 영역&lt;/strong&gt;이 되어야 한다.&lt;/p&gt;
&lt;p&gt;즉 마스크는 다음 조건을 만족해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;양 어깨와 가슴 중앙부가 끊기지 않을 것&lt;/li&gt;
&lt;li&gt;hair silhouette를 따라 움푹 파이지 않을 것&lt;/li&gt;
&lt;li&gt;목 아래 상의 전면이 하나의 연속된 면으로 정의될 것&lt;/li&gt;
&lt;li&gt;hair overlap도 regenerate 대상에 포함될 것&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;8.2 Preserve 대상 축소&lt;/h3&gt;
&lt;p&gt;이번 작업에서 preserve의 핵심은 hair가 아니라 face다.&lt;br&gt;즉 face identity는 유지하되, hair 자체는 반드시 원형 유지할 필요가 없다.&lt;/p&gt;
&lt;p&gt;이렇게 해야 generated clothes가 결과 이미지에서 더 앞 레이어처럼 보일 수 있다.&lt;/p&gt;
&lt;h3&gt;8.3 Conditioning 재설계&lt;/h3&gt;
&lt;p&gt;edge 기반 conditioning을 계속 쓴다면,&lt;br&gt;그 edge가 hair silhouette를 다시 강하게 보존하지 않도록 조정해야 한다.&lt;/p&gt;
&lt;p&gt;즉 conditioning의 기준도&lt;br&gt;“원본 hair 구조 유지”가 아니라&lt;br&gt;“upper body structure 유지”로 바뀌어야 한다.&lt;/p&gt;
&lt;h3&gt;8.4 Composite 목적 변경&lt;/h3&gt;
&lt;p&gt;최종 합성도 “generated hair를 올리는 것”이 아니라&lt;br&gt;&lt;strong&gt;generated upper clothes를 front layer처럼 덮어쓰기&lt;/strong&gt; 방향으로 바뀌어야 한다.&lt;/p&gt;
&lt;p&gt;이 관점 전환이 이뤄져야 파이프라인 전체가 같은 목표를 향하게 된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;9. 이번 트러블슈팅에서 얻은 기술적 교훈&lt;/h2&gt;
&lt;p&gt;이번 작업에서 얻은 교훈은 비교적 명확하다.&lt;/p&gt;
&lt;h3&gt;9.1 생성 태스크에서는 Segmentation Mask와 Generation Mask를 분리해서 생각해야 한다&lt;/h3&gt;
&lt;p&gt;segmentation은 보이는 영역을 분리하는 데 적합하다.&lt;br&gt;하지만 generation은 종종 &lt;strong&gt;보이지 않지만 다시 그려져야 하는 영역&lt;/strong&gt;을 정의해야 한다.&lt;/p&gt;
&lt;p&gt;즉 segmentation 결과를 그대로 generation mask로 가져오는 것은 위험할 수 있다.&lt;/p&gt;
&lt;h3&gt;9.2 문제 정의가 틀리면 모델 선택과 파라미터 튜닝은 한계가 있다&lt;/h3&gt;
&lt;p&gt;ControlNet, inpainting, face protect, 후처리 등은 모두 강력한 도구다.&lt;br&gt;하지만 regenerate 대상이 잘못 설정되어 있으면, 그 위의 튜닝은 구조적 한계를 벗어나기 어렵다.&lt;/p&gt;
&lt;h3&gt;9.3 “무엇을 제거할 것인가”보다 “무엇을 새로 그릴 것인가”가 더 중요할 수 있다&lt;/h3&gt;
&lt;p&gt;이번 이슈의 핵심 전환점은 바로 이 질문이었다.&lt;br&gt;머리카락을 어떻게 지울지가 아니라,&lt;br&gt;결국 &lt;strong&gt;어떤 상의 레이어를 다시 만들 것인지&lt;/strong&gt;를 먼저 정의해야 했다.&lt;/p&gt;
&lt;h3&gt;9.4 Post-Process는 방향 수정이 아니라 미세 보정이다&lt;/h3&gt;
&lt;p&gt;메인 generation이 맞아야 후처리가 의미를 가진다.&lt;br&gt;후처리는 잘못된 regenerate target을 바로잡는 수단이 아니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;10. 결론&lt;/h2&gt;
&lt;p&gt;이번 작업은 겉보기에는 단순한 hair occlusion 보정처럼 보였지만,&lt;br&gt;실제로는 &lt;strong&gt;문제 정의와 마스크 설계가 얼마나 파이프라인 전체를 좌우하는지&lt;/strong&gt;를 보여준 사례였다.&lt;/p&gt;
&lt;p&gt;처음에는 hair removal 문제라고 생각했다.&lt;br&gt;하지만 디버깅을 거치면서 실제 문제는 &lt;strong&gt;upper-clothes overwrite&lt;/strong&gt;, 즉 상의 전면 재생성에 더 가까웠다는 점이 분명해졌다.&lt;/p&gt;
&lt;p&gt;이 차이를 인식한 뒤에는 자연스럽게 다음이 보였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;왜 기존 마스크가 문제였는지&lt;/li&gt;
&lt;li&gt;왜 ControlNet이 해결해주지 못했는지&lt;/li&gt;
&lt;li&gt;왜 후처리에 기대면 안 되는지&lt;/li&gt;
&lt;li&gt;왜 segmentation 결과를 그대로 generation에 쓰면 안 되는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;앞으로 유사한 이슈를 다룰 때는,&lt;br&gt;먼저 눈에 띄는 가림 객체를 제거하는 관점보다&lt;br&gt;&lt;strong&gt;최종 이미지에서 어떤 레이어를 다시 생성해야 하는가&lt;/strong&gt;를 기준으로 문제를 정의해야 한다.&lt;/p&gt;
&lt;p&gt;이번 트러블슈팅은 그 기준을 다시 세우게 만든 사례였다.&lt;/p&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/100</guid>
      <comments>https://mrgoga.tistory.com/100#entry100comment</comments>
      <pubDate>Sun, 5 Apr 2026 16:51:47 +0900</pubDate>
    </item>
    <item>
      <title>개인프로젝트 - 한국 취업시장 특화 MCP 서버</title>
      <link>https://mrgoga.tistory.com/99</link>
      <description>&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href=&quot;https://github.com/PracLee/job_hunting_mcp&quot;&gt;https://github.com/PracLee/job_hunting_mcp&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;1. 왜 이걸 만들게 되었는가&lt;/h2&gt;
&lt;h3&gt;문제의 시작: &amp;quot;같은 서류를 6번 쓰는 고통&amp;quot;&lt;/h3&gt;
&lt;p&gt;취업 준비를 하면서, 채용 사이트에 이력서를 등록하는 과정이 가장 짜증나는 작업이었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;원티드&lt;/strong&gt;는 한 줄 소개 + 성과 중심 bullet + 기술 태그.&lt;br&gt;&lt;strong&gt;사람인&lt;/strong&gt;은 표 기반 이력서 + 4문항 자기소개서.&lt;br&gt;&lt;strong&gt;잡코리아&lt;/strong&gt;는 이력서 + 경력기술서 분리.&lt;br&gt;&lt;strong&gt;점핏&lt;/strong&gt;은 기술 중심 프로필 + 프로젝트 카드.&lt;/p&gt;
&lt;p&gt;같은 경력인데, 사이트마다 양식이 다르다.&lt;br&gt;결국 &lt;strong&gt;같은 내용을 6번&lt;/strong&gt; 복사하고, 붙여넣고, 양식에 맞게 다시 정리하고 있었다.&lt;/p&gt;
&lt;p&gt;그리고 공고마다 강조해야 할 포인트가 다르다.&lt;br&gt;백엔드 공고면 API/DB 경험을 앞에, AI 공고면 RAG/LLM 경험을 앞에.&lt;br&gt;이것까지 매번 수동으로 하고 있었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;이건 자동화할 수 있다&amp;quot;&lt;/strong&gt; 라는 확신이 들었고, 그래서 이 프로젝트를 시작했다.&lt;/p&gt;
&lt;h3&gt;기존 도구들의 한계&lt;/h3&gt;
&lt;p&gt;미국 시장에는 resume optimizer 같은 도구가 많다.&lt;br&gt;하지만 한국 취업 시장에 맞는 도구는 거의 없었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한국식 자기소개서 (지원동기/성장과정/입사후포부) 지원 ❌&lt;/li&gt;
&lt;li&gt;사람인/잡코리아/원티드 등 한국 채용 사이트 양식 지원 ❌&lt;/li&gt;
&lt;li&gt;&amp;quot;경력기술서&amp;quot; 개념 자체가 미국 이력서와 다름&lt;/li&gt;
&lt;li&gt;한국어 기술 동의어 처리 (&amp;quot;자바&amp;quot; = &amp;quot;Java&amp;quot;, &amp;quot;스프링부트&amp;quot; = &amp;quot;Spring Boot&amp;quot;) ❌&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;한국 시장에 특화된 도구가 필요&lt;/strong&gt;했다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. 어떻게 구상했는가&lt;/h2&gt;
&lt;h3&gt;핵심 아이디어: &amp;quot;마스터 프로필 → 공고별/사이트별 변환&amp;quot;&lt;/h3&gt;
&lt;p&gt;전체 구상의 핵심은 단순하다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;이력서/경력기술서를 한 번만 입력
→ 마스터 프로필로 구조화
→ 공고에 맞게 강조 포인트 조정
→ 각 사이트 양식에 맞는 복붙 텍스트 생성&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 흐름을 &lt;strong&gt;MCP(Model Context Protocol) 서버&lt;/strong&gt;로 구현하기로 했다.&lt;br&gt;MCP를 선택한 이유:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Claude Desktop / Claude Code에서 바로 사용 가능&lt;/strong&gt; — 별도 UI 개발 불필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool 기반 아키텍처&lt;/strong&gt; — 기능을 모듈 단위로 쪼개기 좋음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;로컬 실행&lt;/strong&gt; — 이력서 같은 개인정보를 외부 서버에 올리지 않아도 됨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 연동이 자연스러움&lt;/strong&gt; — 서류 작성 보조에 LLM을 바로 활용&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;아키텍처 결정&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;결정&lt;/th&gt;
&lt;th&gt;선택&lt;/th&gt;
&lt;th&gt;이유&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;실행 방식&lt;/td&gt;
&lt;td&gt;로컬 실행&lt;/td&gt;
&lt;td&gt;개인정보 보호 (이력서, 연락처 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM&lt;/td&gt;
&lt;td&gt;각자 API키 또는 Ollama&lt;/td&gt;
&lt;td&gt;비용 분산, 오프라인 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;SQLite (better-sqlite3)&lt;/td&gt;
&lt;td&gt;로컬 파일, 설치 불필요, 충분한 성능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공고 검색&lt;/td&gt;
&lt;td&gt;어댑터 패턴&lt;/td&gt;
&lt;td&gt;사이트별 API가 다르므로 추상화 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;양식 변환&lt;/td&gt;
&lt;td&gt;템플릿 패턴&lt;/td&gt;
&lt;td&gt;LLM 없이도 기본 동작, LLM으로 보강 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;&amp;quot;LLM 없이도 돌아가야 한다&amp;quot;&lt;/h3&gt;
&lt;p&gt;이 프로젝트에서 가장 중요하게 잡은 원칙이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;매칭&lt;/strong&gt;: 규칙 기반 (기술 사전 + 가중치 계산) → LLM 불필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;양식 변환&lt;/strong&gt;: 템플릿 기반 변환 → LLM 불필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프로필 파싱&lt;/strong&gt;: 정규식 + 섹션 분리 → LLM 불필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서류 생성&lt;/strong&gt;: 여기만 LLM 사용 (문장 다듬기, 자소서 초안)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ollama를 쓰면 API 키 없이도 전체 기능을 사용할 수 있다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. 지금까지 구현된 것&lt;/h2&gt;
&lt;h3&gt;Phase 0: 프로젝트 셋업 + 16개 Tool 스켈레톤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MCP 서버 진입점 + StdioTransport 연결&lt;/li&gt;
&lt;li&gt;16개 Tool 전체 등록 (채용공고/프로필/매칭/서류/지원관리/면접)&lt;/li&gt;
&lt;li&gt;SQLite DB + Repository 패턴&lt;/li&gt;
&lt;li&gt;LLM 클라이언트 추상화 (Anthropic / OpenAI / Ollama)&lt;/li&gt;
&lt;li&gt;기술 사전 (80+ 항목, 한국어 동의어 포함)&lt;/li&gt;
&lt;li&gt;Zod 기반 입력 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Phase 1-2: 프로필 파서 고도화 + 원티드 어댑터&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;이력서 파서&lt;/strong&gt; (규칙 기반)&lt;ul&gt;
&lt;li&gt;한국 이력서 섹션 자동 분리 (인적사항/학력/경력/기술/프로젝트/자격증)&lt;/li&gt;
&lt;li&gt;기술스택 자동 추출 (tech-dictionary 연동)&lt;/li&gt;
&lt;li&gt;프로젝트별 성과/역할/기간 파싱&lt;/li&gt;
&lt;li&gt;경력 연차 자동 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원티드 어댑터&lt;/strong&gt; (실시간 API)&lt;ul&gt;
&lt;li&gt;원티드 v4 API 연동&lt;/li&gt;
&lt;li&gt;검색 + 상세 조회&lt;/li&gt;
&lt;li&gt;공고 자동 정규화 + DB 캐싱&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;공고 정규화 엔진&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;주요업무/자격요건/우대사항/기술스택 자동 분류&lt;/li&gt;
&lt;li&gt;경력 범위 파싱 (3~5년, 5년 이상 등)&lt;/li&gt;
&lt;li&gt;직무 카테고리 자동 분류&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Phase 3-4: 플랫폼 양식 템플릿 + resume_export 개선&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;6개 플랫폼 양식 템플릿&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;원티드: 한 줄 소개 + 성과 bullet + 기술 태그&lt;/li&gt;
&lt;li&gt;사람인: 표 기반 이력서 + 인적사항 + 문항별 자소서 구조&lt;/li&gt;
&lt;li&gt;잡코리아: 이력서 + 경력기술서 분리&lt;/li&gt;
&lt;li&gt;점핏: 기술 중심 프로필 + 프로젝트 카드&lt;/li&gt;
&lt;li&gt;로켓펀치: 링크드인 스타일 요약 + 경험 타임라인&lt;/li&gt;
&lt;li&gt;범용: 이메일 지원 / 일반 이력서용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resume_export 개선&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;LLM 없이 템플릿 기반 변환 (기본)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;enhance_with_llm: true&lt;/code&gt; 옵션으로 LLM 문장 보강 (선택)&lt;/li&gt;
&lt;li&gt;공고 지정 시 맞춤 강조 포인트 조정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Phase 5: 채용 사이트 어댑터 추가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;사람인 어댑터&lt;/strong&gt; (Open API 기반)&lt;ul&gt;
&lt;li&gt;공식 API 연동 (SARAMIN_API_KEY 필요)&lt;/li&gt;
&lt;li&gt;직무 코드 / 지역 코드 매핑&lt;/li&gt;
&lt;li&gt;검색 + 상세 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;잡코리아 어댑터&lt;/strong&gt; (웹 파싱)&lt;ul&gt;
&lt;li&gt;HTML 검색 결과 파싱&lt;/li&gt;
&lt;li&gt;상세 페이지 파싱 (주요업무/자격요건/우대사항)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;점핏 어댑터&lt;/strong&gt; (내부 API)&lt;ul&gt;
&lt;li&gt;기술 태그 기반 검색&lt;/li&gt;
&lt;li&gt;API 실패 시 웹 검색 폴백&lt;/li&gt;
&lt;li&gt;상세 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;테스트 현황&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;63개 테스트 전체 통과&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;테스트 분류:&lt;ul&gt;
&lt;li&gt;기술 사전 테스트 (동의어, 추출, 매칭)&lt;/li&gt;
&lt;li&gt;이력서 파서 테스트 (섹션 분리, 필드 추출)&lt;/li&gt;
&lt;li&gt;공고 정규화 테스트&lt;/li&gt;
&lt;li&gt;플랫폼 템플릿 테스트 (6개 플랫폼)&lt;/li&gt;
&lt;li&gt;매칭 스코어링 테스트&lt;/li&gt;
&lt;li&gt;E2E 통합 테스트 (프로필→공고→매칭→양식변환→지원관리)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;4. 현재 구현 상태 종합&lt;/h2&gt;
&lt;h3&gt;어댑터 (공고 검색)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;사이트&lt;/th&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;th&gt;방식&lt;/th&gt;
&lt;th&gt;API 키&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;원티드&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;REST API (v4)&lt;/td&gt;
&lt;td&gt;불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사람인&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Open API&lt;/td&gt;
&lt;td&gt;필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;잡코리아&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;웹 HTML 파싱&lt;/td&gt;
&lt;td&gt;불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;점핏&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;내부 API + 웹 폴백&lt;/td&gt;
&lt;td&gt;불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;로켓펀치&lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt;미구현&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;양식 변환 (이력서 복붙)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;사이트&lt;/th&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;원티드&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;한 줄 소개 + 성과 bullet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사람인&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;표 기반 + 자소서 문항 구조&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;잡코리아&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;이력서 + 경력기술서 분리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;점핏&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;기술 태그 중심 프로필&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;로켓펀치&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;링크드인 스타일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;범용&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;이메일 지원용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Tool 구현 상태&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;구현&lt;/th&gt;
&lt;th&gt;LLM 필요&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs_search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs_get_detail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs_add&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;profile_parse_resume&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 규칙 기반 + LLM 보강&lt;/td&gt;
&lt;td&gt;선택적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;profile_get&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;match_score_job&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 규칙 기반&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;match_rank_jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 규칙 기반&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resume_tailor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ LLM 기반&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resume_export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 템플릿 + LLM 선택적&lt;/td&gt;
&lt;td&gt;선택적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;coverletter_brainstorm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ LLM 기반&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;coverletter_generate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ LLM 기반&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;portfolio_reorder&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ LLM 기반&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application_create&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application_update_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application_list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ 완전 동작&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;interview_prepare&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ LLM 기반&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;16개 Tool 전부 구현 완료. LLM 없이도 10개 Tool이 완전 동작.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. 핵심 기술적 결정과 이유&lt;/h2&gt;
&lt;h3&gt;기술 사전 (tech-dictionary)&lt;/h3&gt;
&lt;p&gt;한국 채용공고에는 같은 기술이 여러 표기로 등장한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;자바&amp;quot;, &amp;quot;Java&amp;quot;, &amp;quot;JAVA&amp;quot; → 모두 같은 기술&lt;/li&gt;
&lt;li&gt;&amp;quot;스프링부트&amp;quot;, &amp;quot;Spring Boot&amp;quot;, &amp;quot;SpringBoot&amp;quot; → 모두 같은 기술&lt;/li&gt;
&lt;li&gt;&amp;quot;k8s&amp;quot;, &amp;quot;쿠버네티스&amp;quot;, &amp;quot;Kubernetes&amp;quot; → 모두 같은 기술&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;80개 이상의 기술과 한국어 동의어를 사전으로 관리하여,&lt;br&gt;매칭 정확도를 비약적으로 올렸다.&lt;/p&gt;
&lt;h3&gt;어댑터 패턴&lt;/h3&gt;
&lt;p&gt;각 채용 사이트의 API/HTML 구조가 완전히 다르다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원티드: 깔끔한 REST API&lt;/li&gt;
&lt;li&gt;사람인: 공식 Open API (키 필요)&lt;/li&gt;
&lt;li&gt;잡코리아: 공식 API 없음 → HTML 파싱&lt;/li&gt;
&lt;li&gt;점핏: 비공식 내부 API + 웹 폴백&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;SourceAdapter&lt;/code&gt; 인터페이스로 추상화하고,&lt;br&gt;&lt;code&gt;search()&lt;/code&gt; / &lt;code&gt;fetchDetail()&lt;/code&gt; / &lt;code&gt;isAvailable()&lt;/code&gt;만 구현하면 새 사이트를 추가할 수 있게 설계했다.&lt;/p&gt;
&lt;h3&gt;템플릿 패턴 (양식 변환)&lt;/h3&gt;
&lt;p&gt;LLM에 양식 변환을 전부 맡기면:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;응답 속도가 느림 (3~10초)&lt;/li&gt;
&lt;li&gt;포맷이 매번 조금씩 다름&lt;/li&gt;
&lt;li&gt;API 비용 발생&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;그래서 &lt;strong&gt;규칙 기반 템플릿&lt;/strong&gt;으로 1차 변환하고,&lt;br&gt;LLM은 선택적으로 문장을 다듬는 역할만 하도록 분리했다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;6. 남은 과제&lt;/h2&gt;
&lt;h3&gt;단기 (다음 Phase)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로켓펀치 어댑터 구현&lt;/li&gt;
&lt;li&gt;실 서비스 환경에서 크롤링 안정성 테스트&lt;/li&gt;
&lt;li&gt;LLM 프롬프트 품질 개선 (한국어 경력기술서 문체)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;중기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CLI 인터페이스 (MCP 없이도 직접 사용)&lt;/li&gt;
&lt;li&gt;이력서 PDF 파싱 (현재는 텍스트만)&lt;/li&gt;
&lt;li&gt;공고 변경 감지 (마감일 임박 알림)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;장기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;비개발자 직무 확장 (디자이너, PM, 마케팅)&lt;/li&gt;
&lt;li&gt;면접 후기 크롤링 + 분석&lt;/li&gt;
&lt;li&gt;연봉 데이터 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;7. 배운 것&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&amp;quot;불편함&amp;quot;이 가장 강한 동기다&lt;/strong&gt; — 같은 서류를 6번 쓰는 짜증이 없었으면 이 프로젝트는 없었다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;한국 시장 도구는 직접 만들어야 한다&lt;/strong&gt; — 미국 도구를 번역해서 쓸 수 없는 영역이 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM은 만능이 아니다&lt;/strong&gt; — 규칙 기반으로 해결 가능한 건 규칙 기반이 빠르고 정확하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;어댑터 패턴의 위력&lt;/strong&gt; — 사이트마다 API가 달라도, 추상화 한 번이면 나머지 코드는 건드릴 필요 없다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP가 개인 도구 개발에 적합하다&lt;/strong&gt; — UI 없이 Claude에서 바로 도구를 쓸 수 있는 건 강력하다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/99</guid>
      <comments>https://mrgoga.tistory.com/99#entry99comment</comments>
      <pubDate>Mon, 30 Mar 2026 08:51:08 +0900</pubDate>
    </item>
    <item>
      <title>Final Project 중간 회고</title>
      <link>https://mrgoga.tistory.com/98</link>
      <description>&lt;h3&gt;1. 주요 작업 내용&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;SD Inpainting 파이프라인 구축 및 배포 인프라 세팅 (3/20)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SD(Stable Diffusion) 기반 Inpainting 런타임과 배포 도구를 새로 구성했다. 파이프라인 코드(&lt;code&gt;pipeline_sd_inpainting.py&lt;/code&gt;), 핸들러(&lt;code&gt;handler_sd.py&lt;/code&gt;), face parsing/segface 모델 통합, SAM2 마스킹 유틸 등 약 &lt;strong&gt;13,700줄&lt;/strong&gt; 규모의 코드를 세팅했다.&lt;/li&gt;
&lt;li&gt;Legacy 헤어 파이프라인 지원 코드(&lt;code&gt;pipeline_optimized.py&lt;/code&gt;, stylegan2, bald_proxy 등)를 import하여 기존 기능과의 호환성을 확보했다. 약 &lt;strong&gt;6,500줄&lt;/strong&gt; 규모.&lt;/li&gt;
&lt;li&gt;GitHub Actions 기반 CI/CD 워크플로우(build-sd-app, build-sd-base, deploy-sd)를 추가하여 Docker 빌드 및 RunPod 배포 파이프라인을 자동화했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;앞머리(Bangs) 세그멘테이션 품질 개선 (3/23)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;숏컷 스타일에서 생성 마스크가 잘리는 아티팩트를 수정했다. 마스크 영역을 넓혀 cutoff 현상을 방지했다.&lt;/li&gt;
&lt;li&gt;얼굴 보호 마스크가 앞머리 영역까지 침범하는 문제를 발견하고, face protect mask 크기를 줄여 앞머리가 보존되도록 조정했다.&lt;/li&gt;
&lt;li&gt;SAM2 프롬프트에 앞머리 positive point를 추가하여 이마 쪽 머리카락 커버리지를 개선했다.&lt;/li&gt;
&lt;li&gt;SegFace 모델의 hair threshold를 0.5 → 0.3으로 낮춰 앞머리 감지 정확도를 높였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 잘한 점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SD Inpainting 런타임부터 CI/CD, Docker, 배포까지 &lt;strong&gt;엔드투엔드 인프라를 한 번에 구축&lt;/strong&gt;한 것은 이후 빠른 반복 개발의 기반이 되었다.&lt;/li&gt;
&lt;li&gt;앞머리 세그멘테이션 이슈를 &lt;strong&gt;마스크 크기 → SAM2 프롬프트 → 모델 threshold&lt;/strong&gt; 순서로 단계적으로 접근하여 체계적으로 해결했다.&lt;/li&gt;
&lt;li&gt;PR 단위로 작업을 분리(SD 런타임 #1, develop 병합 #2)하여 코드 리뷰 단위를 관리했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 아쉬운 점 / 개선할 점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;앞머리 관련 수정이 4커밋에 걸쳐 진행되었는데, 각 커밋이 이전 수정의 부작용을 해결하는 형태였다. 사전에 마스크 파라미터 간 상호작용을 더 분석했다면 시행착오를 줄일 수 있었을 것이다.&lt;/li&gt;
&lt;li&gt;Legacy 코드 import 시 빈 파일(0 bytes)이 다수 포함되어 있다. 실제 필요한 파일만 선별하여 가져왔으면 레포지토리가 더 깔끔했을 것이다.&lt;/li&gt;
&lt;li&gt;테스트 코드(&lt;code&gt;test_runpod.py&lt;/code&gt;, &lt;code&gt;test_ip.py&lt;/code&gt;)가 존재하지만 CI에서 자동 실행되는 구조가 아직 없다. 배포 전 자동 검증 단계 추가가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 다음 주 계획&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;앞머리 외 다른 헤어스타일(긴 머리, 곱슬 등)에 대한 세그멘테이션 품질 검증 및 튜닝&lt;/li&gt;
&lt;li&gt;CI 파이프라인에 테스트 자동화 단계 추가 검토&lt;/li&gt;
&lt;li&gt;배포 파이프라인 실제 운영 환경 검증&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/98</guid>
      <comments>https://mrgoga.tistory.com/98#entry98comment</comments>
      <pubDate>Mon, 23 Mar 2026 16:32:52 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 20주차 회고</title>
      <link>https://mrgoga.tistory.com/97</link>
      <description>&lt;h1&gt;최종프로젝트 기획이 완성됬다.&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;멀티 모달을 학습하기 위해서 &amp;quot;미용실 직원/고객을 위한 트렌드, 취향 분석 적용 앱&amp;quot;을 만들기로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;지금까지의 상황 진척도&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;로직은 사진 전송 -&amp;gt; 얼굴형 분석 + 마스킹 -&amp;gt; 마스킹 된 부위에 헤어 생성 이다.&lt;/li&gt;
&lt;li&gt;지금까지는 이미지 인식(분류)모델을 이것저것 만져보고있다.&lt;/li&gt;
&lt;li&gt;모델빌드가 오래걸리면 40분 가량 걸리는데, 이부분을 축소하는 방법을 찾아보고 있다.&lt;/li&gt;
&lt;li&gt;로컬에서 빌드하다가 용량이 터지는 경우가 4~5번 정도 있어서, docker hub로 build push 후, runpod에서 pull build 하는 방법을 사용했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;현재까지 어려운점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;마스킹 모델의 성능이 머리카락이라는 얇은 물체? 객체?의 특성상 세밀하게 마스킹이 안되는 경우가 있었다.&lt;/li&gt;
&lt;li&gt;모델 변경 파라이터 변경등으로 수정하고 있는데, 위에서 언급한것과 같이, 한번 빌드시 최소 20분이라는 시간이 소요되기 때문에, 그점에서 시간적 소요가 크다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;지금까지 달성한 점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일단 생성모델의 작동을 잘 하고있다.&lt;/li&gt;
&lt;li&gt;긴머리 -&amp;gt; 짧은 머리의 머리카락 변경을 요청하고 있는데, 정상적으로 잘 작동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;앞으로 해결해야할 점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;긴머리 -&amp;gt; 짧은 머리로 변환할때, 기존에 있던, 머리카락 부분을 다른 이미지로 대체를 못하는 경우가 있다.&lt;/li&gt;
&lt;li&gt;블러처리가 되는데, 이 부분을 어떻게 수정해야할지 감이오질 않는다...&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/97</guid>
      <comments>https://mrgoga.tistory.com/97#entry97comment</comments>
      <pubDate>Mon, 16 Mar 2026 08:51:29 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 19주차 회고</title>
      <link>https://mrgoga.tistory.com/96</link>
      <description>&lt;h1&gt;드디어 시작된 최종프로젝트&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;어느덧 교육은 마무리되었고 최종프로젝트가 시작됬다.&lt;/li&gt;
&lt;li&gt;기획부터 데이터선정, 모델선정, 모델학습, 웹배포까지 총괄하는 작업이다.&lt;/li&gt;
&lt;li&gt;지금까지는 내가 만들고 싶은걸 만들었다면, 이제는 적절한 절차를 통해 사업성이 타당한지, 시간내에 구현할 수 있는지, 지금 시장에 나와있는 앱이 있는지를 파악해서 기획서, 요구사항명세, WBS등을 꼼꼼히 고려하여 프로젝트를 진행해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;멘토링..&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;우리팀의 멘토는 M사의 멘토님이 이XX 멘토님이 되었다.&lt;/li&gt;
&lt;li&gt;지금까지 멘토링을 받아본 적이 없어서.. 좀 신기한 경험이였다. 확실히 실무자의 멘토링을 받으니 프로젝트의 가닥이 쉽게 잡혔다.&lt;/li&gt;
&lt;li&gt;어떤게 사업성이 있는 프로젝트인지 확실하게 피드백을 받았고, 어떻게 기획서를 써야하는지 배우고 앞으로의 방향성도 잡아주셔서 의미있는 멘토링이 되어서 배울게 많은 멘토링이였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;우리의 프로젝트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ViT기술을 사용해 보려고 한다. 주제를 선정하고 보니 다른 전기수에서 이미 만들었던 프로젝트라 당황했다...!&lt;/li&gt;
&lt;li&gt;방향성을 다르게하고, 신기술을 더 접목을 시켜서 확실하게 구현을 해야겟다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/96</guid>
      <comments>https://mrgoga.tistory.com/96#entry96comment</comments>
      <pubDate>Sun, 8 Mar 2026 22:36:50 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 18주차 회고</title>
      <link>https://mrgoga.tistory.com/95</link>
      <description>&lt;h1&gt;드디어 수업이 다 끝났다..&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;강사님이 준비해오신 수업은 다 끝났고, 이제 최종프로젝트만 남았다.&lt;/li&gt;
&lt;li&gt;파이널 프로젝트 조가 나왔는데 참여에 적극성이 없으신 분이 있어서 좀 걱정이다.&lt;/li&gt;
&lt;li&gt;그 전에 4차 프로젝트 도 있는데 그건 뭐.. 다들 잘하니깐 금방 끝날것 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;최종프로젝트 기획&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일단 센터에서 정해준 몇개의 주제가 있엇는데, 한가지 대주제로 &lt;strong&gt;LLM 활용 내부고객 업무 효율성 향상을 위한 문서검색시스템&lt;/strong&gt;을 선택했다.&lt;/li&gt;
&lt;li&gt;사용자가 학습할 도메인을 선택한 후 LLM을 통해 학습하는 플랫폼을 구현하는게 목적이다.&lt;/li&gt;
&lt;li&gt;RAG데이터만 잘 가져오면 확장성은 무한한 프로젝트일것으로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;개인프로젝트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LLM을 이용한 TRPG 게임을 만드려고 한다.&lt;/li&gt;
&lt;li&gt;사용자가 배경을 정해도 되고, 미리 입력한 세계관으로 게임을 진행할 수 있게 할 예정이다.&lt;/li&gt;
&lt;li&gt;웹으로 간단히 구현이 가능할것 같고, 관련 자료를 찾아보는중이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;코딩테스트&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhOYGs/dJMcajuxE9g/zk3z8hvamHTkO6QHn9xUc0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhOYGs/dJMcajuxE9g/zk3z8hvamHTkO6QHn9xUc0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhOYGs/dJMcajuxE9g/zk3z8hvamHTkO6QHn9xUc0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhOYGs%2FdJMcajuxE9g%2Fzk3z8hvamHTkO6QHn9xUc0%2Fimg.jpg&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일단 PCCE 는 레벨3를 달성했다. 레벨 4는 굳이...? 라는 느낌이라 이제 아마 PCCP를 준비할것 같다.&lt;/li&gt;
&lt;li&gt;인강은 다 안봤는데 다시 보기 시작해야할것 같다.&lt;/li&gt;
&lt;li&gt;이제 하루에 한문제씩은 꼭 풀어봐야지..!&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/95</guid>
      <comments>https://mrgoga.tistory.com/95#entry95comment</comments>
      <pubDate>Sun, 1 Mar 2026 22:18:32 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 17주차 회고 + 설날 이슈</title>
      <link>https://mrgoga.tistory.com/94</link>
      <description>&lt;h1&gt;이번주의 공부시간은 박살...&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;일단 설이 있엇다.. 핑계지만 이번 주 공부시간은 박살.. 오랜만에 고향 친구들과 가족들을 만나느라 시간을 다 써버렷다..!&lt;/li&gt;
&lt;li&gt;뭔가 만드려고 계속 노력은 하는데, 저번 개인프로젝트가 망한 이후로 의욕이 감퇴된것 같다...&lt;/li&gt;
&lt;li&gt;새로운 의욕거리를 만들어야 겟다...!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;설 주에 있던 일들...&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LLM이 대중화 되었고 내가 LLM을 튜닝하는 공부를 한다고 하니, 다양하게 태클이 들어온다...&lt;/li&gt;
&lt;li&gt;본인 말이 다 맞는줄 아는 답답한 사람들과 말하느라 쉬었지만, 힘든 일정이였다....&lt;ul&gt;
&lt;li&gt;LLM이 잘못된 정보를 자꾸 말한다고 하는데, LLM 환각 원인을 말해주고 최대한 환각이 안나오게 사용하는 법을 알려줘도 못믿는 사람들과 답답한 이야기를 이어나갔다.&lt;/li&gt;
&lt;li&gt;뭐 나도 설명하면서 다시 공부하게됬고, 어떻게 설명해야 사람들이 잘 알아들을수 있는지 알게되는 계기가 되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;돌아오는 주에 할 일들 정리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일단 다시 알고리즘 공부 시작해야겟다..! 거의 2주간 놓고있었으니, 다시 감을 찾는데 오래 걸릴것 같다&lt;/li&gt;
&lt;li&gt;누나 집에서 다니니깐 다시 공부시간을 늘려야지 뭐...&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/94</guid>
      <comments>https://mrgoga.tistory.com/94#entry94comment</comments>
      <pubDate>Sat, 21 Feb 2026 22:59:58 +0900</pubDate>
    </item>
    <item>
      <title>모바일 환경 LLM 적용 검토와 한계 분석</title>
      <link>https://mrgoga.tistory.com/93</link>
      <description>&lt;h1&gt;사이드 프로젝트가 망했다…&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;말 그대로 처참하게 망했다.&lt;/li&gt;
&lt;li&gt;현실적인 문제로 개발에 실패했고, 그 과정을 정리하며 회고해보려 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;만들려던 앱의 개요&lt;/h2&gt;
&lt;p&gt;누나가 임신성 당뇨를 겪고 있다. 특정 음식을 먹으면 공복 혈당과 식후 2시간 혈당을 비교했을 때, 어떤 재료(성분)가 들어간 음식에서 유독 혈당이 크게 치솟는 경우가 있었다.&lt;br&gt;그래서 그 “문제 재료”는 피하고, 혈당 관리에 도움이 되는 음식들을 기반으로 LLM이 레시피를 추천/생성해주는 혈당관리 앱을 만들려고 했다.&lt;/p&gt;
&lt;p&gt;처음엔 단순히 LLM API를 호출하면 개발도 편하고 답변 품질도 좋을 거라 생각했다. 그리고 앱을 마켓에 올린 뒤 구글 애드(Ad)로 수익화하는 그림을 그렸다.&lt;/p&gt;
&lt;p&gt;하지만 곧 현실적인 한계가 보였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API 방식은 운영비(토큰 비용) 가 계속 발생한다.&lt;/li&gt;
&lt;li&gt;단순 API 호출은 내가 하고 싶은 모델 파인튜닝 + 서비스와는 거리가 멀다.&lt;/li&gt;
&lt;li&gt;내 상황에서 금전적인 부담을 감당하기 어렵다는 결론에 가까워졌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 “서버를 직접 운영하지 않아도 되는” Firebase(BaaS) 를 기반으로 가볍게 만들고 싶었다.&lt;/p&gt;
&lt;h2&gt;진행 과정&lt;/h2&gt;
&lt;h3&gt;1) 모델 후보 선정&lt;/h3&gt;
&lt;p&gt;모델 후보는 크게 두 가지였다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EXAONE-3.5-2.4B: 한국어 답변 품질이 좋다.&lt;/li&gt;
&lt;li&gt;Qwen2.5 계열: 경량화 옵션이 다양하다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2) 구조적 제약을 뒤늦게 인지&lt;/h3&gt;
&lt;p&gt;문제는, 내가 서버를 운영하지 않는 구조(Firebase 중심)에서는 &lt;strong&gt;튜닝한 sLLM을 서버에서 직접 돌리기 어렵다&lt;/strong&gt;는 점이었다.&lt;br&gt;(서버를 따로 두자니 다시 운영비/관리 부담이 생긴다.)&lt;/p&gt;
&lt;p&gt;그때 요즘 광고에서 흔히 보이는 문구가 떠올랐다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;“휴대폰에서 AI를 사용하세요.”&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;그래서 방향을 틀었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“그렇다면 모델을 더 경량화해서 &amp;#39;On-device LLM&amp;#39; 으로 돌리면 되지 않을까?”&lt;/li&gt;
&lt;li&gt;목표: 모바일 기기에서 로컬 추론이 가능한지 검증해보기&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;치명적인 문제&lt;/h2&gt;
&lt;h3&gt;1) 로컬 테스트부터 이미 느렸다&lt;/h3&gt;
&lt;p&gt;최종 모델은 “로컬 기기에서 먼저 돌려보고 결정하자”로 정했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;먼저 EXAONE-3.5-2.4B 를 로컬에서 테스트했다.&lt;br&gt;“2.4B면 그래도 금방 나오겠지”라고 생각했는데, 응답이 30분 이상 걸렸다.&lt;br&gt;→ 이 속도면 모바일에서 돌리는 건 사실상 불가능하다고 판단했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 더 경량화된 옵션이 있는 Qwen2.5-1.5B-Instruct 를 선택했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen2.5-1.5B도 로컬 테스트에서 답변까지 약 10분이 걸렸다.&lt;br&gt;→ 지금 생각하면 여기서 멈췄어야 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2) 모바일 실험: 앱이 그냥 죽었다&lt;/h3&gt;
&lt;p&gt;그래도 “혹시 몰라서” 실제로 &amp;#39;앱 + 모델 탑재 형태&amp;#39;로 설치해서 실행해봤다.&lt;/p&gt;
&lt;p&gt;결과는 단순했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;앱이 그냥 종료(크래시) 해버렸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;성능/속도 문제가 아니라, &amp;#39;메모리/리소스/런타임&amp;#39; 안정성 단계에서 이미 버티지 못했다.&lt;br&gt;즉, “돌아가긴 하는데 느리다” 수준이 아니라 실행 자체가 성립하지 않는 환경이었다.&lt;/p&gt;
&lt;h2&gt;배운 점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아무리 경량화된 모델이라도, 현재의 모바일 기기에서 LLM을 제대로 돌리는 건 아직 무리라는 걸 몸으로 배웠다.&lt;br&gt;관련 연구도 이미 존재했다: &lt;a href=&quot;https://arxiv.org/pdf/2402.14905&quot;&gt;논문 링크&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;개발에서 자주 하던 “일단 만들고 보자” 방식이, 이런 문제에서는 오히려 시간을 크게 낭비하게 만든다.&lt;br&gt;다음부터는:&lt;ul&gt;
&lt;li&gt;선행 연구/사례/벤치마크를 먼저 확인하고&lt;/li&gt;
&lt;li&gt;실행 가능성을 검증한 뒤&lt;/li&gt;
&lt;li&gt;설계를 시작하는 편이 훨씬 효율적이라는 걸 느꼈다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;On-device를 전제로 하지 않고, 비용을 통제할 수 있는 방향부터 먼저 설계할 것 (예: 레시피 생성은 서버에서, 앱은 캐싱/프롬프트 최소화/사용량 제한 등)&lt;/li&gt;
&lt;li&gt;또는 LLM을 “생성”이 아니라 검색+요약(RAG) 기반의 제한된 답변으로 축소해서 리스크를 낮출 것&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/93</guid>
      <comments>https://mrgoga.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 17 Feb 2026 20:51:13 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 15주차 회고</title>
      <link>https://mrgoga.tistory.com/92</link>
      <description>&lt;h2&gt;이제 웹이다&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;길고 길었던 머신러닝 ~ LLM ~ NLP ~ 멀티모달까지의 과정이 끝낫고, 프로젝트도 나름 성공적으로 끝났다.&lt;/li&gt;
&lt;li&gt;점진적 증진방식으로 프로젝트 규모를 키웟고 결과물도 좋았다.&lt;ul&gt;
&lt;li&gt;아쉬운 점은 양이 너무 커져서 발표자료나 제출자료에 내용을 빼먹고 안넣은 부분이 있어서 다 보여주지 못해서 오히려 아쉬웠다.&lt;/li&gt;
&lt;li&gt;발표자료나 제출자료를 검토할때는 기억에 의존하지 않고, PR문서를 확인하는 습관을 길러야겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이제 웹상으로 올리는 일만 남아서 활약할 때가 된것 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;개인프로젝트를 시작했다.&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;아무래도 포트폴리오가 더 필요할 것 같아서, 친누나의 요청으로 혈당 관리 앱을 하나 만들고있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;웹으로 짜려고 했는데, 사용자의 편의성을 위해서 앱으로 출시하고 광고도 받을 생각이다.&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tr1hN/dJMcabXn2XT/dDP9RHQ8lvYSCbTtN0WW91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tr1hN/dJMcabXn2XT/dDP9RHQ8lvYSCbTtN0WW91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tr1hN/dJMcabXn2XT/dDP9RHQ8lvYSCbTtN0WW91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftr1hN%2FdJMcabXn2XT%2FdDP9RHQ8lvYSCbTtN0WW91%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;플러터를 이용해서 멀티 디바이스 지원이 가능하게 하려고 했는데, 테스팅 과정에서 내 노트북의 용량의 한계를 겪고 일단 안드로이드 시뮬레이터를 돌리면서 UI + FireBase + Google AdMob 까지는 연동을 완료했다.&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v4W2t/dJMcaa5fMmJ/OkKeURkaR3tPRvguxgpAL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v4W2t/dJMcaa5fMmJ/OkKeURkaR3tPRvguxgpAL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v4W2t/dJMcaa5fMmJ/OkKeURkaR3tPRvguxgpAL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv4W2t%2FdJMcaa5fMmJ%2FOkKeURkaR3tPRvguxgpAL1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;개발하면서 조금이라도 광고 수익을 높이려고 미리 광고 승인요청을 했는데 아직 구글에서 승인을 안해주고있다... 얼른 일해라 구글...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;일단 API를 사용해서 조언을 해주는 앱을 만드려고 했는데, 비용이 꽤 나올것 같아서, OnDevice LLM을 구축해 보려고 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원래 API 호출로 구조를 다 잡아 놨는데, 개발중에 비용문제가 걱정이 되서 다시 구조를 뒤엎는 중이다.&lt;/li&gt;
&lt;li&gt;막상 바꾸려니 Android 기기가 필요해서 예전에 쓰던 핸드폰을 들고 등원해야겟다..&lt;br&gt;&lt;del&gt;- 이럴꺼면 Android Studio + Android SDK는 왜 다시깔았지.. 지워야겟다..&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;앱 용량이 커질 수 있다는데, 일단 한번 해보고 안돼면 서버에 sLLM 하나 띄워놔야되나...? 아니면 BM이 없어서 아직 이런 앱이 없는건가...?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;광고 수익 나오면 맛있는거 사먹어야지&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;팀으로 진행하는 사이드프로젝트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;소개팅 대화 데이터를 모으기 위해서 돌리고 있는 소개팅 시뮬레이터는 103명 의 대화 데이터가 모이긴 했는데, 아직 부족해서 어떻게 홍보해야할지 다시 생각을 해봐야겟다.&lt;/li&gt;
&lt;li&gt;지인들, 학원 다른기수는 이미 요청완료 했고, 인터넷 커뮤니티에라도 올려볼까 생각중이긴 한데, 이게 익명의 사이트에서 어떤사람들이 어떤 공격을 할 줄 몰라서 걱정이 되는 부분이긴 하다.&lt;ul&gt;
&lt;li&gt;일단 프롬프트 인젝션을 막아놓기는 했지만, 기상천외한 사람들이 인터넷에는 많아서 걱정이긴 하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 글을 보는 사람이 누구인지는 모르겟지만, 본다면 &lt;strong&gt;&lt;a href=&quot;https://blinddatesimulator.streamlit.app/&quot;&gt;데이팅 시뮬레이터&lt;/a&gt;&lt;/strong&gt; 이거 한번 해보세요 재밌어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;공부시간은 천천히 올라가고 있다.&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;공부할게 없다고 생각이 들면, 코딩테스트 문제를 풀던가, 인강을 보던가, 프로젝트 개발을 하는 삶으로 맞춰졌다.&lt;br&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yOTCz/dJMcaflbMFl/wIt6ZL58GQNKxOWAMbWQu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yOTCz/dJMcaflbMFl/wIt6ZL58GQNKxOWAMbWQu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yOTCz/dJMcaflbMFl/wIt6ZL58GQNKxOWAMbWQu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyOTCz%2FdJMcaflbMFl%2FwIt6ZL58GQNKxOWAMbWQu1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;코딩시간 랭킹도 저번주 보다 많이 올라갔다! in 100을 목표로 달려봐야지&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/92</guid>
      <comments>https://mrgoga.tistory.com/92#entry92comment</comments>
      <pubDate>Sat, 7 Feb 2026 15:38:52 +0900</pubDate>
    </item>
    <item>
      <title>[플레이데이터 SK네트웍스 Family AI 캠프 22기] 14주차 회고 + 정보처리기 필기 회고</title>
      <link>https://mrgoga.tistory.com/91</link>
      <description>&lt;h1&gt;단위 프로젝트가 다시 돌아왔다&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;전 프로젝트 때 걱정했던 부분을 보완한 팀을 배정돼서 팀에 대한 만족도는 높다.&lt;/li&gt;
&lt;li&gt;아직 정식으로 시작도 하기전인데 거의 다 완성이 되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;코딩테스트 시험을 다시 봤다.&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;뭔가 만족할만한 점수가 나오지 않아서 스트레스를 좀 받았다.&lt;/li&gt;
&lt;li&gt;그래도 전보다는 점수가 올라서 다행이긴 하지만, 인강 + 복습시간을 더 늘려야겠다.&lt;/li&gt;
&lt;li&gt;코딩테스트 스터디는 이제 할 게 없어서 안 하기로 스터디원들과 합의를 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;누나집에서 하숙을 시작해서 공부시간이 늘었다&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;철산에 있는 누나집에서 2달간 하숙을 하기 시작했다,&lt;/li&gt;
&lt;li&gt;항상 8시 반이면 다음날 등원을 위해 집에 가야 했지만, 이제는 9시 반 넘어서 퇴원을 해도 다음날 아침 운동까지 할 수 있는 환경이 되었다.&lt;/li&gt;
&lt;li&gt;늘어난 공부시간을 이용해서 코딩테스트 알고리즘 공부를 더 늘려갈 생각이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;늘어난 공부시간으로 Wakatime 전세계 9948등을 달성했다.&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daRo3G/dJMcadU7Mxq/BtPYWtZKV6n8rQIPxRrmQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daRo3G/dJMcadU7Mxq/BtPYWtZKV6n8rQIPxRrmQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daRo3G/dJMcadU7Mxq/BtPYWtZKV6n8rQIPxRrmQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaRo3G%2FdJMcadU7Mxq%2FBtPYWtZKV6n8rQIPxRrmQ0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;코딩시간을 알려주는 Wakatime 앱에서 전세계 9948등을 달성했다.&lt;/li&gt;
&lt;li&gt;예전에 500등인가까지 올라간 기억이 있는데, 주말에도 조금씩 공부를 더 진행해서 500등 안쪽으로 들어가기 목표를 잡아야겟다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;정보처리기사 필기를 봤다&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;4년 전인가.. 개발자로 취업을 위해 필기만 따놨다가, 취업이 돼버려서 실기를 유기한.. 정보처리기사 필기를 다시 봤다.&lt;/li&gt;
&lt;li&gt;전에 볼 때는 서울인근에 시험장이 없어서, 충청도쪽에서 본 기억이 있는데, 요즘은 CBT로 봐서 자리가 널널 했다.&lt;/li&gt;
&lt;li&gt;시험장에 필기구를 들고갔다가 &amp;#39;필요없네&amp;#39; 라고 생각하고 가방에 집어 넣었는데, Python, Java, C 언어 출력 문제가 있어서, 암산으로 하기가 어려웠다.&lt;/li&gt;
&lt;li&gt;4년 개발 경력과 4년전 공부했던 기억만 가지고 시험을 보러 갔는데 &amp;#39;어? 떨어지면 어떻게하지?&amp;#39;라는 생각이 들 정도로 문제난이도가 좀 있었다.&lt;/li&gt;
&lt;li&gt;CBT로 진행이 되어서 가채점 결과가 바로 나왔는데, 다행이 걱정했던것 보다 점수가 높게 나와서 턱걸이 합격을 할 수 있었다.&lt;/li&gt;
&lt;li&gt;이제 4월에 있을 실기시험도 보고 바로 다시 취업준비를 해야겠다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>회고</category>
      <author>고가씨</author>
      <guid isPermaLink="true">https://mrgoga.tistory.com/91</guid>
      <comments>https://mrgoga.tistory.com/91#entry91comment</comments>
      <pubDate>Sun, 1 Feb 2026 21:07:55 +0900</pubDate>
    </item>
  </channel>
</rss>