2025년 9월 10일 수요일

코드가 법이다, 그 후

"옥주현, 수년간 소속사 불법 운영···형사처벌 대상"이라는 제목의 기사를 접했다. "대중문화예술산업발전법상 법인과 1인 초과 개인사업자로 활동하고 있는 연예인은 대중문화예술기획업으로 등록해 활동해야 한다. 이는 필수적 법적 요건으로 위반할 시 형사 처벌을 포함한 법적 제재를 받는다."고 하여, 법령상 특정 업종으로 등록해야 하는데 누락했으니 '불법 운영'이라는 내용이었다. 기사에는 실수로 누락했다는 해명이 있었다. 나는 이 해명이 맞고 기사가 악의적으로 나왔다고 짐작한다.

 

대한민국 법령 체계가 어떤 국가적 개념들이 모인 단일한 뿌리에서 자라나는 게 아니라 실무 주체인 주무기관이 있고 그 주무기관 산하에 소관법령이라는 형태로 나열된다는 걸 깨닫고 놀랐었다. (예: 산림청 소관법령) 그리고 각 주무기관은 자기 사업을 각자 영위하고 거기에 필요한 법률을 각자 정부입법으로 만들어낸다. (중간과정 매우 생략 주의) 이 과정에서 개념적으로는 인접한데 소관이 갈리는 경우가 생기면서 일반인이 보기엔 이상한 경우도 생긴다. (예: 화재는 소방청 소관이지만 산불은 산림청 주관이고 소방청은 협조)

 

이 때문에 일반 시민들은 시시 때때로 바뀌는 법령을 잘 따라가지 못하고 때로는 '담당 공무원이 나보다 몰라서 관련 규정 차근차근 알려줘야 했다' (예: 캐스퍼 전기차는 경차 아니고 소형차여서 취득세 부과) 류의 경험담이 종종 보인다. 일상생활에 밀접한 세법, 건축법, 소방법 같은 건 각 분야 전문가가 업무적인 고도의 전문성과 함께 법령을 꾸준히 따라가는  전문성도 구비해야 한다.

이 상황에서 공무원을 욕하고 다그친다고 상황이 나아질 것 같지도 않다. 이미 일선 공무원은 주먹구구식으로 업무를 분장하고 혹은 그마저도 잘 지켜지지 않고 한쪽으로 쏠려서 부담을 느껴 면직하거나 목숨을 끊거나 하고, 순환 보직으로 계속 바뀌는 와중에 인수인계라는 게 존재하지 않아서 계속 새 사람이 전혀 모르는 일을 떠맡는다고 한다.

 

나는 옥주현의 소속사도 행정 절차 중 하나를 누락했을 뿐이고 억울한 입장이라고 이해했으므로, 이렇게 억울한 상황이 어떻게 생겼는지 그리고 어떻게 하면 앞으로는 생기지 않을지 궁금했다. 그래서 ChatGPT를 열어서 물어보았다. 다음은 내가 입력한 질의들이고 수정이나 재시도는 없이 한 번에 쭉 진행되었다.

  1.  https://m.entertain.naver.com/home/article/144/0001066309 이 기사를 읽을 수 있나?
  2.  좋아. 나는 실수로 누락했다는 주장이 그럴듯하다고 생각해. 그래서 https://law.go.kr 에서 정보를 찾아봤지. 아래 URL은 검색 결과 페이지야. https://law.go.kr/lsBylSc.do?menuId=9&subMenuId=55&tabMenuId=261&query=%EB%8C%80%EC%A4%91%EB%AC%B8%ED%99%94%EC%98%88%EC%88%A0%EA%B8%B0%ED%9A%8D%EC%97%85#liBgcolor2 https://law.go.kr/LSW/aai/searchList.do?query=%EB%8C%80%EC%A4%91%EB%AC%B8%ED%99%94%EC%98%88%EC%88%A0%EA%B8%B0%ED%9A%8D%EC%97%85&pageNum=1&pagePer=10&searchType=1&modelYn=N&indexNames=&version=&ignoreWord=&keywordSearchYn=N&searchResultLsKndCd=0&firstSearchKeyword=&preSearchKeyword=&searchKndCd=0&mainType=main&detailSearchYn=N&lsChapCd=&lsKndCd=&upCptOfiCd=&cptOfiCd=&startAncYd=&endAncYd=&startEfYd=&endEfYd=&startPrmlYd=&endPrmlYd=&startAdmRulEfYd=&endAdmRulEfYd=&sortCode=0&bylClsCd=&chk= 검색 결과를 보면 일단 법률 수준에서 바로 대중문화예술기획업이라는 키워드가 나오지는 않는 것 같아. 법률 하위의 시행령이나 규칙 같은 걸로 내려가야 실질적인 용어로 검색이 되고. 여기서 내가 너한테 요청하고 싶은 건, 대중문화예술기획업 같은 업종을 등록하는 행정절차가 필요하다는 걸 당사자 시민이 알려면 어떤 문서들을 어떻게 파악해야 하는 건지 니가 심층적으로 검토해줬으면 해.
  3.  너는 애초에 저런 법이 있고, 저런 업종에 대한 등록 의무가 있으리란 걸 인지한 사람을 전제로 하고 그 이후의 실무 절차를 설명하고 있다고 이해했어. 내가 궁금한 건 애초에 저런 법이 있어서 따라야 한다는 사실 자체를 시민 당사자가 어떻게 예상할 수 있냐는 거야. 바꿔 말하면 내가 하고자 하는 행위가 행정적으로 그리고 법적으로 어떤 의미가 있고 어떤 법률에 영향을 받는지 어떻게 알 수 있지?
  4.  좋아. 내가 질문한 방향에 맞게 답이 된 것 같아. 하지만 결국 1) 일반인은 알기 어려운 게 사실이고 2) 정부에서 잘 알려줘야 하고 3) 누락은 여전히 생길 수 밖에 없다 ...라는 거잖아? 니가 정리는 잘 했지만 결국 실상은 매우 실망스럽네. 그럼 가급적 최신 연구나 세계 각국의 실험적 행정을 검색해서 이 점을 개선하려는 시도가 있었는지 봐줄 수 있나?
  5.  다음 단계로 제시된 3가지 중에서 2와 3을 볼 수 있으면 좋겠네.
  6. B를 해줘. A는 B가 끝난 다음에 진행할지 판단할 테니까 다시 물어봐줘.
  7.  B의 결과는 기대보다 미흡하네. A를 보여줘.
  8.  1,2 모두 지금 관심사는 아니야. 오히려 궁금한 건, 위의 yaml을 원래의 법령에서 추출할 때 각 조항을 어떤 문법에 따라 분석하고 yaml로 추출할 조항과 무시할 조항을 선택했는지야.
  9. 좋아. 실제 원문에서 추출한 yaml을 보여줘. 
  10. 명확한 패턴이 있는 조문에서 if-then-else를 뽑아냈다는 건 이해했고 결과도 좋아 보여. 그럼 반대로 원문에는 있지만 yaml 추출에 사용되지 않은 조항이 유의미한 정보를 담고 있는지 경우를 파악할 수 있을까? 그러니까 다시 말하면 yaml에 충분한 규정이 담기지 못하는 경우를 막을 수 있을까? 
  11. 좋아. yaml에 없는 보조 정보가 어떻게 정리되는지 예시를 보여줘.
  12. (이 뒤에 변환 코드까지 달라고 해봤지만 매우 단순한 문자열 감지뿐이어서 참고는 되지 않음) 

 

ChatGPT에 적힌 내용을 모두 신뢰하는 건 아니고 큰 틀에서 어떤 키워드가 있는지만 본다면 Rule as Code (RaC)가 가장 그럴듯하다. 이걸로 검색을 해보면 OECD 문서가 나오기도 해서 시중에 진짜로 쓰이는 용어인 것 같다.

개념 자체는 이미 알고 있다. 2006년 출판, 2009년 한국에 번역된 로렌스 레식의 코드 2.0을 당시에 읽었고 그 전에 나왔던 저작들도 접했었다. 또한 오픈소스 동네에서 지내며 실생활에 프로그램이 어떤 영향을 끼치는지도 체감했기 때문에 매일매일 변동증감하는 코드가 그 자체로 곧 규정으로 기능한다는 개념도 쉽게 수용했다. 아마 영어권 화자라면 code라는 말 자체를 프로그램과 규정으로 구분해서 받아들일 필요 없이 그냥 중의적인 표현으로 보았겠지.

ChatGPT와의 대화가 끝으로 가면서는 실제 법률을 어떻게 코드화는지 사례를 보여주기에, 개별 사례보다는 코드화 그 자체의 원리나 패턴을 물었고, 실제 문언에서 if-then-else를 어떻게 뽑아내었는지 설명이 제시되었다. 애초에 법령 자체가 코드라면 이런 변환 과정 자체가 없어도 되고 문맥에 따라 해석이 달라질 수 있는 경우도 더 적을 것이다.

 

코드가 법이란 건 알고 있다. 다음은 법률이 코드여야 한다의 순서인가? 

리눅스에서 지문 인증이 된다고?

예전처럼 리눅스 커널 메일링리스트를 받아보는 건 아니지만 M1에 아사히 리눅스를 깔아서 쓰고 있기도 하고 2025년 여름 즈음으로 어쩐지 커널 버전업이 활발하기도 해서 종종 이런저런 채널로 커널 소식을 접할 때가 있고 마침 유튜브에 이번 주의 그런 영상이 떠서 보았다.

 

https://github.com/xapp-project/fingwit

민트 리눅스라는 배포판에서 위 프로젝트를 기본 내장해서 지문 인식을 도입한다는 모양이다. 민트를 쓰지는 않다보니 바로 확인해볼 수는 없겠다.

기왕 M1에 리눅스를 깔아서 쓰고 있기도 하고 이미 터치ID 딸린 애플 키보드를 하나 가지고 있기도 해서 (맥미니도 그렇고, 맥북도 조개 모양으로 닫아놓고 쓸 때는 외장 키보드에 지문 인식이 붙은 게 좋긴 좋다), 당연히 저 프로젝트 주변으로 터치ID 키워드가 존재할 거라고 생각했다.

 

linux "fprintd" apple touch id -site:apple.com

하지만 놀랍게도 fingwit으로는 전혀 나오는 게 없고, 더 하위의 fprintd로 찾아보니 좀 나오는 게 있다.

https://www.reddit.com/r/archlinux/comments/1mc7wup/touch_id_with_hyprland/?tl=ko

https://itsfoss.com/fingerprint-login-ubuntu/

아마 fingwit 말고도 이미 기존 구현체들이 있어서 우분투 그놈에서는 바로 설정 가능한 모양이다. 적어도 스크린샷으로 보이는 건 그렇다. 민트는 개중 새롭고 가볍고 뭐 그런 구현체를 채택한 거겠지.

 

이렇게 되면 아사히 리눅스 동네에서 fprintd 어쩌구 하는 얘기가 많지 않은 게 오히려 이상하게 느껴진다. 리눅스를 쓰는 집단들 중에 지문 인식기 달린 장치를 보유했을 가능성이 가장 높을 것 같은데. 

2025년 9월 1일 월요일

큰 화면으로 전자책을 보기 위한 모험

주로 전자책에서 TTS를 켜서 귀로 듣는 편이다. 종이책을 직접 다 보기엔 눈도 피곤하고 금방 집중력도 떨어지곤 해서다. 전에는 교보문고 전자도서관 등에서 자치단체 공공도서관을 통해 읽곤 했는데 얼마 전에 밀리의 서재에서 AI TTS라는 게 나와서 목소리 품질이 꽤 좋아져 만족스럽다.

그렇다고 아예 화면을 안 볼 수도 없는 게, TTS가 읽어준 게 억양과 발음이 모호해서 무슨 말인지 직접 봐야 한다거나 앞에서 무슨 말을 했길래 이 대목이 이렇게 된 건지 다시 봐야 한다거나 가끔은 정말 눈으로 직접 보고 싶은 인상적인 대목도 있거나 등등 여러 경우가 있다. 거대한 확대경이 붙은 자동 발화 독서대 같은 거랄까.

 

하지만 전자책 시장의 DRM 정책은 이 과정을 거의 불가능하게 만든다. 안드로이드 기기에서 크롬캐스트를 통해 화면을 공유하면 전자책은 그냥 검게만 나온다. 전자책 화면은 DRM 기술로 제한되어서 다른 기기로 전송할 수 없다는 게 그 이유다.

그래서 방법을 찾다가 결국 안드로이드 기기 자체가 DP Alt로 외부 모니터 출력을 지원하기도 한다는 걸 알았다. 이 기능이 들어가면 기기 가격이 꽤 비싸져서 결국 2025년 하반기인 현재에 2023년 출시 기기를 중고로 사야했다. Y700 2세대.

 

드디어 큰 화면으로 볼 수 있게 되었다. 하지만 노트북에 외장 모니터를 연결하는 거랑은 차원이 달랐다. 안드로이드 기기에 USB-C 케이블로 모니터를 연결하면 그 전의 해상도 설정은 사라지고 무조건 그 모니터가 지원하는 최대 해상도로 설정되었다. 4K 모니터이기 때문에 FHD로 다시 바꿔야 글자를 눈으로 따라읽을 수 있는 정도가 된다. 모니터를 뺐다가 다시 꽂을 때도 그리고 해상도를 바꿀 때도 아마 이 기기는 디스플레이 공간을 완전히 새로 구성하는 것인지 거기에 떠 있는 앱은 몽땅 초기 상태로 되돌아간다. 손이 많이 간다. 2023년 구세대 기기라 그런 건가 하는 생각도 들긴 하는데 OS가 나름 최신이니 그런 문제는 아니겠지.

USB-C로 연결한 뒤에 오디오 출력도 약간 곤란한 문제가 있었다. 기본적으로는 안드로이드 기기 자체 스피커로 소리를 내거나 연결된 모니터 스피커로 소리 내는 선택지가 있는데 나는 이미 그 모니터는 크롬캐스트 기기에 연결하면서 저품질 내장 스피커는 음소거로 바꾼 상태라 모니터로는 소리가 나지 않는다. 얼마 전 가구 배치를 새로 정리하면서 스피커에 입력 포트를 다 써버려서 더 뭘 어떻게 하기도 어렵다. 결국 이미 스피커에 물린 리눅스 장치에서 블루투스 오디오 프로파일을 활성화해서 안드로이드가 블루투스로 소리를 보내면 블루투스 신호를 받은 리눅스가 거기 물린 스피커선으로 소리를 다시 보내는 식으로 일단 정리를 했다.


여기까지만 해도 이미 꽤 번거로운데 밀리의 서재 앱이 한결 더 상황을 곤란하게 만든다. 교보문서 전자도서관 앱이나 교보문서 e북 앱은 안 그런데, 밀리의 서재는 외부 모니터로 띄워두고 TTS를 재생한 상태에서 블루투스로 연결했던 마우스를 연결 해제하면 TTS 재생이 멈춘다. (외부 모니터 없을 때는 멈추지도 않는다) 모니터를 연결하고 나면 기기 본 화면을 터치패드 모드로 바꾸는 기능이 있긴 하지만 마우스랑은 편리함이 완전 다르기 때문에 가급적 마우스를 쓰고 싶었을 뿐인데. (로지텍 마우스라서 연결된 3가지 기기 중에서 잠깐 바꾸면 되는 수준이다)

그래서 이걸 밀리의 서재에 1:1 문의로 넣었더니 '블루투스 기기에 대한 최적화가 진행되지 않았다'고 질문 내용에 대해서는 한 문장으로 답변을 마치고 그 뒤에 이어지는 문장들은 '외부 화면은 차단하고 있는데 왜 그게 된다는지 모르겠고 아마 그 자체가 에러' 운운으로 길게 이어진다. '너 혹시 나의 소중한 DRM을 깨뿌순 거니??' 하는 붉고 굵은 글자가 눈에 보이는 것만 같았다. 어쩌면 다음 밀리앱 업데이트에는 아예 DP Alt 안에서도 못 쓰게 되는 건가 괜히 무서울 따름이다.

'큰 화면으로 보려는 수요가 있다는 걸 무시'하지 말아달라고 다시 답을 달았다. 당신의 눈이 언제까지나 작은 화면의 작은 글씨를 감당해낼 수 있을 거라 장담하지 말라.

2025년 8월 26일 화요일

python with 문법이 js using 문법으로

시간이 좀 지나 MDN을 다시 보니 Node.js 24부터 지원한다고 되어 있다. 

 

---

이런저런 프로그래밍 언어들의 파편을 구경하면서 유용하다고 생각했던 것들이 몇 가지 있다.

파이썬의 with 문법도 그 중 하나다.

(검색을 더 해보니 C#에도 똑같은 용도로 using이 있나보다. https://onepredict.github.io/using-keyword/#%EC%84%A0%ED%96%89-%EA%B8%B0%EC%88%A0 )

 

https://www.geeksforgeeks.org/python/with-statement-in-python/

with open("example.txt", "r") as file:
    content = file.read()
    print(content)  # File closes automatically

이렇게 한 블럭 안에서만 쓰고 버릴 변수를 만들어준다. 

직선적인 흐름에서는 열고 닫는 게 자연스럽지만 early return 같은 경우에는 그 앞에 만들었던 이런저런 연결을 닫아준다던지 하는 작업 때문에 return 앞부분이 번잡해지는 경우가 생기는데 그럴 때 유용할 것이다. 

 

PHP는 이런 게 없는 걸로 알고,

js는 with 문법 자체는 있지만 as 변수명으로 이름을 명시하지 않고 그 블럭 안에서 this를 대체하는 방식이어서 여러 단점이 있고 MDN에도 비추라고 구분되어 있다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with

 

그래서 js에 블럭 안에서만 유효한 let이 생긴 뒤로는 따로 블럭만 하나 열어서 그 안에 let으로 변수를 만들어주는 식으로 가끔 썼던 기억이 있다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let

  

그러다 using 문법이 들어온 걸 알게 되었다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using

https://github.com/tc39/proposal-explicit-resource-management

typescript에서는 이미 몇 년이 넘은 제안이다. MDN 문서 기준으로 Node.js는 지원을 안 하지만 다른 브라우저들은 지원하는 게 이유가 있었다.

 

https://deno.com/blog/updates-from-tc39#explicit-resource-management-using

https://deno.com/blog/v2.3#explicit-resource-management-and-the-using-keyword 

Deno에서는 2.3 버전부터 지원했다고 한다. 2025년 4월 말에 발표된 버전이니까 여기도 지원이 아주 오래된 건 아니다.

Node.js에도 곧 반영이 되면 좋겠다.

2025년 8월 22일 금요일

발 달린 가구 대통합

평면도에서 자리를 차지하는 가구를 4개에서 2개로 줄이려고 작업중이다.

 

우선 튼튼한 선반을 들여서 벽 한 면을 바닥부터 천장까지 다 쓸 수 있게 수납 공간을 만들고 컴퓨터 관련 장비들을 몰아넣고 모니터 위로 책도 밀어넣었다.

거실장 tv장 에어컨장 거실수납장 티비장식장 티비대 오픈장 거실책장 우드인테리어 - 한솔홈 

모양은 다르지만 이 구도랑 비슷하겠다.

 

이것만 해도 장점은 뚜렷하다. 책장이 따로 있을 때는 어쩐지 눈길을 많이 타지 않아서 먼지만 쌓여가는 쓸쓸한 공간이었는데 지금은 어쨌든 가장 오래 시야가 닿는 방향이 책도 같이 있다보니 책에 시야가 더 간다.

스피커도 기존에는 선을 최대한 길게 써서 공간 전체의 좌우에 두었는데 이번에 저 사진과 비슷하게 모니터 좌우로 배치를 바꿨고 스피커가 허용하는 입력단자를 총동원해서 3개 장치의 입력을 한 번에 틀어둘 수 있게 정리했다. AUX선에서 잡음이 실릴까 걱정했는데 아예 없진 않지만 평소에 인지하지 못할 정도여서 다행히도 문제없이 일단락 지었다. 

그리고 모니터 앞쪽으로는 원래 책상으로 쓰던 테이블에서 상판만 뜯어내서 아래 위 모두 접을 수 있게 경첩을 달았다. 평면도 상의 공간 차지를 가급적 줄이려던 거라 이 단계가 필수였다. 원래 계획하던 공정은 다 적용했지만 편의성이 좀 아쉬운 부분들이 있어서 나중에 쿨타임 차면 다시 손댈 것 같다. 

 

한편으로는 잡동사니 수납장을 새로 정립해야 한다. 그동안은 이런저런 자잘한 물건들이 쌓이면 무턱대고 버리지는 못하고 박스에 차곡차곡 모아두곤 했는데 1x년째 그러고 있다보니 그런 박스들도 꽤 모여버렸다. 종종 버릴 건 버린다지만 수납 자체도 다시 생각해볼 때가 되었다.

책장이 있던, 눈에 덜 띄고 발길도 덜 가는 공간으로 수납장을 밀어넣고 거기에 이것저것 소코반을 해야 한다.

 

전에 쓰던 책장은 나무 합판을 간단하게 조립한 물건인데 이번에 다 해체해버렸다. 원래는 이사 자주 다닐 때 매번 책을 책장에서 꺼내고 묶고 풀고 다시 넣는 과정을 하지 않으려고 큰 책장 대신 작은 책장을 여러 개 올려서 썼는데 이젠 종이책 자체를 버리면 버렸지 더 늘릴 생각은 없으니 나무 조립식 책장도 버릴 때가 되었다.

풀어낸 합판들은 원래 계획으로는 수납장에 덧대서 나무 느낌을 내볼까 하는 생각도 있었는데 그러기엔 손도 더 가고 나무색과 벽색이 잘 맞을지도 의문이라 버리는 쪽으로 기울고 있다.

2025년 8월 12일 화요일

영상 분석을 AI가 이렇게 잘 해주면

영상 분석이 필요한 개인 프로젝트를 구상한지 오래 되었다. 완결된 뭔가가 나온 적은 없지만 그동안 꾸준히, 자전거로 치자면 뒷바퀴 바퀴살은 무슨 재질로 몇 개나 붙여야 주행에 좋을지, 체인은 어느 정도 팽팽해야 하는지, 핸들은 평평해야 할지 구부려야 할지, 혹시 앞바구니를 당장은 아니지만 나중에는 붙이고 싶은데 미래를 위해 프레임 모양을 어떻게 만들어야 할지 부분부분 구상과 기술 검토는 해왔다.

 

영상 분석에서 초반에 문제가 됐던 건 결국 그 정확도였다. 흥미로 하는 개인 프로젝트고 다뤄야할 영상이 폭발적으로 늘지는 않기 때문에 속도는 크게 중요하지 않았다. 초기에는 TensorFlow에 있는 이미지 분류 같은 걸 돌려서 거기서 나온 텍스트 더미로 그 다음 단계를 어떻게 해야 하나 궁리하는 정도였다. 텍스트 결과물이 만족스럽거나 하진 않았지만 어쨌든 일단 다음 진행단계를 밟아야 유의미한 진척이 생기기 때문에 한 눈 질끈 감고 정확도가 낮으면 나중에 다시 돌아보자고 생각했었다.

그리고 얼마 전 드디어 (나로서는) 놀라운 결과물을 내주는 도구를 찾았다. AI 모델을 로컬에서 실행해주는 ollama에 qwen25vl:7b 모델을 붙여서 일련의 이미지를 먹이면 내가 얻고자 했던 이미지의 특성들을 착착 뽑아준다. 이 비전 모델을 실행하려면 갖춰야될 GPU 메모리 크기가 약간 장벽이지만 원하는 결과물이 나오는 이상 그 정도는 문제가 안 된다.

ollama를 처음 접했을 때 느꼈던 가능성, AI 관련 각종 기술과 용어들을 따라가지 못해서 어쩌지 하는 막막함이 ollama 같은 걸 그냥 블랙박스로 두고 그동안 쭉 해왔던 것처럼 API로 호출해서 잘 활용해주면 업무 현장에 여전히 내 역할이 있겠구나 하는 납득으로 바뀐 그 느낌이 이번에도 비슷하게 온다. 이거라면 예전에 텍스트까지만 수작업으로 직접 구현하고 이미지는 적당한 검사 서비스 제공자를 못 찾아서 결국 포기했던 성인물 검사도 상당한 수준으로 만들어낼 수 있을 것 같다.

 

물론 모든 난관이 한방에 해소된 건 아니다. 영상 분석의 앞뒤로 이어져야 할 프레임 추출 등의 작업들을 위해 MCP를 활용하려고 찾아봤는데 비전 모델이 MCP 연동까지 지원하지 않기도 하고, 요즘 추세가 여러 모델을 혼합해서 쓴다고도 하고, 아예 A2A라고 기능 단위의 에이전트들끼리 통신하는 게 필요하다고도 한다. 아주 단순화해서 이해하자면 사람이 수동으로 하는 걸 MCP라는 이름으로 모델에서 넘기고 필요하면 IPC 같은 게 되게 한다는 거다. 그럴듯하게 들리긴 하는데 아직 필수라고 느껴지진 않아서 일단 수동으로 때워야 할 부분 같다.

또 ollama는 임베딩 기능을 텍스트에만 지원해서 영상으로 다른 비슷한 영상을 찾게 하는 건 다른 구현을 통해야 할 것 같다. ollama 같이 모델 돌려주는 역할을 하는 다른 동네에서는 된다는 얘기가 보이니 찾아보면 해결은 될 것 같다.

2025년 5월 4일 일요일

ZFSBootMenu로 ZFS 안의 우분투를 부팅하다가 zpool upgrade로 feature를 추가해버렸다

그리고 다음번 부팅 때 ZBM은 미지원 기능이 있어서 zpool을 읽어줄 수 없다며 진행을 멈췄다.

 

zpool upgrade를 되돌릴 수 있는지 가장 먼저 찾아봤지만 안 된다는 답만 나왔고 논리적으로 생각해봐도 이미 파일시스템 내부구조가 바뀌었을 테니 되돌리는 게 말이 안 되는 얘기였다.

 

다음으로는 zfsbootmenu github에 찾아가고 IRC도 들어가봤지만 너무 조용했다. 나한테 나타난 증상이면 전세계 ZBM 사용자 중에서 못 해도 천 명 정도는 겪었을 증상일 텐데. IRC도 입장하고 몇 시간 가만히 있어봤지만 그 어떤 대화도 일어나지 않았다. ZFS를 쓰고 그 중에서도 ZBM으로 부팅을 할 정도라면 고인물 중에서도 소수라는 얘기겠지.

 

https://github.com/zbm-dev/zfsbootmenu/issues/624 실제로 같은 경우가 며칠 앞서서 등록되어 있었다. 하지만 '배포되는 ZBM 쓸 거면 너무 앞서가는 feature는 쓰지 마시고, 최신 feature를 쓸 거면 ZBM을 빌드하세요' 라는 답이 끝이었다.

빌드 방법을 여기저기 찾아봤지만 딱히 친절하게 나와있지도 않았다. 공식 웹사이트에 몇 가지 따라하기 문서들이 있었지만 친절하기보다는 '시범은 한 번만 보여준다' 느낌으로 전후과정 설명 없이 진행만 쭉쭉 나가는 것들이 대부분.

 

친절함을 기대하는 건 그만 접고, 예전에 이것저것 멘땅에 헤딩하던 가락을 살려서 git clone 후에 몇 가지 만져보니 겨우 느낌이 왔다. (2일 경과)

빌드는 podman나 docker 안에서 이루어진다. ZBM 자체가 작은 리눅스임을 강조하고 있기도 하고, ZFS 같은 거 모르는 UEFI 다음에 등장해서 ZFS를 인식해서 ZFS 안쪽으로 부팅 절차를 넘겨주는 역할인만큼 여느 앱처럼 컨테이너 안에서 빌드가 가능한 모양이었다. (IRC 채널 주제에 적힌 설명을 보면 무려 '쉘 스크립트로!')

기반이 되는 이미지를 만들 때 커널은 요즘 버전인 6.12, 6.14 등을 지정할 수 있었고, zfs 커널은 따로 지정하지 않았지만 2.3.1 최신으로 모듈 빌드가 들어갔다. 처음엔 우분투 버전에 맞춰 6.14를 지정했지만 dkms ZFS 빌드가 실패했고 6.12로 바꾸니 다행히 빌드가 됐다.

이미지를 만든 다음에는 ZBM 파일을 만들면 되고, 만들어진 vmlinuz.EFI 파일을 USB의 EFI 아래에 복사하고 efibootmgr 명령을 다시 실행해주면 ZFS로 정상 부팅이 진행된다.

 

아래는 사용한 명령들이고, 우분투 25.04 라이브를 사용했다. 처음엔 라이브 환경으로는 부팅마다 초기화가 되어버려서 이미 구성되어 있던 Fedora Asahi Remix에서 실행했는데 이미지 생성 때 amd64가 아니라 arm64로 잡혀서 경고가 난다. 빌드 단계에서 arch를 지정할 수도 있었겠지만 그냥 얌전히 amd64 환경으로 옮겨갔다.

sudo apt install git podman -y

git clone https://github.com/zbm-dev/zfsbootmenu.git

cd zfsbootmenu

sudo releng/docker/image-build.sh -k 6.12 rescue

sudo ./zbm-builder.sh -i rescue

efibootmgr -c -d "$BOOT_DISK" -p "$BOOT_PART" \
  -L "ZFSBootMenu (Backup)" \
  -l '\EFI\ZBM\VMLINUZ-BACKUP.EFI'

efibootmgr -c -d "$BOOT_DISK" -p "$BOOT_PART" \
  -L "ZFSBootMenu" \
  -l '\EFI\ZBM\VMLINUZ.EFI'


2025년 3월 5일 수요일

[병명검열] 입원수술 후기

나는 어제 세 분의 신을 뵈었으며
그 이름은 진통제 항생제 마취제이시다.
 
 
---
장애인 재활은 진짜 엄청난 의지의 산물이다.
나는 하반신 마취 잠깐으로 두어 시간 안에 감각이 돌아오기 시작해서 몇 시간 안에 마취가 다 풀렸고, 그 과정에서 분홍소세지 덩어리가 내 몸에 달린 살덩어리가 됐다가 내 다리인데 잘 안 움직였다가 어느 새 그냥 내 몸이 되어있는 진척을 겪었다.
이 진척을 어떤 보장도 없이 오직 하면된다는 의지로 일궈낸다는 게 더없이 대단하게 느껴졌다.

2025년 2월 20일 목요일

8개월이 지난 회고

https://blog.keizie.net/2024/06/another-postmortem.html 에 이어.
 
 
다니던 회사가 폐업으로 끝나고 나라가 주는 월급으로 2개월 정도를 지내다가 한 곳에 딱 한 달, 다른 곳에 두 달 좀 넘게 다니며 새해를 지나 연말정산까지 진행했다.
 
 
1. 해온 일
  • 개발조직이 주가 아닌 업체 두 곳에서 개발조직을 자리잡게 하는 목표였다. 세부적으로는 도메인이 달라서 업무도 약간 달랐지만. 결과적으론 두 번 모두 실패했다. 세상엔 비기술 인력이 훨씬훨씬 많음을 새삼 느꼈다.
  • 한 곳은 이미 있는 개발팀의 팀장이 개발문화에 발담은 적 없이 스스로 바닥부터 공부를 해서 코드를 짠 사람이라, 출근해보니 깃허브에 올라와 있지 않은 소스코드가 꽤 많은 상황이었고 팀원이 소스코드를 확인 못하고 업무지시만 받아서 작업을 했다고 한다. 회사에서는 공통된 팀 단위의 기록 공간이 없이 저마다 개인 노션을 만들고 몇몇 사람들만 공유를 해서 돌려보는 식이었다. 지난 작업들이 있다고는 하는데 코드도 문서도 볼 수 없는 상황을 해소하느라 시간을 꽤 썼다. 무엇보다 놀란 건 메일이 구글 워크스페이스가 아니라 생전 처음 들어보는 메일 포함 사무 서비스 몇 가지를 제공하는 업체였다는 것이다. 특히 메일은 '구글 로그인' 기능이 있는 곳을 회사 구글 계정으로 바로 쓸 수 없다는 점이 너무나도 불편했고 어색했다.
  • 다음 곳은 상주 개발팀장이 없이 한동안 신입 개발자만 뽑아서 사장이 직접 이것저것 요구사항을 전달하고 쪼아가며 일을 하다가 사장 지인을 리모트 팀장역으로 뒀다가 이번에 처음 상주 팀장이 들어앉은 거였다. 공동대표 체제이기도 했는데 예전에 다른 회사에서 잠깐 맛봤던 것처럼 이번에도 좋은 결과는 아니었다. 업무 지시가 구두로 들어오고 시시각각 새로 쌓이거나 바뀌는 게 너무나도 큰 문제였는데 이걸 어떻게든 개선하려고 시도했지만 최상위에서 업무를 발생시키는 사장이 끊임없이 외부 영업을 도느라 내부에 시간을 할애하기 힘든 상황이 바뀌지 않는 한 업무지시가 짧고 단편적이고 부정확할 수 밖에 없음을 절감했다. 몇 번의 퇴사 면접 때 여러 차례 이 점을 얘기했는데 얼마나 전달이 됐을지는 모르겠다.
  • 주니어 교육을 좀 더 진지하게 생각하게 되었다. 두 번째 회사가 팀장 없이 '방치된' 기간이 길다 보니 에러가 났는데 무슨 에러인지 확인하지도 않고 아무 코드나 의심되는 부분을 냅다 고치려고 한다든지, 기본적인 기술 용어는 들어본 적도 없이 그저 결과물이 나오도록 프레임워크 영역 안에서 부품 코드만 짜넣는다든지 하는 모습을 보았다. 물론 초년차가 뭐 대단한 바탕이 없는 게 당연한 거지만 당장 눈에 보이는 것 이상의 뭔가가 있다는 걸 생각조차 하지 못하는 게 너무나도 안타까웠다. 기회가 될 때마다 어떤 기술이 현재에 이르기까지 어떤 연원이 있었는지, 연관되는 키워드들은 뭔지를 설명해주고자 애썼다. 나로서는 드물게도 주말 오전에 시간을 내어 강사 노릇을 하려고도 했지만 이건 몇 번 못하고 끝나버려 아쉽다.
  • 하나의 주제를 잡아 직접 해결하기보다는 전반적으로 뭐가 문제인지 확인까지만 하고 저연차가 이해할 수 있는 수준으로 설명하고 어디를 어떻게 손대라고 지시하는 전처리 단계 위주로 진행했던 것 같다. 그럴 수 밖에 없는 여건이었던 게 가장 큰 이유고, 주니어의 성장에도 이 편이 유리하다고 생각했다. 예전 회사의 돌파력 있던 팀원들이 아쉽기는 했지만.
 
2. 다뤄본 것
  • 두 회사 모두 비용은 덜 들이면서 적절한 시스템을 구성한다는 목표는 비슷했다. 한 쪽은 이미 다들 노션을 편하게 쓰고 있던 터라 노션을 팀 단위로 바꾸면서 돈을 썼다. 지라에 해당하는 건 슬랙의 리스트 기능부터 깃허브 이슈까지 다양하게 검토했지만 뚜렷하게 결론을 못 냈던 걸로 기억한다. 다른 쪽은 개인들은 노션을 쓰고 있었지만 회사로는 활발하지 않아도 지라와 컨플루언스를 이미 도입해둔 상황이어서 무료 10명 선에서 유지하며 유료로 넘기지 않기 위해 노력했다. (한번은 어쩌다 11명째 가입자가 생긴 상태로 시험판 기간이 지나서 갑자기 사용이 제한되는 바람에 얼른 10명으로 다시 맞추고 기술지원을 요청해서 되살린 적도 있었다)
  • EC2 안에 docker로 떠 있는 구조를 ECS Fargate로 바꾸고 AWS X-Ray도 붙이는 작업을 했다. 비용 절감을 위해서였는데 다음달 비용이 나오는 걸 확인 못해서 결과를 못 본 게 아쉽다. ECS 전환 자체보다는 ECR+ECS 기반으로 Github Actions 자동 배포 스크립트를 짜고 슬랙에 결과를 보여주는 구성을 하는 게 더 오래 걸렸다. Self-hosted Runner를 도입했으면 좀 더 간단해졌을 것 같기도 한데 다음에 기회가 닿으면 시도해봐야겠다.
  • https://tailscale.com/kb/1019/subnets Tailscale로 서브넷 라우터를 실제로 구성해봤다. 그동안은 매번 ssh 터널을 구성했는데 이번엔 그렇게 각자 터널을 다 세팅하게 만들도록 ssh 터널링의 개념을 설명하고 교육하는 것조차 부담으로 느껴져서 Tailscale 앱만 깔게 하면 이게 차라리 쉽다고 생각하고 시작했다. 하지만 의외로 윈도우 환경에서는 Tailscale이 뭔가 보안 앱의 검출에 걸려서 동작하지 못하는 상황이 생겼다.
  • 그동안은 백엔드 위주로 일을 하다보니 React와 Next.js라는 요즘의 프론트엔드 기술을 접할 일이 잘 없었는데 이번에는 백엔드도 프론트엔드도 기존 팀원들이 현황을 만족스럽게 설명해주거나 버그가 있는 부분이 정확히 뭔지 파악하기 힘들다 보니 자연스럽게 프론트엔드의 고질적인 문제라고 하는 부분을 내가 직접 확인하고 해결해야 했다. 이 과정에서 그럭저럭 React의 컴포넌트 구조와 Next.js의 라우팅 방식 등에 익숙해질 수 있었다.
    • 비슷한 시기에 개인적으로 접했던 linkwarden, hoarder가 모두 Next.js 기반으로 어느 정도 백엔드스러운 기능까지 구현하고 있어서 꼭 Nest.js를 써야 백엔드고 Next.js는 백엔드가 아니라는 식의 선입견을 깰 수 있었다.
    • v0.dev와 bolt.new, Github Copilot Workspace 등 내가 잘 모르면서도 어렵지 않게 프론트엔드 코드를 얻을 수 있는 수단이 생긴 것도 큰 도움이 되었다. 개인 프로젝트를 진행할 때 눈에 보이는 뭔가를 만들어내는 게 늘 걸렸는데 이제는 혼자 풀스택을 다루는 게 정말 멀지 않다는 걸 체감했다.
  • 우연찮게도 구글에서 라이센스 제안을 받아서, 구글 Looker 플랫폼 라이센스를 받을 수 있었다. 찾아보니 예전의 Data Studio가 Looker Studio가 됐다는 식이어서 예전 기억으로 가볍게 생각했었는데 실은 Looker라는 별개의 서비스를 사들이면서 브랜딩만 맞춘 거지 예전 Data Studio와는 전혀 다른 거라고 했다. BI를 위해 인력으로 매주 자료를 쌓는 걸 어떻게 자동화할 수 있는지 개발팀에 설명하고 회사에 도입할 수 있게 되어 기뻤다. 어쩌다 보니 도입 완료까지는 못 봤지만 인수인계한 내용 정도는 지금의 팀원들도 충분히 소화할 수 있으리라 기대한다. 나중에 어떻게 됐는지 물어봐야지.

 

3. 다뤘어야 하는 것

  • 단연코 2025년 현재는 AI의 하이프가 한 번 더 도약하는 시기다. ChatGPT라는 걸출한 서비스가 자리잡으면서 AI가 학자스러운 세계의 모델 경쟁만이 아니라 이미 존재하는 주요 클라우드 서비스 제공자들의 응용 기능들을 어떻게 가져다 쓰느냐가 업무의 판세를 엎을 수 있는 환경이 되었다.
  • 이미지의 분석, OCR, 객체 인식, TTS, STT, 영상 분석 등을 해야 하는 회사들이었다. 팀 환경부터 만들어야 하는 상황이 아니었다면 이런 기술적인 경험들을 하고 내가 원했던 결과물을 이끌어낼 수도 있었을 텐데 기술적인 부분에 충분한 시간을 쏟지 못해 아쉽다.

 

4. 다루고 싶은 것

  • 기술 위주가 아닌 회사여서 더더욱이나 개발팀이 뭘 하는지 조직 외부에 회사 전체에 잘 알릴 수단이 필요했다. 내 나름대로는 개발팀이야말로 커밋 로그도 남고 논의 문서나 설계나 각종 흔적들이 남는다고 생각해 너무나도 투명하게 일의 자취가 드러난다고 생각하지만 그것도 한발짝 떨어져서 기술에 익숙하지 않은 사람들에게는 먼나라 이야기가 된다. 지라에 이슈를 등록하라는 것도 누군가에게는 장벽이 되고, 어떤 작업이 지라에는 완료로 되어있는데 왜 내 눈에는 달라진 게 없는지 의아해한다. 글자 몇 개 바꾸고 숫자 두어개 바꾸면 될 것 같은 일이 왜 내일모레에 결과로 나오지 않는지 믿을 수 없어 한다. 이런 간극을 해소할 방법이 필요하다고 절실히 느꼈다. 개발 경력이란 걸로 이만큼 연차가 쌓였음에도 똑부러지는 답을 내지 못했다. 누군가는 두 번의 회사에서 실패했다고 말할 수도 있겠다. 릴리즈 노트를 내는 것과는 차원이 다른 문제임은 나도 절감했다. 어떻게 하면 좋을지 아직도 만족스러운 결론을 내지 못했다.