TinyPilot: Month 40

Michael Lynch

TinyPilot: 40번째 달

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

한 줄 요약

microSD 플래싱의 놀라운 어려움

하이라이트

  • TinyPilot이 역대 두 번째로 높은 월 매출을 기록했다.
  • TinyPilot의 제조 외주 전환이 거의 완료됐다.
  • 기계식 키보드의 어두운 세계에 발을 들였을지도 모른다.

목표 달성도

매달 초에 달성하고 싶은 목표를 정한다. 이번 달 목표 달성 결과는 다음과 같다:

외주 제조업체로 생산 이전을 최대한 빠르게 진행하기

  • 결과: 첫 번째 배치에서 사소한 문제가 있었지만 곧 이전을 마칠 수 있을 것 같다.
  • 평가: B

외주 제조업체로부터 첫 생산 배치를 받았고, 11월에 고객에게 배송할 예정이다.

이번 배치가 완벽해서 이전 완료를 선언할 수 있기를 바랐다. 안타깝게도 사소한 오류가 조립 과정에 있어 사무실에서 직접 수정해야 했고, 아직 제조업체에서 창고, 그리고 고객까지 매끄럽게 이어지는 파이프라인을 갖추지 못했다.

TinyPilot 소프트웨어 릴리스 과정에서 수작업 줄이기

  • 결과: 나에게 묶여 있던 수동 릴리스 작업을 없앴다.
  • 평가: A

나는 항상 TinyPilot 소프트웨어 릴리스 과정을 자동화하고 단순화할 방법을 찾는다. 특히 TinyPilot의 일상적인 워크플로에서 내가 병목이 되는 구간을 없애는 데 관심이 많다. 10월에는 TinyPilot Pro 새 버전이 나왔을 때 TinyPilot 웹사이트를 업데이트하는 과정을 자동화하면서 두 가지 모두에서 진전을 이뤘다.

원래는 내가 직접 릴리스를 만든 뒤 웹사이트의 다운로드 URL을 수동으로 업데이트해야 했다. 이제는 웹사이트가 업데이트 서비스와 동기화되어 새 릴리스를 자동으로 인식한다.

TinyPilot Pro 라이선스 집행 강화를 위한 계획 수립하기

  • 결과: 계획 수립에 진전이 없었다.
  • 평가: F

개발팀이 10월에 예상보다 시간이 부족해 라이선스 집행 계획을 세우는 데 진전을 이루지 못했다.

TinyPilot 통계

지표2023년 9월2023년 10월변화
순 방문자 수6,2008,700+2,500 (+40%)
판매 수익$83,380.02$98,896.81+$15,516.79 (+19%)
엔터프라이즈 구독$290.70$290.700
로열티$2,056.30$2,609.84+$553.54 (+27%)
총 수익$85,727.02$101,797.35+$16,070.33 (+19%)
이익$8,644.82$69,280.58+$60,635.76 (+701%)

이번 달은 TinyPilot 역사상 두 번째로 매출이 높은 달이었는데, 이유는 전혀 모르겠다. 분석 데이터에서 특별히 눈에 띄는 점도 없고, 새로운 리뷰나 언급을 본 적도 없다. 2022년 10월에도 매출이 높았으니 단순히 계절적 요인일 수도 있다.

제조 이전에 집중하느라 마케팅에 투자하지 못해서 수치가 조금 떨어질 줄 알았다. 관성만으로 버틸 수 있다는 걸 확인해서 다행이지만, 2023년 마지막 몇 달 동안은 성장에 다시 투자를 늘리기 시작했다.

새 제조업체와 microSD 문제 바로잡기

사라진 디스크

TinyPilot 기기는 microSD라는 작은 디스크에 데이터를 저장한다. 제조업체가 TinyPilot 기기의 첫 샘플을 보내기로 한 며칠 전, 내가 보낸 레퍼런스 기기에 microSD가 들어 있는 것을 발견했다. microSD가 필요한지 묻는 것이었다.

TinyPilot microSD 디스크

알고 보니 제조업체가 자재 명세서(BOM)에 microSD를 포함하지 않았던 것이다. 나 역시 빠져 있다는 걸 전혀 눈치채지 못했다.

다행히 microSD를 구매해 플래싱하는 과정은 빠르고 간단하다. 이미 TinyPilot 로고가 찍힌 microSD를 제작하는 업체가 있었고, 제조업체와 해당 업체를 연결해 준 뒤 TinyPilot 소프트웨어를 microSD에 플래싱하는 방법을 설명했다.

제조업체와 나는 microSD 때문에 첫 샘플 배송을 미룰 가치는 없다고 합의했다. 기기는 microSD 없이 먼저 보내고, microSD는 1~2주 뒤에 따로 보내기로 했다.

첫 샘플에 문제가 워낙 많았던 탓에 microSD 얘기는 완전히 잊어버렸고, 제조업체도 결국 보내지 않았다.

microSD가 올바르게 플래싱됐는지 확인하기

10월 중순쯤 제조업체는 첫 샘플에서 내가 지적한 모든 문제를 수정했다고 했다. 고객에게 바로 배송할 수 있을 정도로 완전히 완성된 소규모 생산 배치를 보내겠다고 했다.

그래도 첫 배치에 대해서는 사내 기준에 부합하는지 추가 QA를 진행할 예정이었다. 검증 과정의 일부는 제조업체가 microSD를 올바르게 플래싱했는지 확인하는 것이었다.

배치가 도착하기 이틀 전까지도 제조업체가 microSD를 올바르게 플래싱했는지 어떻게 확인할지 생각하지 않았다. 디스크의 마지막 바이트 하나까지 정확히 일치하는지 확인하고 싶었다.

microSD 검증이 간단한 일이 아니어서, TinyPilot 지원 엔지니어링 팀에 제조업체의 microSD와 우리의 “골든” 디스크 이미지를 비교해 차이점을 보고하는 간단한 셸 스크립트를 만들어 달라고 부탁했다. 팀은 내 테스트에 맞춰 간신히 스크립트를 완성했다.

첫 배치가 도착했을 때 microSD를 장착하고 무결성 검사 스크립트를 실행했더니 모든 것이 일치한다고 나왔다. 좋았다!

기능 테스트를 실행해 보니 모든 것이 정상적으로 작동했다. 정말 기뻤다. 이번 배치는 제조업체가 완벽하게 처리했다는 뜻이었고, 외주 제조업체로의 이전이 성공했다고 선언할 수 있게 됐다.

테스트하던 마지막 TinyPilot을 종료하려는데 뭔가 이상한 점을 발견했다. 비디오 설정이 TinyPilot 출하 시 기본값이 아니었고, 누군가 나보다 먼저 이 기기를 사용한 것처럼 보였다.

테스트하던 기기를 종료하고 microSD 검사 스크립트를 다시 실행했다. 이번에는 테스트 중에 설정을 많이 바꿨으니 당연히 변경 사항이 보고되어야 했다. 그런데도 스크립트는 내 microSD가 골든 이미지와 완벽하게 일치한다고 보고했다.

큰일이었다.

스크립트는 지원 엔지니어의 머신에서는 정상적으로 작동했지만, 내 테스트 환경에서는 항상 거짓 양성(false positive)을 반환했다.

microSD를 더 자세히 살펴보니 제조업체가 우리의 지침을 오해한 것이 분명했다. 우리는 QA용 테스트 microSD로 검사를 한 뒤 고객에게 포장하기 전에 새 microSD로 교체해 달라고 요청했다. 하지만 제조업체는 교체를 하지 않고, 사용된 microSD가 그대로 들어간 제품을 고객에게 배송하고 있었다.

다행히 이 실수는 사무실에서 비교적 쉽게 바로잡을 수 있었다. 현지 팀이 박스를 하나씩 열어 microSD를 깨끗한 상태로 다시 플래싱하고, 재포장한 뒤 창고로 보냈다.

장기적으로는 사무실에서 모든 microSD를 다시 플래싱하고 싶지 않다. 제조업체에 문제를 알리자 실제로 지침을 오해했음을 인정하고, 고객에게 전달되는 모든 microSD가 우리 이미지로 새로 플래싱되도록 프로세스를 수정했다고 했다. 다음 배치는 다시 검증할 예정이지만, 이제 이 문제가 거의 끝나가고 있기를 기대한다.

microSD 문제는 어떻게 막을 수 있었을까?

microSD 문제는 이전에 발생한 여러 오류가 겹쳐진 결과였다:

  • 제조업체의 자재 명세서에서 microSD가 빠져 있다는 걸 알아채지 못했다.
  • 제조업체가 샘플 microSD를 보내지 않았는데, 나도 후속 확인을 잊어버렸다.
  • 프로세스가 거의 끝날 때까지 microSD를 어떻게 검증할지 생각하지 않았다.
  • microSD 검사 스크립트에 얼마나 엄격함을 들여야 하는지 과소평가했다.

BOM을 검토할 때 나는 기억에만 의존해 모든 것이 있다고 생각했다. 제품 하나를 철저히 분해해 제조업체의 BOM과 우리 제품의 모든 구성 요소가 1:1로 일치하는지 확인했어야 했다.

이번이 제조업체가 약속을 지키지 않아 문제가 생긴 두 번째인데, 아직 마땅한 해결책을 찾지 못했다. 전반적으로는 대부분의 업무를 잘 챙기지만, 내가 후속 확인을 하지 않으면 10% 정도는 잊어버린다. 기다리고 있는 일이 있을 때 문제를 제기해 왔지만, 그러다 보니 microSD나 설명서 같은 것들이 쉽게 누락된다. 배송을 막기 전까지는 중요해 보이지 않는 부품들이기 때문이다.

microSD 검사 스크립트에도 투자를 너무 적게 했다. 당시에는 일회성 스크립트처럼 느껴져서 고객 대상 코드만큼 시간과 공을 들일 필요가 없다고 생각했다. 하지만 거짓 양성을 겪고 나서 QA 과정에서 스크립트가 예상대로 동작하는 것이 얼마나 중요한지, 실수했을 때 비용이 얼마나 클 수 있는지 깨달았다. 그래서 지금은 프로덕션 수준의 코드를 만드는 표준 프로세스에 따라 스크립트를 다시 작성하고 있다.

제조업체의 프로세스를 처음부터 끝까지 검증할 방법이 무엇인지 아직 잘 모르겠다. 사내에서 직접 할 때는 Notion에 정리된 지침이 있었고 팀 전체가 그것을 따랐다. 하지만 제조업체와는 Notion 워크스페이스를 공유할 수 없다. 작업자들이 모두 영어를 읽지 못하기 때문이다. 그래서 우리는 영문 지침을 전달하고 제조업체가 이를 베트남어로 번역하면 작업자들은 베트남어 버전을 본다. 베트남어 프로세스가 영문 프로세스와 일치하는지 내가 확인할 방법이 없다.

QA 과정의 영상을 요청한 것은 도움이 됐다. 언어와 상관없이 제조업체가 QA를 어떻게 수행하는지 보여줬기 때문이다. 하지만 전체 과정을 처음부터 끝까지 영상으로 담기는 어렵다. QA 과정 영상에서는 테스트에 사용한 microSD가 최종 제품에 그대로 남아 있다는 사실이 명확히 드러나지 않았고, 이를 어떻게 막을 수 있을지 잘 모르겠다.

제조업체는 베트남 공장으로 방문해 달라고 초대했지만, 올해는 출장을 너무 많이 다녀서 거절했다. 돌이켜보면 방문했더라면 비용이 많이 드는 실수를 막을 수 있었을지도 모른다. 현지 팀원 중 한 명에게 방문을 제안할 수도 있었다.

고객 성공 프로세스 만들기

연초에 현지 TinyPilot 팀의 업무는 고객 서비스가 약 20%, 조립과 풀필먼트가 80%였다. 제조와 풀필먼트를 외부 업체로 이전하면서 올해 그 비중이 크게 바뀌었다. 2024년 초까지는 조립과 풀필먼트가 현지 팀 업무에서 0%가 될 예정이다.

문제는 고객 서비스가 여전히 현지 팀의 주당 업무 시간 중 50%도 차지하지 않는다는 점이다. 남는 시간을 어떻게 활용할 것인가?

팀은 연초부터 이 문제를 논의해 왔다. 가장 자연스러운 전환은 지원 요청에 수동적으로 대응하는 것에서 기존 고객에게 능동적으로 다가가는 것으로 옮겨가는 것이며, 일부 기업은 이 역할을 “고객 성공”이라고 부른다.

창피한 사실이지만 나는 고객에게 거의 연락하지 않는다. 중요하지만 긴급하지 않은 일 중 하나로 항상 미루게 되는 일이다. 하지만 현지 직원들에게 이 일을 가르칠 수 있다면 더 이상 내 시간에 제약받지 않게 된다.

우리는 다음과 같은 새로운 고객 성공 프로세스를 시범 운영하고 있다:

  1. 고객 서비스 팀이 TinyPilot에 많은 금액을 지출한 고객(특히 재구매 고객)을 조사한다.
  2. 고객 서비스 팀이 해당 고객의 회사와 주문에 대한 구체적인 내용을 담은 사람이 직접 쓴 이메일(자동화된 것처럼 보이지 않도록)과, 기능 요청이나 불편 사항을 논의하기 위한 통화 초대를 보낸다.
  3. 고객과 미팅을 갖고 TinyPilot을 어떻게 활용하고 있는지 알아본다.
  4. 고객 피드백을 기능 로드맵에 반영한다.

내가 고객으로서 다른 기업으로부터 연락을 받을 때면 대개 노골적으로 이기적이다. “저희 제품 라인업을 더 잘 이해하도록 돕고 싶습니다” 같은 말을 하지만, 실제로는 더 많이 사게 하려는 속셈이다.

나는 TinyPilot의 고객 아웃리치가 기생적이거나 탐욕스럽게 느껴지기보다 협업처럼 느껴지길 바란다. 이를 통해 로드맵을 고객이 원하는 기능에 맞게 조정하고, 그렇지 않았다면 발견하지 못했을 TinyPilot의 새로운 기회를 찾을 수 있을 것이라 생각한다.

사이드 프로젝트

안녕 Ansible, 안녕 Nix

지난 몇 년간 개발 환경을 관리하는 데 Ansible을 사용해 왔지만, 점점 지치는 고질적인 문제점들이 많았다. 지난 몇 달간 Ansible을 Nix로 대체하려고 노력했는데, 이제 거의 마무리된 것 같다.

예전에 Nix Home Manager를 본 적이 있지만, 왜 필요한지 이해하지 못했다. 홈 디렉터리의 파일을 관리한다고? NixOS가 이미 전체 시스템을 관리하는데?

내가 놓치고 있던 핵심은 다음과 같다:

  • Home Manager는 NixOS뿐만 아니라 모든 Linux나 Mac 시스템에서 동작한다.
  • Home Manager는 텍스트 파일에 최적화되어 있어 텍스트 파일을 관리하는 인터페이스가 NixOS보다 낫다.

이제는 Ansible로 개발 시스템을 관리하는 대신 Home Manager와 프로젝트별 Nix flake로 모든 것을 관리한다. 한 달 넘게 Ansible 플레이북을 실행하지 않았다.

눈에 띄는 변화 중 하나는 자주 쓰는 명령어에 대해 bash alias를 더 자주 정의해 사용한다는 점이다. 예전에는 bash alias를 추가하려면 Ansible 플레이북에 추가한 뒤 해당 alias를 적용하고 싶은 모든 시스템에서 플레이북을 다시 실행해야 했다. 하지만 Ansible 플레이북 실행은 너무 느리고 실패하기 쉬워서, 결국 절반의 시스템에만 alias가 적용되고 절반에는 적용되지 않곤 했다. 그 과정에 마찰이 너무 많아서 새로운 alias를 추가해 평소 습관에 녹여낼 동기가 거의 생기지 않았다.

Nix에서는 이제 Home Manager가 모든 bash alias를 관리한다. 셸 alias를 추가하고 싶으면 ~/.config/home-manager/home.nix를 편집한 뒤 home-manger switch를 실행해 변경 사항을 적용하면 된다(사실 이 명령어는 hs라는 bash alias로 줄여 놓았다). 전체 과정은 1분도 걸리지 않으며, Ansible처럼 외부 요인 때문에 실패하는 일도 없다.

NixOS로 완전히 전환하려고 시도했었지만, 평소 쓰던 Debian 개발 환경과 차이가 너무 많아 어려움을 겪었다. Home Manager를 사용하는 것은 Nix에 올인하는 것과 익숙한 Debian 워크플로를 유지하는 것 사이의 좋은 절충안이다.

이제 괴짜 기계식 키보드 유저가 됐다

Python 창시자 Guido van Rossum과의 Lex Fridman 인터뷰에서 Lex는 자신의 Kinesis Advantage 2 키보드를 얼마나 사랑하는지에 대해 길게 이야기한다.

Kinesis는 기계식 키보드 분야에서 인기 있는 업체다. 이들의 키보드는 키가 오목한 웰(well) 안에 배치되어 있고 키보드의 두 부분이 서로 몇 인치 떨어져 있는 것이 특징이다.

Lex Fridman은 자신의 Kinesis Advantage 2 기계식 키보드를 사랑한다.

Lex는 Kinesis 키보드를 너무 좋아해서 노트북 내장 키보드를 쓰는 대신 거대한 키보드를 들고 비행기를 탈 정도다.

나는 14살 때부터 Microsoft Ergonomic Keyboard를 어떤 형태로든 계속 써 왔다. 마음에 들긴 하지만 Lex가 Kinesis에 대해 말하는 것처럼 사랑하지는 않아서, 지난 몇 달간 기계식 키보드가 궁금해졌다.

최근까지 내 메인 키보드였던 Microsoft Natural Ergonomic Keyboard 4000

기계식 키보드를 쓰는 사람을 두세 명 정도 알지만, 그 매력을 이해하지 못했다. 그들이 무언가에 열광하고 싶다면야 좋지만, 키보드에서 얻을 수 있는 최대의 즐거움은 꽤 제한적이라고 느껴서 굳이 신경 쓸 필요가 있을까 싶었다.

그러다 호기심이 생겨 하이엔드 키보드에 대해 더 찾아보기 시작했다. 깨어 있는 시간 대부분을 키보드 앞에서 보내니, 경험을 최적화하는 데 투자할 만하다는 생각이 들었다.

Kinesis, Ergodox, ZSA 등 몇 가지 옵션을 살펴본 끝에 Kinesis Advantage 360을 선택했다.

최근 갈아탄 Kinesis Advantage 360 키보드.

키보드를 처음 쓴 첫날은 정말 힘들었다. 평소 타자 속도의 5% 정도밖에 나오지 않았다. 처리해야 할 서류가 많아서 다음 날 아침까지 키보드를 치워 두었다.

둘째 날은 좀 나아졌지만 여전히 어려웠다. 계속 사용하다 보니 이제 영어 문장을 쓸 때는 이 키보드가 더 빠르지만, 프로그래밍할 때는 더 느리다. 이 키보드에서 [, {, = 같은 문자에 아직 익숙해지지 않았다. 쉽게 쓰려고 키를 리매핑까지 했지만 여전히 손에 익히는 중이다.

Kinesis에 익숙해지면 일반 키보드로 다시 전환해도 문제없다는 후기를 본 적이 있는데, 내 경험은 그렇지 않았다. Surface Pro 6의 좁은 노트북 키보드로 바꾸면 오타가 엄청나게 많이 난다. 언젠가는 두 키보드 모두 편하게 쓸 수 있게 될지도 모른다.

60일 환불 기간이 있지만, 지금으로서는 Kinesis를 계속 쓸 것 같다.

마무리

무엇을 해냈나?

  • 외주 제조업체가 만든 TinyPilot Voyager 2a 기기의 첫 배치를 출하했다.
  • TinyPilot 릴리스 과정에서 수작업을 없앴다.
  • 기계식 키보드로 갈아탔다.

배운 점

  • 제조업체의 약속을 더 적극적으로 추적하기
    • 이전에도 저지른 실수인데 제대로 해결하지 않았다.
    • microSD 문제는 제조업체가 무언가를 하겠다고 약속하고 나는 그들이 처리하고 있다고 가정하다가, 둘 다 잊어버리고 결국 문제가 생기는 패턴을 반복한 것이다.
    • 약속한 내용을 기록하고 혹시 잊을 경우를 대비해 매주 진행 상황을 점검해야 한다.
  • BOM을 구성 요소별로 일일이 대조하기
    • 제조업체가 몇 달 전 자재 명세서를 보내왔을 때 나는 머릿속으로 기대한 항목만 확인했고, microSD가 빠져 있다는 걸 놓쳤다.
    • 앞으로 BOM 합의 과정을 거칠 때는 기존 제품을 분해해 모든 구성 요소를 목록화한 뒤 제조업체의 BOM과 일치하는지 검증할 것이다.

다음 달 목표

  • 외주 제조업체로의 생산 이전을 최대한 빠르게 완료하기.
  • 고객 아웃리치 통화 5건 진행하기.
  • TinyPilot 사무실의 모든 구 재고와 예비 부품을 정리하기.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글