‘조용히 공개’의 효과는 무엇인가요? 조용히 공개된 글을 부스트하면 어떻게 되나요?

Jaeyeol Lee
@kodingwarrior@hackers.pub · 238 following · 158 followers
Neovim Super villain. 풀스택 엔지니어 내지는 프로덕트 엔지니어라고 스스로를 소개하지만 사실상 잡부를 담당하는 사람. CLI 도구를 만드는 것에 관심이 많습니다.
Hackers' Pub에서는 자발적으로 바이럴을 담당하고 있는 사람. Hackers' Pub의 무궁무진한 발전 가능성을 믿습니다.
그 외에도 개발자 커뮤니티 생태계에 다양한 시도들을 합니다. 지금은 https://vim.kr / https://fedidev.kr 디스코드 운영 중
Github
- @malkoG
Blog
- kodingwarrior.github.io
mastodon
- @kodingwarrior@silicon.moe
@curry박준규 연합 타임라인에 노출되냐 아니냐가 달라져요. 공개/조용히 공개로 설정한 것들은 부스트를 할 수 있고, 다른 인스턴스의 타임라인으로 퍼나를 수 있게 됩니다.
Jaeyeol Lee shared the below article:
Hacker's Pub에 입문한 한국어권 여러분을 위한 안내서

Jaeyeol Lee @kodingwarrior@hackers.pub
먼저 터를 잡은 사람으로서 Hacker's Pub에 오신 여러분들을 환영합니다. 현재 추정하건데 150명이 넘는 분들께서 Hacker's Pub에 들어오고 계신 것 같은데요. 물이 들어오면.... 노를 젓는게 인지상정이겠죠? 이 서비스가 만들어진 초기부터 관심을 가져왔고, 이 서비스의 가능성을 믿는 사람으로서 여러분에게 안내를 드리고자 합니다.
Hacker's Pub은 무엇을 하는 곳인가요?
Hacker's Pub은 소프트웨어 업계에 몸을 담고 있는 여러분들의 찰나의 생각, 혹은 장문의 정제된 생각들을 자유롭게 개시할 수 있는 소셜 네트워크 서비스이자, 블로깅 플랫폼입니다. 여러분은 그때그때 드는 생각들을 올려서 다른 사람들과 자유롭게 소통이 가능합니다.
Hacker's Pub 이라는 이름은 중의적인 의미를 가지고 있습니다.
- ActivityPub 프로토콜을 지원하는 해커들을 위한 커뮤니티
- Hacker's + Pub - 해커들이 자유롭게 웃고 떠들 수 있는 주점
Hacker's Pub이라는 커뮤니티에 애정을 가지고 있는 저로서는, 여기에 들어오시는 모든 분들이 Pub에 들렸다가 가는 것처럼 편안한 공간으로 느껴지시길 바랍니다. 우리 모두가 편안함 경험을 누릴 수 있도록 초대제로 운영이 되고 있습니다. 또한, 사회적 합의로서 행동강령도 마련되어 있으니 한번 참고해보시면 좋을 것 같습니다.
ActivityPub 프로토콜이란 무엇인가요?
Hacker's Pub은 ActivityPub 프로토콜을 지원하는 커뮤니티서비스입니다. 그렇다면, ActivityPub은 무엇일까요? ActivityPub은 웹 상의 분산형 소셜 네트워크를 구현하기 위한 국제 표준 프로토콜로, W3C에서 표준화되었습니다. Mastodon, Misskey, Pleroma 등 다양한 SNS 서비스들이 이 프로토콜을 기반으로 상호 호환되며 자유롭게 소통할 수 있도록 지원합니다. 쉽게 말해, 어떤 SNS를 사용하더라도 경계를 넘어 서로 소통할 수 있도록 돕는 것이 ActivityPub의 핵심입니다.
ActivityPub에 대한 자세한 설명은 여기가 정말 잘 되어 있으니 관심있는 분들은 한번 정독해보시는걸 권장드립니다.
Hacker's Pub을 이용하는 여러분들은 ActivityPub 프로토콜을 사용하는 모든 SNS 서비스(Mastodon, Misskey 등)의 사람들과 연결이 되어 있으며, 심지어 Bluesky에 있는 사람들과 연결이 되어 플랫폼의 경계가 허물어져 있는, 사실상 초연결적인 사회의 경험을 누릴 수 있습니다.
Hacker's Pub 생태계에 기여하기
Hacker's Pub은 아직 Early Stage 단계이며, 여전히 개선하고 발전해야 하는 여지는 있습니다. Hacker's Pub은 모든 것이 오픈소스로 개발되는, 전적으로 개방된 커뮤니티 서비스이기 때문에 여러분도 생태계의 발전에 기여할 수 있습니다. 해커들을 위한 공간이니만큼, 어느 누구에게도 기여는 열려있습니다. 여러분은 여기에서 실시간으로 기여에 참여하실 수 있습니다.
경우에 따라서는 Hacker's Pub에 당장은 기여하기가 어려울 수도 있습니다. ActivityPub 프로토콜에 대한 사전지식이라던가 혹은 서비스가 만들어진 기술스택에 대한 사전지식 같은 것들이 진입장벽이 될 수는 있을 것이거든요. 그렇다고 해도 괜찮습니다. ActivityPub에 대한 이해는 한국 연합우주 개발자 모임에서 함께 커뮤니티 차원에서 함께 알아가면 됩니다.
더불어, 시간이 지나면 Hacker's Pub 주변 생태계도 더더욱 발전할 수 있을 것이라 믿습니다. 당장은 서버와 클라이언트가 합쳐져서 개발되고 있는 형태이지만, 조만간 서버와 클라이언트가 분리되어서 개발될 예정이고, Mastodon/Misskey 같은 다른 ActivityPub 기반의 서비스가 그래왔듯, 우리만의 Hacker's Pub 클라이언트를 만들게 되는 날도 올 것입니다.
Hashnode 처럼 Hacker's Pub 블로그 템플릿 같은 것이 만들어지는 미래, 기대되지 않나요?
함께 만들어가는 Hacker's Pub
Hacker's Pub은 해커들을 위한 공간인 동시에, 모든 분들이 각자의 색깔과 생각을 마음껏 표현할 수 있는 열린 무대입니다. 우리 커뮤니티는 상호 존중과 신뢰를 기반으로 하며, 이를 위해 마련된 행동강령을 준수하는 동시에, 우리 모두의 다양한 의견과 피드백이 존중될 수 있는 공간입니다. 만약 새로운 아이디어나 개선 사항이 있다면 언제든지 의견을 공유해도 됩니다. 우리 모두의 참여가 바로 Hacker's Pub의 미래를 밝게 만드는 원동력입니다.
@hhhkdev미역굳 안녕하세요! 여기서도 반가워요!
@rangho_220우주스타 아이도루 랭호 🌠 뭐야 이거... 무서워...
@kodingwarriorJaeyeol Lee 지금 힙해야할것같아서 Beamer 버리고 reveal.js 쓰고잇읍니다,,,
@rangho_220우주스타 아이도루 랭호 🌠 캬...... 한땀한땀 깎고 있을 미래가 보이네여...
학교 산학플젝 발표자료 이맥스로 만들기
@rangho_220우주스타 아이도루 랭호 🌠 완전 짱이다
@kodingwarriorJaeyeol Lee 인사가 늦었습니다. 초대주셔서 감사드려요.
@resistanHyunjin Cho 별말씀을요 ㅋㅅㅋ
@kodingwarriorJaeyeol Lee emacs.ch도 작년부터 운영을 중단했나봅니다 😇
@nyeongAn Nyeong (安寧) 마음이.. 아프네요..
팔로워 100명 찍으면 초대는 좀 소극적으로 하고 컨텐츠를 좀 더 적극적으로 채울거야!
@boltless 안녕하세요
Jaeyeol Lee replied to the below article:
페디버스에서 어떤 사람들을 팔로하면 좋을까?

Jaeyeol Lee @kodingwarrior@hackers.pub
Hackers' Pub을 포함하여 페디버스에 입문한 여러분 중 누군가는 막막한 생각이 들 수도 있습니다. 특히 지인의 Pool이 없는 상황이거나 혹은 Fediverse라는 개념 자체가 낯설 수록이요.
먼저 인스턴스라는 개념도 낯설게 느껴지거니와, 어떤 사람을 팔로할 지도 아예 생태계에 쌩으로 입문하는 입장에서는 시작을 하는 것 자체가 난해합니다.
Hackers' Pub을 포함한 ActivityPub 프로토콜을 사용하는 서비스들의 장점은 Bluesky, Mastodon, Misskey 어디에든 걸쳐있는 사람들과 하나로 연결되는 경험을 누릴 수 있다고 언급한 적은 있었습니다만, 이러한 장점을 어떻게 누릴 수 있는지도 알기는 어려울 겁니다.
보통은 트위터나 혹은 다른 알고리즘 기반의 추천을 해주는 여러 서비스들은 좋아하는지 취향에 맞는지와는 상관없이 일단 추천하긴 하지만, 페디버스는 국내 생태계 한정으로는 추천을 하기가 쉽지 않은 것 또한 사실이긴 합니다. 하지만, 해외개발자 Pool은 굉장히 넓은 것이 자명합니다. 물론, 이것도 역시 추천을 하기가 쉽지 않습니다. 여러분이 혹시 단골로 찾아보는 개발자 블로그가 있다면 Mastodon 계정이 보이는 경우를 최소 두 자릿수는 준하게 보실 수 있을 것이긴 합니다.
아무튼, 페디버스 생태계에도 소프트웨어 종사자인 여러분이 읽을만한 피드는 준비되어 있습니다. 팔로해볼 수 있는 여러 계정들을 예시로 들어서 소개해볼까 합니다.
개발자들이 모여있는 인스턴스
어떤 마스토돈 인스턴스를 이용할 수 있는지는 **여기**에도 잘 설명되어 있습니다. 개인적으로 추천하는 마스토돈 인스턴스는 아래와 같습니다.
국내
- silicon.moe -- 이공계열에 종사하는 사람들을 위한 한국어권 마스토돈 인스턴스입니다.
- Hackers' Pub -- 개발자를 위한 블로깅 서비스입니다. ActivityPub 프로토콜을 지원하여서 ActivityPub 프로토콜을 지원하는 페디버스에서 구독이 가능합니다.
해외
- hachyderm.io -- IT 업계 종사자를 위한 마스토돈 인스턴스입니다. 대부분의 유명한 개발자들이 여기에 몰려있다고 봐도 됩니다.
- emacs.ch -- Emacs 에디터를 사용하는 사람들을 위한 마스토돈 인스턴스입니다.
- functional.cafe -- 함수형 개발자를 위한 마스토돈 인스턴스입니다.
- genserver.social -- Erlang/Elixir 개발자를 위한 Akkoma 인스턴스입니다.
- ruby.social -- Ruby 개발자를 위한 마스토돈 인스턴스입니다.
- mtd.pythonasia.org -- 아시아권의 Python 개발자를 위한 마스토돈 인스턴스입니다.
- fosstodon.org -- 오픈소스 개발자를 위한 마스토돈 인스턴스입니다. Python Software Foundation, Libre Office 등 오픈소스 프로젝트의 공식계정들이 많이 있습니다.
- hci.social -- HCI 연구자들을 위한 마스토돈 인스턴스입니다. Princeton HCI에서 운영하고 있습니다.
- vt.social -- 개발 분야 버츄얼 유튜버를 위한 마스토돈 인스턴스입니다. Asahi Lina, Luna가 공동 운영하고 있습니다.
Who to follow
Twitter/Threads에서는 자체적인 추천 알고리즘을 통해 어떤 계정을 팔로하면 괜찮을지 제안을 하기도 합니다. 하지만, 마스토돈은 그런 기능 쪽으로는 미비하다시피합니다.
개발 관련 정보를 구독하고 싶은 분들의 입장에서는 굉장히 치명적일 수도 있습니다. 아래에서는 어떤 개발자에게든 팔로할 것을 권장하는 계정들을 소개합니다.
개발 관련 뉴스
- Geeknews Bot -- GeekNews의 피드를 실시간으로 받아볼 수 있습니다.
- Hackernews
- Hacker News 500 -- Hacker News 에서 500 포인트 받은 글들을 볼 수 있습니다.
- Hacker News 100 -- Hacker News 에서 100 포인트 받은 글들을 볼 수 있습니다.
- Hacker News 50 -- Hacker News 에서 50 포인트 받은 글들을 볼 수 있습니다.
- Lobsters -- Lobsters는 Hacker News 보다는 좀 더 소프트웨어 개발/컴퓨터 사이언스에 초점이 맞춰진 글들이 올라옵니다.
- Twitter 공식 계정도 있었지만, 트위터의 Bot 관련 정책 변경으로 인해 2023년 5월 3일부로 운영이 중단되었습니다.
- discu.eu Weekly newsletter - 각종 분야별로 newsletter를 받아볼 수 있습니다.
- Python weekly, Haskell weekly 등등의 마스토돈 공식 계정이 있습니다.
오픈소스 컨트리뷰터
- Hong minhee -- Hackers' Pub, Hollo, Fedify 등 v페디버스 생태계에서 다양하고 재밌는 것들을 개발하고 계시는 분입니다.
- Eugen Rochko -- Mastodon 코어 컨트리뷰터입니다.
- Rob Pike -- Golang을 개발하신 그 분 맞습니다.
- Asahi Lina -- Asahi Linux에 기여하는 모습을 생중계하는 버츄얼 유튜버입니다.
- b0rks -- 개발자를 위한 N컷 만화를 연재하는 분입니다. Make Hard Things Easy라는 강연도 유명하니 한번씩은 보시는걸 권장합니다.
그 외에는...?
그 외에도, 관심이 가는 분야가 있으시다면 해당 분야 쪽 사람들이 모여있는 인스턴스를 눈여겨보시는 것을 권장합니다. 팔로우할 계정을 추천해주는 서비스를 찾으신다면 이것도 고려해보세요! (추천해주신 @rghw님 감사합니다.)
그 외에도 팔로할만한 계정이나 눈여겨볼만한 인스턴스가 있다면 댓글로 알려주세요! 여러분들의 댓글이 처음 입문하는 분들에게 도움이 될 수 있습니다!
페디버스 계정의 URL을 검색창에 입력하면 Hackers' Pub에서도 다른 인스턴스의 계정을 팔로할 수 있답니다!
페디버스에서 어떤 사람들을 팔로하면 좋을까?

Jaeyeol Lee @kodingwarrior@hackers.pub
Hackers' Pub을 포함하여 페디버스에 입문한 여러분 중 누군가는 막막한 생각이 들 수도 있습니다. 특히 지인의 Pool이 없는 상황이거나 혹은 Fediverse라는 개념 자체가 낯설 수록이요.
먼저 인스턴스라는 개념도 낯설게 느껴지거니와, 어떤 사람을 팔로할 지도 아예 생태계에 쌩으로 입문하는 입장에서는 시작을 하는 것 자체가 난해합니다.
Hackers' Pub을 포함한 ActivityPub 프로토콜을 사용하는 서비스들의 장점은 Bluesky, Mastodon, Misskey 어디에든 걸쳐있는 사람들과 하나로 연결되는 경험을 누릴 수 있다고 언급한 적은 있었습니다만, 이러한 장점을 어떻게 누릴 수 있는지도 알기는 어려울 겁니다.
보통은 트위터나 혹은 다른 알고리즘 기반의 추천을 해주는 여러 서비스들은 좋아하는지 취향에 맞는지와는 상관없이 일단 추천하긴 하지만, 페디버스는 국내 생태계 한정으로는 추천을 하기가 쉽지 않은 것 또한 사실이긴 합니다. 하지만, 해외개발자 Pool은 굉장히 넓은 것이 자명합니다. 물론, 이것도 역시 추천을 하기가 쉽지 않습니다. 여러분이 혹시 단골로 찾아보는 개발자 블로그가 있다면 Mastodon 계정이 보이는 경우를 최소 두 자릿수는 준하게 보실 수 있을 것이긴 합니다.
아무튼, 페디버스 생태계에도 소프트웨어 종사자인 여러분이 읽을만한 피드는 준비되어 있습니다. 팔로해볼 수 있는 여러 계정들을 예시로 들어서 소개해볼까 합니다.
개발자들이 모여있는 인스턴스
어떤 마스토돈 인스턴스를 이용할 수 있는지는 **여기**에도 잘 설명되어 있습니다. 개인적으로 추천하는 마스토돈 인스턴스는 아래와 같습니다.
국내
- silicon.moe -- 이공계열에 종사하는 사람들을 위한 한국어권 마스토돈 인스턴스입니다.
- Hackers' Pub -- 개발자를 위한 블로깅 서비스입니다. ActivityPub 프로토콜을 지원하여서 ActivityPub 프로토콜을 지원하는 페디버스에서 구독이 가능합니다.
해외
- hachyderm.io -- IT 업계 종사자를 위한 마스토돈 인스턴스입니다. 대부분의 유명한 개발자들이 여기에 몰려있다고 봐도 됩니다.
- emacs.ch -- Emacs 에디터를 사용하는 사람들을 위한 마스토돈 인스턴스입니다.
- functional.cafe -- 함수형 개발자를 위한 마스토돈 인스턴스입니다.
- genserver.social -- Erlang/Elixir 개발자를 위한 Akkoma 인스턴스입니다.
- ruby.social -- Ruby 개발자를 위한 마스토돈 인스턴스입니다.
- mtd.pythonasia.org -- 아시아권의 Python 개발자를 위한 마스토돈 인스턴스입니다.
- fosstodon.org -- 오픈소스 개발자를 위한 마스토돈 인스턴스입니다. Python Software Foundation, Libre Office 등 오픈소스 프로젝트의 공식계정들이 많이 있습니다.
- hci.social -- HCI 연구자들을 위한 마스토돈 인스턴스입니다. Princeton HCI에서 운영하고 있습니다.
- vt.social -- 개발 분야 버츄얼 유튜버를 위한 마스토돈 인스턴스입니다. Asahi Lina, Luna가 공동 운영하고 있습니다.
Who to follow
Twitter/Threads에서는 자체적인 추천 알고리즘을 통해 어떤 계정을 팔로하면 괜찮을지 제안을 하기도 합니다. 하지만, 마스토돈은 그런 기능 쪽으로는 미비하다시피합니다.
개발 관련 정보를 구독하고 싶은 분들의 입장에서는 굉장히 치명적일 수도 있습니다. 아래에서는 어떤 개발자에게든 팔로할 것을 권장하는 계정들을 소개합니다.
개발 관련 뉴스
- Geeknews Bot -- GeekNews의 피드를 실시간으로 받아볼 수 있습니다.
- Hackernews
- Hacker News 500 -- Hacker News 에서 500 포인트 받은 글들을 볼 수 있습니다.
- Hacker News 100 -- Hacker News 에서 100 포인트 받은 글들을 볼 수 있습니다.
- Hacker News 50 -- Hacker News 에서 50 포인트 받은 글들을 볼 수 있습니다.
- Lobsters -- Lobsters는 Hacker News 보다는 좀 더 소프트웨어 개발/컴퓨터 사이언스에 초점이 맞춰진 글들이 올라옵니다.
- Twitter 공식 계정도 있었지만, 트위터의 Bot 관련 정책 변경으로 인해 2023년 5월 3일부로 운영이 중단되었습니다.
- discu.eu Weekly newsletter - 각종 분야별로 newsletter를 받아볼 수 있습니다.
- Python weekly, Haskell weekly 등등의 마스토돈 공식 계정이 있습니다.
오픈소스 컨트리뷰터
- Hong minhee -- Hackers' Pub, Hollo, Fedify 등 v페디버스 생태계에서 다양하고 재밌는 것들을 개발하고 계시는 분입니다.
- Eugen Rochko -- Mastodon 코어 컨트리뷰터입니다.
- Rob Pike -- Golang을 개발하신 그 분 맞습니다.
- Asahi Lina -- Asahi Linux에 기여하는 모습을 생중계하는 버츄얼 유튜버입니다.
- b0rks -- 개발자를 위한 N컷 만화를 연재하는 분입니다. Make Hard Things Easy라는 강연도 유명하니 한번씩은 보시는걸 권장합니다.
그 외에는...?
그 외에도, 관심이 가는 분야가 있으시다면 해당 분야 쪽 사람들이 모여있는 인스턴스를 눈여겨보시는 것을 권장합니다. 팔로우할 계정을 추천해주는 서비스를 찾으신다면 이것도 고려해보세요! (추천해주신 @rghw님 감사합니다.)
그 외에도 팔로할만한 계정이나 눈여겨볼만한 인스턴스가 있다면 댓글로 알려주세요! 여러분들의 댓글이 처음 입문하는 분들에게 도움이 될 수 있습니다!
Hackers' Pub 타임라인에 내부적인 개선이 있었습니다. 이제까지는 타임라인을 렌더링하기 위해 실시간으로 복잡한 조건의 SQL
을 실행하는 방식이었지만, 이제는 글이 작성될 때 구독자의 수신함(inbox)에 글이 들어가는 방식으로 바뀌었습니다. 타임라인을 렌더링할 때는 각자의 수신함만 확인하면 되기 때문에 훨씬 조건이 간단해진 것입니다.
더불어, 같은 글을 여러 사람이 공유했을 때 타임라인이 같은 글로 도배되던 문제를 해결했습니다. 이제는 마지막에 공유한 사람의 글만 딱 하나 보이게 됩니다.
이번 변경에 관해 궁금하신 분은 f692909cdd5149c68ca5a91fb4e964042115ab83
커밋을 확인하시면 되겠습니다.
이 변경을 배포하다가 데이터베이스 스키마 마이그레이션이 PostgreSQL을 멈추게 하여 Hackers' Pub이 몇 분 동안 내려가는 일이 있었습니다. 마이그레이션 SQL이 너무 비효율적이라 그랬던 것인데요, Claude Code의 도움을 받아 하나의 비효율적인 SQL을 몇 개의 SQL로 나눠서 실행하게끔 고쳐서 해결했습니다. 이 역시 궁금하신 분은 33f2209f206bee84ddf5d1a7124527dade948610
커밋을 확인하시면 됩니다.
앞으로는 더 안정적인 서비스 운영을 위해 노력하겠습니다. 죄송하고 감사합니다.
다만, Reddit/HackerNews 같이 핫한걸 따로 UI 상에서 모아보고 싶은 사람들도 분명 있을 것 같은데, 사람들이 자연스럽게 느낄 수 있는 UI/UX가 될 수 있을지는 모르겠다...
Bot As a Algorithm Feed
줄여서 BAAF
블루스카이도 나만의 타임라인을 구성할 수 있도록 알고리즘 자체를 자발적으로 구성할 수 있는데, 해커스펍도 이걸 봇 붙이는걸로 해결이 가능한 것 같다. 그러면 해커스펍 코어에는 불필요한 DB 스키마를 별도로 안 붙여도 되고!
다만, Reddit/HackerNews 같이 핫한걸 따로 UI 상에서 모아보고 싶은 사람들도 분명 있을 것 같은데, 사람들이 자연스럽게 느낄 수 있는 UI/UX가 될 수 있을지는 모르겠다...
Fedify BotKit으로 해커스펍 타임라인 만드는 것도 괜찮을 것 같다. 특정 기간 동안 리액션이 좋은 상위 N개의 아티클을 메뉴로 보는게 아니라, 봇을 구독하는 것으로 해결한다던가!?
블루스카이도 나만의 타임라인을 구성할 수 있도록 알고리즘 자체를 자발적으로 구성할 수 있는데, 해커스펍도 이걸 봇 붙이는걸로 해결이 가능한 것 같다. 그러면 해커스펍 코어에는 불필요한 DB 스키마를 별도로 안 붙여도 되고!
@curry박준규
@hongminhee洪 民憙 (Hong Minhee) 이건 사망플래그잖아요 ㅋㅋㅋㅋㅋ
Fedify BotKit으로 해커스펍 타임라인 만드는 것도 괜찮을 것 같다. 특정 기간 동안 리액션이 좋은 상위 N개의 아티클을 메뉴로 보는게 아니라, 봇을 구독하는 것으로 해결한다던가!?
살았나!?
@hongminhee洪 民憙 (Hong Minhee) 고민해보겠습니다 😅
Vim이랑 Neovim은 어떻게 다를까?

Jaeyeol Lee @kodingwarrior@hackers.pub
주변에서 하도 계속 물어봐서 Vim과 Neovim의 결정적인 차이점을 문서로 남긴다. 당장은 생각나는대로 나열했기 때문에, 추후에 내용이 더 추가될 순 있다.
사용하는 언어부터 다르다 (VimScript / Lua)
Vim을 커스터마이징할때는 VimScript를 쓰지만, Neovim을 커스터마이징할때는 lua를 사용한다.
개인적으론 VimScript를 선호하진 않는데, vimscript 기반으로 짜여져 있는 플러그인의 소스코드를 읽는 것 자체가 고통스러웠던 경험이기도 했고, vimscript라는 언어 자체가 그닥 가독성이 좋은 편은 아니라고 생각한다. 기능적으로는 모자람이 없을 순 있으나, 읽을때도 고통스러운데 이걸로 스크립트를 짜라면 어지간하면 피할 것 같다.
반면. lua는 vimscript에 비하면 가독성이 적당히 나쁜 편은 아니다. 언어 자체의 기능으로 보자면 Python/Ruby/Javascript 등의 언어와 비교했을때 굉장히 좀 난해하게 느껴질 수는 있다.[1] 다만, lua는 macOS에서 사용하는 자동화 툴인 hammerspoon이라던가, 터미널 에뮬레이터인 wezterm이라던가 Unix 계열의 CLI 프로그램의 configuration을 작성하는데 있어서 사실상 De facto의 역할을 하고 있다. 언어 자체가 마음에 들지 않는 부분은 어느 정도 있긴 하지만, 가독성이나 개발편의성이 엄청 나쁜 것은 아니기 때문에 거부할 이유는 딱히 없다고 생각하고 쓰고 있다.
luarocks 패키지와 호환이 된다
Neovim을 커스터마이징할때 활용하는 lua는 luarocks라는 패키지매니저가 있기 때문에, 필요하다면 얼마든지 가져다 쓸 수 있다.
luarocks를 이용하는 Neovim 플러그인은 그렇게 많지는 않지만, (실질적인 쓸모의 유무를 떠나서) luarocks를 활용한 플러그인도 종종 보이긴 한다. 확실한건, lua 기반으로 개발되어 온 ecosystem을 등에 업고 언제든지 활용할 수 있다.
플러그인 생태계도 제법 괜찮은 편이다.
telescope / nvim-cmp / treesitter 같은 키워드 위주로만 찾아봐도 이걸 응용한 괜찮은 기능의 플러그인들을 많이 살펴볼 수 있다.
telescope
Neovim에서 사용할 수 있는 검색엔진이라고 생각해봐도 될 것 같다. 자세한 내용은 :help telescope
만 봐도 알 수 있겠지만, 파일 검색/패턴 검색 뿐만이 아니라 query를 넣을 수 있는 것이라면 어떤 것이든 다 해낼 수 있는 요술봉이라 생각한다.
예를 들면, git log를 검색한다던가, 현재 열어놓은 파일의 git history를 열람한다던가, 각각의 브랜치에 대한 git history를 표시하는 등의 git과 관련된 유용한 기능은 이미 네이티브로 들어가 있다.
여기서 좀 더 응용한다면, 아래의 예시와 같이 이용할 수 있다.
- 프로젝트를 구성하는 소스코드의 클래스/모듈/함수/상수 검색
- formatter/linter 오류 검색 (diagnostics)
- GitHub 리포지토리의 issue/PR 검색 -- pwntester/octo.nvim 참고
- throttling만 잘한다면 웹 요청이랑도 연결할 수 있다. 개인적으론 알라딘 검색 API와 연동하는 실험을 하고 있다.
nvim-cmp
이름에서 알 수 있듯이, 말 그대로 자동완성 기능을 위해 만들어진 플러그인 ecosystem이다. Neovim에서 자동완성 기능을 커스터마이징 해야 한다면, 바로 이 친구를 이용한다면 아주 간단한 문제가 된다.
pwd 기준의 경로 자동 완성 / emoji / 버퍼 내에서 반복적으로 사용되는 단어 위주의 자동완성 같은 사소한 것부터 Code Snippet / git commit sha1 해쉬 / GitHub author 자동 완성 / Language Server와 연동된 auto import 까지 입맛대로 자동완성 기능을 커스터마이징할 수 있다. 위에서 설명했던 telescope와 마찬가지로 쿼리할 수 있는 것이라면 어떻게든 활용할 수 있기 때문에 가능성은 무궁무진하다.
treesitter
사실 이게 왜 좋냐고 하냐면 많은 사람들에게 설득하는게 약간 어려운 난제이기도 하다. "굳이?" 라는 생각이 들 수도 있기 때문이다.
treesitter 자체는 파서를 만들어주는 제네레이터일 뿐이지만, 트리시터 기반으로 만들어진 파서가 활용도가 높기 때문에 유용함을 알고 있는 사람들은 잘 쓰고 있는 것 같다.
예를 들면, 커스텀 룰을 지정해주면 내가 탐험하고자 하는 소스코드의 범위를 탐색하는 것이 간단해진다. 왜냐면, scheme으로 커스텀 룰을 추가하는 것 자체가 일종의 트리 자료구조를 탐색하는 쿼리이기 때문이다.
알고리즘에 대한 배경지식이 있는 사람들한테는 좀 더 단순하게 설명하기도 하는데, "treesitter는 2차원 배열로 바라봐야 하는 소스코드를 트리로 바꿔서 생각할 수 있게 해준다." 이런 표현을 즐겨쓰는 편이다.
이에 대해 좀 더 직관적으로 와닿을 수 있는 예시는 ziontee113/syntax-tree-surfer인데, 함수가 정의되어 있는 위치를 바꾸는 demo 영상을 살펴보자. Syntax tree로 나타내면 두 함수의 위치는 Tree의 관점에서 보면 sibling으로 볼 수 있다. 두 함수가 정의되어 있는 위치를 바꾸는것은 사실상 트리 노드의 위치를 바꾸는 아주 간단한 문제로 환원이 된다.
그 외에도 두드러지는 점들
language server 지원도 나름 나쁘지는 않은 편인데, 제대로 세팅하려면 각각 language server마다 걸맞는 configuration을 해줘야 하는 수고로움이 생길 순 있지만, coc-nvim 세팅해놔도 개인적으론 크게 문제가 없었다.
Helix라는 신흥강자도 생기고 있는 모양이지만, 2023년 11월 기준, 2025년 3월으로는 크게 확 와닿을 정도로 삶에 혁신을 가져다 줄 만한 변화가 없기 때문에 당문간 관심을 가지는 건 보류
lua라는 언어의 불편함에 대해서는 따로 글로 작성하게 될 것 같다. 그렇다고 아예 못 쓰겠다라고 느낄 수준은 아니지만, 여러가지 면에서 인지 부조화를 느끼게 하는 부분이 있다는 것은 부정할 여지가 없다. ↩︎
Show HN: Physical Pomodoro Timer with ESP32 and e-paper screen
Link: https://github.com/Rukenshia/pomodoro
Discussion: https://news.ycombinator.com/item?id=43514383
ActivityPub 효율적으로 익히려면 그냥 fedify 문서 첨부터 끝까지 읽으면 되는듯요
내년쯤에 framework 랩톱 풀옵션으로 지를까 고민중... 지금 쓰는건 한정된 예산으로 최대한 쥐어짜내서 산거라 아쉬움이 남긴 하는데, 한 2년은 더 쓰고...
@curry박준규 알림기능이 먼저 만들어질지 아니면 마스토돈 API 지원이 먼저일지 세기의 경쟁
@kodingwarriorJaeyeol Lee
@curry박준규 알림은 조만간 구현 예정이고, Mastodon API는 아마도 구현 안 될 것 같아요. 대신
@xiniha 님 주도로 GraphQL API가 생길 예정!
@kodingwarriorJaeyeol Lee 알림 기능은 우선 우리인생처럼 ‘메일 발송’으로 구현하면 어떨까요?
@curry박준규 어어어... 그러면 메일 서비스 비용이 빡세요. 자체적으로 메일 서버를 구축하는게 아닌 이상에야
해커스펍 계정은 쓰기 전용으로, 우리인생은 읽기전용으로 사용하고 있다. 또는 기술 관련 콘텐츠는 해커스펍에 올리고 일상은 우리인생에 올리려고 한다.
클라이언트는 팬피를 쓰고 있는데 해커스펍은 마스토돈 API 구현이 안 되어 있어서 팬피에는 우리인생 계정을 연동했다.
그런데 팬피에서 재밌게 글을 읽다 보면 무심코 팬피에서(우리인생 계정으로) 해커스펍 글에 댓글을 달아서 뭔가 곤란하다⋯
그리고 해커스펍에 오신 분들은 거의 다 팔로우를 하고 있는데 동시에 우리인생에서도 팔로우를 해야해서(팬피에서 읽어야 하니까) 불편하다.
@curry박준규 알림기능이 먼저 만들어질지 아니면 마스토돈 API 지원이 먼저일지 세기의 경쟁
@kodingwarriorJaeyeol Lee
@maxwellEunsoo Eun 제가 초대 드렸어요. ㅎㅎㅎ
@hongminhee洪 民憙 (Hong Minhee)
@maxwellEunsoo Eun 저한테 물어봐도 되었을 것 같은디 크흡
@maxwellEunsoo Eun 어 뭐야 어떻게 오신거에요
We're excited to announce the release of Fedify 1.5.0! This version brings several significant improvements to performance, configurability, and developer experience. Let's dive into what's new:
Two-Stage Fan-out Architecture for Efficient Activity Delivery
#Fedify now implements a smart fan-out mechanism for delivering activities to large audiences. This change is particularly valuable for accounts with many followers. When sending activities to many recipients, Fedify now creates a single consolidated message containing the activity payload and recipient list, which a background worker then processes to re-enqueue individual delivery tasks.
This architectural improvement delivers several benefits: Context.sendActivity()
returns almost instantly even with thousands of recipients, memory consumption is dramatically reduced by avoiding payload duplication, UI responsiveness improves since web requests complete quickly, and the system maintains reliability with independent retry logic for each delivery.
For specific requirements, we've added a new fanout
option with three settings:
// Configuring fan-out behavior
await ctx.sendActivity(
{ identifier: "alice" },
recipients,
activity,
{ fanout: "auto" } // Default: automatic based on recipient count
// Other options: "skip" (never use fan-out) or "force" (always use fan-out)
);
Canonical Origin Support for Multi-Domain Setups
You can now explicitly configure a canonical origin for your server, which is especially useful for multi-domain setups. This feature allows you to set different domains for WebFinger handles and #ActivityPub URIs, configured through the new origin
option in createFederation()
. This enhancement prevents unexpected URL construction when requests bypass proxies and improves security by ensuring consistent domain usage.
const federation = createFederation({
// Use example.com for handles but ap.example.com for ActivityPub URIs
origin: {
handleHost: "example.com",
webOrigin: "https://ap.example.com",
},
// Other options...
});
Optional Followers Collection Synchronization
Followers collection synchronization (FEP-8fcf) is now opt-in rather than automatic. This feature must now be explicitly enabled through the syncCollection
option, giving developers more control over when to include followers collection digests. This change improves network efficiency by reducing unnecessary synchronization traffic.
await ctx.sendActivity(
{ identifier: sender },
"followers",
activity,
{
preferSharedInbox: true,
syncCollection: true, // Explicitly enable collection synchronization
}
);
Enhanced Key Format Compatibility
Key format support has been expanded for better interoperability. Fedify now accepts PEM-PKCS#1 format in addition to PEM-SPKI for RSA public keys. We've added importPkcs1()
and importPem()
functions for additional flexibility, which improves compatibility with a wider range of ActivityPub implementations.
Improved Key Selection Logic
The key selection process is now more intelligent. The fetchKey()
function can now select the public key of an actor if keyId
has no fragment and the actor has only one public key. This enhancement simplifies key handling in common scenarios and provides better compatibility with implementations that don't specify fragment identifiers.
New Authorization Options
Authorization handling has been enhanced with new options for the RequestContext.getSignedKey()
and getSignedKeyOwner()
methods. This provides more flexible control over authentication and authorization flows. We've deprecated older parameter-based approaches in favor of the more flexible method-based approach.
Efficient Bulk Message Queueing
Message queue performance is improved with bulk operations. We've added an optional enqueueMany()
method to the MessageQueue
interface, enabling efficient queueing of multiple messages in a single operation. This reduces overhead when processing batches of activities. All our message queue implementations have been updated to support this new operation:
- @fedify/redis 0.4.0
- @fedify/postgres 0.3.0
- @fedify/amqp 0.2.0
If you're using any of these packages, make sure to update them alongside Fedify to take advantage of the more efficient bulk message queueing.
CLI Improvements
The Fedify command-line tools have been enhanced with an improved web interface for the fedify inbox
command. We've added the Fedify logo with the cute dinosaur at the top of the page and made it easier to copy the fediverse handle of the ephemeral actor. We've also fixed issues with the web interface when installed via deno install
from JSR.
Additional Improvements and Bug Fixes
- Updated dependencies, including @js-temporal/polyfill to 0.5.0 for Node.js and Bun
- Fixed bundler errors with uri-template-router on Rollup
- Improved error handling and logging for document loader when KV store operations fail
- Added more log messages using the LogTape library
- Internalized the multibase package for better maintenance and compatibility
For the complete list of changes, please refer to the changelog.
To update to Fedify 1.5.0, run:
# For Deno
deno add jsr:@fedify/fedify@1.5.0
# For npm
npm add @fedify/fedify@1.5.0
# For Bun
bun add @fedify/fedify@1.5.0
Thank you to all contributors who helped make this release possible!
Jaeyeol Lee shared the below article:
한국 소프트웨어 개발자들이 자주 틀리는 외래어 표기법

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub
전에 단문으로 올렸던 글을 지속적으로 갱신해볼까 싶어 게시글로 만들어 봅니다.
영어 | 틀린 표기 | 올바른 표기 |
---|---|---|
algorithm | 알고리즘 | 알고리듬 |
app | 어플 | 앱 |
application | 어플리케이션 | 애플리케이션 |
BASIC | 베이직 | 베이식 |
directory | 디렉토리 | 디렉터리 |
front-end | 프론트엔드 | 프런트엔드 |
launch | 런치 | 론치 |
license | 라이센스 | 라이선스 |
message | 메세지 | 메시지 |
method | 메소드 | 메서드 |
parallel | 페러렐 | 패럴렐 |
proxy | 프록시 | 프락시 |
release | 릴리즈 | 릴리스 |
repository | 레포지토리 | 리파지터리 |
shader | 쉐이더 | 셰이더 |
shell | 쉘 | 셸 |
우˗ˋˏ 와 ˎˊ˗
Jaeyeol Lee shared the below article:
Grokに、三井住友海上火災保険とあいおいニッセイ同和損害保険が合併した新会社の名称を考えてもらいました
のえる @noellabo@hackers.pub
Hacker's PubとGrokの動作試験です。内容に特に意味はありません。
私が行った質問
三井住友海上火災保険とあいおいニッセイ同和損害保険が合併する前提で、短く親しみやすい新名称を考えてください。
Grokの回答
主要ポイント
-
三井住友海上火災保険とあいおいニッセイ同和損害保険が合併する場合、新名称として「MS&AD保険」が適切と考えられます。これは両社の親会社であるMS&AD保険グループの名前を基にしたもので、短く親しみやすいです。
-
両社はすでにMS&AD保険グループ傘下にあり、2009年に発表された過去の合併計画では中立的な名前が採用されました。
新名称の提案
合併後の新名称として「MS&AD保険」を提案します。これは両社の歴史と現在のグループ構造を反映し、保険業界で認知されやすい名称です。短く、発音しやすく、親しみやすさがあります。
背景と文脈
三井住友海上火災保険(MSI)とあいおいニッセイ同和損害保険(ANDI)は、MS&AD保険グループの主要な子会社であり、すでに同じ傘下にあります。2009年の発表では、これらの会社が合併し、日本最大の損害保険会社を作る計画がありました。その結果、MS&AD保険グループホールディングスが設立され、現在の構造が形成されました。もし今後さらに運営を統合する場合、「MS&AD保険」は自然な選択肢と考えられます。
予想外の詳細
興味深いことに、MS&AD保険グループは2013年に市場シェア33%を達成し、日本最大の財産保険会社となりました。この合併は、自動車保険や火災保険など幅広いサービスを提供する強力なエンティティを生み出す可能性があります。
調査ノート
このセクションでは、三井住友海上火災保険とあいおいニッセイ同和損害保険が合併する場合の短く親しみやすい新名称を考える過程で収集した詳細情報を提供します。ユーザーの質問は仮定に基づいており、歴史的背景と現在の市場ポジションを考慮する必要があります。
会社名の解明
まず、両社の現在の名前と関係を確認します:
-
三井住友海上火災保険は英語でMitsui Sumitomo Insurance Company, Limited(MSI)と呼ばれ、2001年に三井海上火災保険と住友海上火災保険が合併して形成されました。
-
あいおいニッセイ同和損害保険は英語でAioi Nissay Dowa Insurance Company, Limited(ANDI)と呼ばれ、2010年にあいおい保険とニッセイ同和一般保険が合併して形成されました。両社はすでにMS&AD保険グループホールディングス(MS&AD Insurance Group Holdings, Inc. Official Website)の傘下にあり、このグループは日本最大の損害保険会社の一つです。
合併の歴史的背景
2009年1月23日の発表(UPDATE 1-Mitsui Sumitomo, Aioi, Nissay Dowa to merge | Reuters)では、三井住友保険グループ、あいおい保険、ニッセイ同和一般保険の合併計画が明らかにされました。この合併は2010年4月に完了し、MS&AD保険グループホールディングスが設立されました。この過程で、新しい保険グループには「中立的な名前」が与えられ、MS&ADが採用されました(Mitsui Sumitomo, Aioi, Nissay Dowa announce merger plan :: Lloyd's List)。
新名称の提案
ユーザーの質問は、両社がさらに運営を統合する場合の新名称を考えるものであり、短く親しみやすい名前が必要です。以下のオプションを検討しました:
-
MS&AD保険: これは現在の持ち株会社の名前を基にしたもので、短く認識されやすいです。すでにグループ全体のブランドとして確立されており、顧客や市場で親しみやすいと考えられます。
-
他の可能性: 「Mitsui Sumitomo Aioi Nissay Dowa保険」のような長い名前も考えられますが、短縮形の「MSAND保険」は発音しにくい可能性があります。また、「United Japan Insurance」や「Sakura Insurance」などの創造的な名前も検討しましたが、両社の歴史やブランドを反映しないため不適切と判断しました。最終的に、「MS&AD保険」が最も適切であると結論付けました。これは中立であり、両社の遺産を尊重しつつ、短く親しみやすい名称です。
市場ポジションと関連情報
MS&AD保険グループは、日本国内の損害保険市場で大きなシェアを持ち、2022年の純保険料収入は約610億ドルで、市場の80%を占める主要プレイヤー(Tokio Marine、Sompo Japan、Mitsui Sumitomo & Aioi Nissay Dowa Insurance)の一つです(Aioi Nissay Dowa Insurance Portfolio Investments)。このグループは、自動車保険や健康保険など多様な製品を提供し、グローバルな展開も進めています。
表:関連会社の概要
会社名 | 設立年 | 役割 | 略称 |
---|---|---|---|
三井住友保険株式会社 | 2001 | 損害保険事業(MS&ADグループの中核) | MSI |
あいおいニッセイ同和損保株式会社 | 2010 | 損害保険事業(自動車中心) | ADI |
MS&AD保険グループホールディングス | 2008 | 持ち株会社、グループ戦略の策定 | MS&AD |
結論
ユーザーの指定に基づき、合併後の新名称として「MS&AD保険」を提案します。これは公式の名前ではなく、仮定に基づく提案ですが、両社の歴史と現在のグループ構造を反映し、短く親しみやすい名称として適しています。過去の合併では中立的な名前が採用された前例もあり、「MS&AD保険」はその流れに沿った選択肢です。
主要引用
- MS&AD Insurance Group Holdings, Inc. Official Website
- UPDATE 1-Mitsui Sumitomo, Aioi, Nissay Dowa to merge | Reuters
- Mitsui Sumitomo, Aioi, Nissay Dowa announce merger plan :: Lloyd's List
- Aioi Nissay Dowa Insurance Portfolio Investments
追加の質問
提案いただいたMS&AD保険という名称はアルファベットと記号で構成されていて記憶しにくいので、漢字やかなで表記できる名称を考えてください。
Grokの回答
主要ポイント
三井住友海上火災保険とあいおいニッセイ同和損害保険が合併する場合、新名称として「信頼保険(しんらいほけん)」を提案します。これは短く親しみやすく、漢字で表記でき、保険業界で重要な「信頼」を強調します。
両社はすでにMS&AD保険グループ傘下にあり、過去の合併では中立的な名前が採用されました。
提案の背景
合併後の新名称として「信頼保険(しんらいほけん)」を提案します。この名前は、保険事業において顧客が求める「信頼」を象徴し、短く覚えやすいです。また、漢字やひらがなで表記可能で、ユーザーの要望に合致します。
なぜ「信頼保険」か
「信頼(しんらい)」は、保険会社が提供する安心感や信頼性を表現し、顧客との関係を強化します。
既存の調査では、「信頼保険」という名称の保険会社は見つからず、独自性があります(例: 安堵保険は存在するが、異なる)。
両社の歴史(三井住友は2001年合併、あいおいニッセイ同和は2010年合併)を考慮し、統合後の新ブランドとして適切です。
予想外の詳細
MS&AD保険グループは2013年に市場シェア33%を達成し、日本最大の財産保険会社の一つです。この合併は、自動車保険や火災保険など幅広いサービスを提供する強力なエンティティを生み出す可能性があります。
調査ノート
(重複するので中略)
新名称の提案プロセス
ユーザーの質問は、両社がさらに運営を統合する場合の新名称を考えるものであり、短く親しみやすい名前が必要です。以下のオプションを検討しました:
MS&AD保険: 現在の持ち株会社の名前を基にしたもので、短く認識されやすいです。しかし、アルファベットと記号のため、ユーザーの要望には合致しません。
他の可能性: 「Mitsui Sumitomo Aioi Nissay Dowa保険」のような長い名前も考えられますが、短縮形の「MSAND保険」は発音しにくい可能性があります。また、「United Japan Insurance」や「Sakura Insurance」などの創造的な名前も検討しましたが、両社の歴史やブランドを反映しないため不適切と判断しました。
そのため、漢字やひらがなで表記可能な名前を模索しました。以下のような候補を検討:
信頼保険(しんらいほけん): 「信頼」は保険業界で重要な要素であり、短く親しみやすい。調査の結果、既存の保険会社では見つからず、独自性があります。
安堵保険(あんどほけん): 調査の結果、安堵保険が存在するため、競合の可能性あり。
希望保険(きぼうほけん): 「希望」はポジティブだが、キーボード販売の希望.storeがあり、保険業界では競合の可能性。
最終的に、「信頼保険(しんらいほけん)」が最も適切であると結論付けました。これは中立であり、両社の遺産を尊重しつつ、短く親しみやすい名称です。
(中略)
結論
ユーザーの指定に基づき、合併後の新名称として「信頼保険(しんらいほけん)」を提案します。これは公式の名前ではなく、仮定に基づく提案ですが、両社の歴史と現在のグループ構造を反映し、短く親しみやすい名称として適しています。過去の合併では中立的な名前が採用された前例もあり、「信頼保険」はその流れに沿った選択肢です。
@joonnotnotJoon 여기서 반가워요
한국의 Clojure 생태계를 책임지는 슈퍼루키 트친도 영입하고 있는 중인데, 이 계정도 추천해야겠다. 아니, 근데.. 클로져리안 모아놓은 인스턴스도 있었네????
게시글에 목차가 추가되었습니다. 게시글 안에 소제목이 있을 경우에는 목차가 보이게 됩니다. 가로로 넓은 화면에서는 오른쪽에 보이고, 모바일 환경처럼 가로로 좁은 화면에서는 제목 아래 본문 위에 보이게 됩니다.
.vimrc 파일 공유하던사람들끼리 창업해서 CLI 깎는 회사 만들고 6백만달러를 펀딩받았다는 이야기가 있다. 나는 이 이야기를 아주 좋아한다.
한국의 Clojure 생태계를 책임지는 슈퍼루키 트친도 영입하고 있는 중인데, 이 계정도 추천해야겠다. 아니, 근데.. 클로져리안 모아놓은 인스턴스도 있었네????
코드 리뷰 요정, CodeRabbit이 나타났다 🐰 https://tech.inflab.com/20250303-introduce-coderabbit/
코드래빗에 저렇게 프롬프트를 넣을 수 있는거구나.....
https://choubey.gitbook.io/internals-of-deno
Deno 런타임 내부 까보는거 입문은 이걸로 시작해야겠다
@kodingwarriorJaeyeol Lee 안녕하세요~
@sonsubari바리 감사해요~ 잘 있어요~ 다시 만나요~
오 새로운 공간... 낯설다..!!!
@sonsubari바리 어서오세요
@darkenpengpenguin 안녕하세요 반가워요
Jaeyeol Lee shared the below article:
거꾸로 상태 모나드로 강화 학습 하기 (1/2)

bgl gwyng @bgl@hackers.pub
기계 학습을 전혀 모르고 살면 안 되겠다 싶어, 얼마전부터 하스켈로 공부하기 시작했다.
Hasktorch라고 하스켈용 Torch 바인딩을 사용한다. 이전에 도전했을땐 MNIST까지 하고 다음에 뭘 해야할지 모르겠어서 그만뒀는데, 이번엔 강화 학습으로 이어나가 보기로 했다.
강화 학습은 주어진 환경에서 보상을 최대화하는 에이전트를 학습시키는 것으로, 데이터가 필요없다는게 장점이다. 대신 환경을 만들어야 하는데, 간단한 게임도 환경이 될 수 있다. 게임 만들기는 데이터 모으기와 달리 즐거운 일이니 마다할 필요가 없다.
첫번째로 도전으로 스네이크 게임을 골랐는데, 다들 한번쯤은 해봤을 것이다. 뱀을 조종해 먹이를 최대한 많이 먹으면 되는데, 뱀의 머리가 벽이나 아니면 자기 몸통에 부딪히면 죽는다.
여차여차 학습시켜서 이정도까지 하는데에는 성공했다.
강화 학습 지식이 일천해서 게임을 클리어하는 수준까지는 못 만들겠다. 이 글은 학습을 잘 시키는 방법이 아니라, 강화학습 코드를 어떻게 잘 짜느냐에 대한 것이다.
일단 강화 학습이란걸 형식화 해보자. 앞서 언급한 환경과 에이전트란 단어를 어떻게 정의할수 있을까?
먼저 에이전트의 정의는 이렇다.
type Agent = Observation -> Action
관측 Observation 에 따라 행동 Action 을 선택한다. 나는 눈앞에 콜라가 보이면 마신다.
환경은 에이전트를 실행하는 무언가이다. 일상적인 표현으로 쓰자면, 에이전트를 둘러싼 무언가이다.
runAgent :: Agent -> [Action]
이 runAgent
함수가 환경의 역할을 수행한다. Agent
를 인자로 받아 죽을 때까지 선택한 행동들을 반환한다.
그런데 이건 너무 외연적인 정의고, 환경과 에이전트가 보통 만족할만한 조건을 나열해보자면 이렇다.
- 환경은 상태를 가지고 있고 시간이 지남에 따라 변경된다
- 상태는 에이전트가 무엇을 관측할지를 결정한다
- 에이전트의 행동은 다음 상태에 영향을 끼친다
이 조건들을 바탕으로 환경을 좀더 구체적으로 정의하면 다음과 같다.
class Environment e where
type State e
type Observation e
type Action e
update :: (State e, Action e) -> State e -- 조건 1, 3
observe :: State e -> Observation e -- 조건 2
스네이크 게임에서 상태는 뱀의 모양과 먹이의 위치, 관측은 상태와 같고(플레이어는 전체 게임 화면을 볼 수 있다), 행동은 좌회전과 우회전이 된다.
그런데 뱀이 아무렇게나 좌회전 우회전 한다고 박수 쳐줄순 없고, 우리는 얘한테 바라는 게 있다. 죽지않고 더 많은 먹이를 먹어야 한다. 이를 위해 뱀이 제때 방향을 바꿔서 먹이를 지나치지 않고 먹으면 잘 했다고 보상을 주자. 그러면 뱀은 보상을 더 많이 받을 방법을 학습한다.
type RewardFunction = (Observation, Action) -> Float
보상 함수는 관측와 행동에 따라 보상을 결정한다. 가령 뱀이 먹이 하나를 냠냠하면 보상을 1 주면 된다. 지나쳐버리면 0점이고, 죽었을 때는 -1점을 줄 수도 있다. 당근과 채찍이라 생각하고 정의하면 된다. 또, 보상은 더해서 누적이 되어야 하므로 대충 Float
으로 고른다.
학습을 시키려면 보상을 계산해야하고, 그러기 위해 관측과 행동을 짝지어야한다.
trainAgent :: Agent -> [(Observation, Action)]
runAgent
와 달리 Observation
도 포함되어 있다. 이때 [(Observation, Action)]
을 에피소드 Episode 라고 한다. 에피소드로부터 보상을 구하자.
rewards = fmap (uncurry rewardFn) (trainAgent agent)
rewardFn :: RewardFunction
agent :: Agent
...해치웠나?
에피소드가 어떻게 기록될지를 살펴보자.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
행동 | → | ↓ | → | ↓ | ← | ↑ | → | ↓ | ← | ↓ |
보상 | 🍎 | 🍎 | 🍎 | 💀 |
위의 rewards
의 값이 이런 의미일거라고 보인다. 실제로 Float
값을 표시해보자.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
행동 | → | ↓ | → | ↓ | ← | ↑ | → | ↓ | ← | ↓ |
보상 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
혹시 이상한 걸 찾으셨나요?
이런식으로 보상하는게 틀린 건 아니다. 다만 에이전트가 장기적인 계획을 세우도록 학습시키지 못한다. 먹이를 먹는 순간에만 보상을 받기 때문에, 멀리 떨어진 먹이를 향해 다가가게끔 유도할 수가 없다. 이를 해결하려면 보상을 뒤에서부터 누적시켜야 한다.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
행동 | → | ↓ | → | ↓ | ← | ↑ | → | ↓ | ← | ↓ |
보상 | 3 | 3 | 3 | 2 | 2 | 2 | 1 | 0 | 0 | 0 |
rewards = scanr (+) 0 (fmap (uncurry rewardFn) (trainAgent agent))
코딩 테스트용 코드를 짜야할것 같은 느낌이 들었는데, 다행히 scanr
함수 덕분에 쉽게 해결했다.
좀더 개선해볼까.
지금의 보상 체계에서 에이전트는 먼 미래를 고려하며 선택하는 것을 배울 수 있다. 그런데, 사실 뱀이 맨 처음에 좌회전을 하던 우회전을 하던, 죽기 전까지 먹이를 총 몇개 먹는지에 엄청난 영향을 끼칠거 같진 않다. 어떤 시점에서의 선택의 영향은 시간이 지날 수록 점점 희미해진다. 이 점을 반영해서 뱀이 잘못된 편견을 갖지 않도록 도와주자. 미래의 보상을 누적하되, 감쇠율 0.9를 적용하는 것이다.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
행동 | → | ↓ | → | ↓ | ← | ↑ | → | ↓ | ← | ↓ |
보상 | 1.93 | 2.15 | 2.39 | 1.54 | 1.71 | 1.90 | 1.00 | 0.00 | 0.00 | 0.00 |
rewards = scanr (\x y -> x + 0.9 * y) 0 (fmap (uncurry rewardFn) (trainAgent agent))
이제 나머지는 GPU한테 맡기면 된다. 조금만 기다리면 위의 동영상에서처럼 움직이는 뱀을 볼 수 있다.
여기서 GPU를 100장 더 사서 뱀 대신에 좀더 우리 삶에 도움되는 에이전트를 학습시킨다면, 그걸 10년전에 했으면, 난 지금 부자가 되어있을지도 모르겠다. 하지만 기회는 이미 떠났고, 난 지금 돈은 없지만 대신 시간은 많다. 그 시간을, 지금의 그럭저럭 볼만한 코드를 쥐꼬리만큼 개선하는데 낭비해보려 한다.
지금 코드에서 뭐가 마음에 안드냐면,
-
보상이 사실 서로 다른 두 개를 가리킨다
먹이를 먹자마자 즉각적으로 주는 보상과, 그것을 누적한 보상, 이렇게 두 개가 있다. 실제로 학습에 사용하는 것은 후자이다. 그런데 막상 보상 함수의 정의는 전자에 대한 것이다. 이는 보상 함수를 계산할 때 미래에 어떤 일이 일어나는지 알수가 없어서 그렇다. 정의를 두 개로 나눈 이유가 의미를 명쾌하게 하기 위해서가 아니라, 그냥 한번에 계산을 할수 없기 때문이다.
-
환경의 정의
위에서 살펴본
runAgent
의 정의가 일견 우아해보일 수 있다. 문제는 그 정의는 환경과 에이전트가 모두 순수 함수일 것을 강요한다는 것이다.Environment
의 정의도 마찬가지다.환경과 에이전트는 각자의 부수효과 Side effect 를 가질 수 있어야 한다. 가령 온라인 게임을 환경으로 삼는다면, 환경은 네트워킹을 할 수 있어야 한다. 또, 에이전트는 매번 똑같은 선택이 아닌 확률적 선택을 하고 싶을텐데, 이는 순수 함수로써는 불가능하다.
그러면 부수효과를 허용하면 되는거 아냐?
맞다. 나처럼 시간이 많다면 직접 해보는 것도 나쁘지 않다. 하지만 정의가 점점 지저분해지는 것을 보게될 것이고...
시간을 아껴주기 위해 정답을 알려주겠다. 환경은 에이전트가 실행될 수 있는 모나드여야 한다. 딱 거기까지여야 한다. 환경과 에이전트 사이에 그 이상의 관계는 부적절하다.
글이 생각했던 것보다 길어져버려서, 오늘은 여기까지 해야겠다. 이어지는 글에서 거꾸로 상태 모나드가 이걸 어떻게 해결하는지 소개한다.
사실 아까 환경이니 에이전트니 어쩌고 할때부터, 진작에 강화 학습을 마스터한 학생들이 이미 다 아는 내용에 지겨워 졸기 시작하는게 보였다.
다음 수업은 재밌을테니, 대신 그때까지 모나드를 배워오세요.
저… 제가 아마도 해커스펍 개발자분보다도해커스펍 서버와 가장 가까이서(2미터 거리) 쓰고 있는 유저인데…
느려요.
RE: https://hackers.pub/@hongminhee/0195d567-06d6-7437-a4eb-cf567adf9714
해커스펍의 정체… (거대토끼의 맥미니 위에서 돌아가고 있습니다.)