GN⁺: 에이전틱 코딩에서 개발자 역량의 역할
------------------------------
- 에이전트형 코딩 어시스턴트가 더 유능해짐에 따라 반응은 매우 다양하고, 일부는 "*1년 안에 개발자가 더 이상 필요하지 않을 것* "이라고 주장
- 다른 사람들은 AI가 생성한 *코드의 품질* 과 *주니어 개발자를 이러한 변화하는 환경에 대비시키는 방법* 에 대해 우려를 제기함
- 지난 몇달간 Cursor, Winds…
------------------------------
https://news.hada.io/topic?id=20006&utm_source=googlechat&utm_medium=bot&utm_campaign=1834

Juntai Park
@arkjun@hackers.pub · 47 following · 44 followers
中年의 中小企業 開發者, 90年代 Console Gamer. 좋은 하루를 繼續해 나아간다. 좋은 하루가 모이면 좋은 人生이 된다.
韓国人のプログラマー、40代、小学生の息子とゲームするのが幸せ😃💕龍が如く 、ゼルダの伝説、マリオ、ピクミン好き
「いい1日を続ける」
いい1日を続けていけば、いい人生になる!
threads
- @rkjun
x
- @rkJun
uri.life
- @arkjun@uri.life
GitHub
- @arkjun
https://choubey.gitbook.io/internals-of-deno
Deno 런타임 내부 까보는거 입문은 이걸로 시작해야겠다
코드 리뷰 요정, CodeRabbit이 나타났다 🐰 https://tech.inflab.com/20250303-introduce-coderabbit/
코드래빗에 저렇게 프롬프트를 넣을 수 있는거구나.....
게시글에 목차가 추가되었습니다. 게시글 안에 소제목이 있을 경우에는 목차가 보이게 됩니다. 가로로 넓은 화면에서는 오른쪽에 보이고, 모바일 환경처럼 가로로 좁은 화면에서는 제목 아래 본문 위에 보이게 됩니다.
.vimrc 파일 공유하던사람들끼리 창업해서 CLI 깎는 회사 만들고 6백만달러를 펀딩받았다는 이야기가 있다. 나는 이 이야기를 아주 좋아한다.
Juntai Park shared the below article:
복잡한 코드를 단순하게 줄여나갈 수록 발생하는 버그의 빈도나 심각도가 점진적으로 올라가는 경향이 있다고 느낀다

ㄹ @disjukr@hackers.pub
<metadata></metadata><style class="style-fonts"> @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAQsABEAAAAADHQAAAPRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKggCBcAsGAAE2AiQDCAQgBYJeByAMFBsxC1GU7kmc7IuDeIxnknghkogrbGm/yUrQr2+4AWU2eJ7yqver0gMwA3Apn7YXEm9wGAyuCeZhwkEGwsU2dSmhL3X5FByVFyffuXywYwJeQMyQoTnpoLuJgfyOKhWW//9e/Zj7X6bY2GJ5Of9miUZkbxpzAa2CtITVcoaFqhurXC9g/6hepcHKv18JArgBAAIoBEEAF8KEkYqVazbECQPAsgAGzmt9XaZjA4UCpG8i309uOM0ocUCLC1gJ31RzqzSh7De81lD3tfpC92V6W0OWPbuHsqn/gMkGKEADfjQCDQ1MYAikca2hZbFc5pbVCzb8vB95kDr7cavbdIfI1Gb7xRoTVMwDuKHbtE7bj6SaZqVuFbdL27T9qNT9yBLkAJfWdVy700Qx06rdzWzlfbm7EZe4Wu96WLOhOJ9+xPkVXpYdZ+dBjnJAtiBG0prBnHwXk6+L3PLPAT0X1/Eb3arbSwffWdgBpPrxjfrx0gGZA3ZJV1L8fZrrAk8xJCo2CO2ZixRoEyvJBLhi1rEYWk+GQEVlM8HseR1XQ+yb9po9oYNuSUhgByw5kOd7rUXIwJD6XPsIkaA0GKItbxm0g3c5eOCzniQQlKUwZf9fvDcdIiIqhoTElk8ZdIbPORRQsgVfK0DXiIZqoSOt5XsGPeBHDhPM7MTXBdArYqN2OMhu+ZNBX/ibwwMv+/DV0UxgnPUqQOOEIohYFhoABYCRrTcD3dAEblOZSX0myohFy5YFhja87TLxrIwInBvMJuxrci9wXhMDa2+Zt6/KPddJcXOwh93e3mhi+7suFbsqAXNlHk8GrpuUlKXDyXnzxMSG4KglwcHJX1NpDXY/++npl6OSbbpdx9Twl0YtlVflZ2Iof8P3TeMj8t4YVVHP+GzM1oEJF71dano2q9fJYenSwaMG9e/tNXNe+uZqplNblXM9YldoZWfH5iVXzWsss3Cq2VqPvWtz3W6O96scvXR4x/tBTsX+b35Db6vDktwqrvBu41nym3DV7wH3V32NBXiVEjfTem3txl/dD3BCLfD+XpLGtwHp/8+PEVwP6qMX0JL1lfpEYSKxbOl1zznSnEYMZyDZw0Ij+DmrUXiwX6NJN3HfGNbYGMon5GC+D5rqpp0+emqnmwYqaKyT/gbopo/eTDnSZclSQkWddNBJL+1h15QrleWzZQZOGKk8vTtQBf1hqF0GffKmrA1imUE+W34jZCbPy5WmvW4GXiJi8ocV81B9mO9i0MST/Ze5uKKPvoYZdtNFVwP3N1z0RVNNTVXRhMZ1ZPWVqbKfxA4gAvzAJU0KAAAA); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAARQABEAAAAADJAAAAP2AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKghyCDAsGAAE2AiQDCAQgBYJeByAMFBtNC8iO0UvPCUWZcpJwSsfD136v5+7uD5ACBB8XFy6xkIDjW1thm7rqql8boQqoCHVt3s/nZS8DKMXPFFRmSv5168xa0+P+hZV1VjycCp72Cp8q//8vbTB3fppg6WL5OfPORDxCvVJpVjtQBUkIV8NbOmDFEC/6jvqO6lUarPy7KNAGFOUkjJEWg78JtemtagKFAlUFA7fn/CIOkJIkxPXEUJcaiokUDXK44BFWts+VtkLh0Tc8Il41dx1EPwkHrkmox5+GQaqlY4ySIiGjk1igk8QoUBTB0be5CihtdK1eqelEV1kHWNwSQLPf9oCiHp0XqLmHArBDz0EjX10UJwC1iJCHY3lqSZwAokUBqHkmTgDxIvLy4jBvQ1sIRgSR8i6CvKivvYuXhCW+1nd1E5yAeGg8xyEems4xfCGmnY1ujLPjBJBswSRZgmEJ+RYzn4985EycANLFSsSLw+va6tt4P0vzhSymGQZ5+Hd1bfw7lmYwjhNAdklfUt3OOa4LeU42T5KKDWKNzEcqmJBKNoSBC4TQJARbZwUKqKawIMDsaXGYR6D8++0t/wRDo2wIIx6DaQazcQIoFysb2zwszTAYqFTnBVB8rkbBqaFhavm1AllH10swwCgadCZVIQfu/H8L3ps3EyycFTZmld8ukB10pwQXaNGl1ADABxKCuGAgFiw/I5Dd9BAJoQgTQ5UaDvgIQiQXhWgWJX+MQI6lx0mIR4IYr9RE4JrUBJDt1yW9qKqSQQIlwFXcAbTBFZceY7ixnRxzD9kuUf09p+3X1XtPPzkL/sMjlo7W4WH7caplSEU6j4C/72wraRkKPzIQy6tI9J/9OBxy+rT9+HX17q6j4B89ASdPPx+0HrnRTLLHh+3H2/59eAOHT3ct8o2M6KsWD6TTOav/HfJCa+uxj7i3+XXL1qKz4hLxQlFS8xGP+G5rRWK6UaY82PH1m9uTu91nOVhQf/yXKQglF5T/j6g9nvjK/togMmxNN8ZPZSoO3Kmb9BQGOo6/dCks8rXS+gMvNZrnz9prpE/mMpqgEHCreiI2imYF8mDUi4HY+sX63P8Kdf4NHy7/CAXgW0zYobnv1VyZzqsBNEkg+Nlky/8B/fG3U8ENoK78wFrWTemfGcwitS6D7m2NLhCL0ox5Y4U1dPpiTTrUrdkysl2GrTX3mWIN5ufAOZx2Ky3TjtOoRItua6zFWWkFJEW8JElysLp16rZcB2wjqWJZOVliUM7hnd5ep8QaFGvPsLKMJG2QSgzKydIbMZTcLFWcDpx1l0ggflw2jzXAcq/1Ew+uWebjxpVW2ezM6dVn3fbNi15EqrQp1UrM9VZdl6hRF7kQIAgWqPKwAAAA); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAARsABEAAAAADIwAAAQTAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKghiCBQsGAAE2AiQDCAQgBYJeByAMFBtGC8iuA2xwfQMNpVXW2LKcYgxDZLO05aK8Fyc+hxsPfGusPzuYWqWJaSNCpZHJRCohWiZ0a3KX7nVN6/9b93VTqdaYr85fDVpCBv6oBrDsjLWDM86IS2qvtTBxzf9eZnKf73zDDXBtlaIDjhJNng6vUVCiSzjCCEuf2ZUP/iRgK+9/OP/CFQeacLHk/n/35se9f7YJlm4LuLPnv22iKzKzvVBNYrUDVZCEMNo7WMUoRzxfPYPuJgXr71cigAIAASQYhoE8s8zCpmbyyuDLBFIABq6P8XEYQyFhgHCZ2J55AmFBErzBgwtEBWuW9jIrkfQioXNiMwXRA2w6M8GDn++AJNP4h5YtU2RjBBU4lgQyEciwlMGLJIU7k6/eyzTJ+5HPAAYWNShre2cYNuxr9vcMZBovg4KfnvhrgANE6XaaYjWoAQ1ogH2WvwY8QBmKM6OkyiFIksxeIymDPCvXKJNYtr7KKUUgKZT2bFIo71kqScx0NjiFiPHXQLZgZl0K2KHqxaxakvf8a30GOpBLikdRVXGVGszMVElpYqZlUbq6tVZXt6bElhD+GtglZdLvs6ddF3gD6yNlwgaFUiZJT0hZqTssuOKmK5YOYe2rmVBTtjRmL+ZM16zX2se63ZqJRCz4WWKmJdL8NYgDuaVV6WkVQSUskD43PggmAkcGhZEjT1XINDpdAwNMlWFhGZI4hBr8W3hvnk3gcFzwGDfyfIUsoAs1iCBWRXqVAF5KkHFyKJg88kqFrKKrNWigVTV61QFeTzBwRpiYMfJmhWyhWzXYYFdtenWAYOe9AJEvwzQsBQbQYiADuP0UXAAK4C2xZ/aMFplwrGLHy76t50fSqTrEsLM68dW7PbrXzpF7LzxZfnTedf/tmN425CkQgyM72FTTsw+P3lfXFbvu5ZEG7zjbytd1NWa85HJGQOXu8hfk5wNXDP3Xg/d+LThFv9Ne7SxprqtLTv9BIzVNTPGWfyg9rw9MOtgftnfaKPHWjuGGLTsn3sWjOJ2zA8Z1Jqc8rLavjrHu3XM/lz6S6e0Pjo7YNLT+GV3rxJTO8iluL3j231n7+ry6++y0CN73jiNsb8GVAK7SonITDMSGeaU724aXj418JZD5R/g4vDqAn+bOLf9n9I8tkMMABPjT1DN+G+vfXoGbQpPitTabTJIvujELlTGZdq/LtgjHMvwAfd4WbmaSB27DGNrNBZCbzWG3l04TCt7m+2CPbaUGtVaylUpVwalZC1uDeiRUgGDBYqVxWs2pzio4TsIsZN0QQYGApYzp461SNcPCygwNXRK8QSUo6IaIaBQoOVgYf6vYWi9RIr67GF4ogV23tok7Ni+T3N6gUZe/zc2jdfPRix5K8lTJVIlzE6UJMvLM0C8hAwekJtAPAA==); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAR4ABEAAAAADLwAAAQfAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgkiCMQsGAAE2AiQDCAQgBYJeByAMFBtyC8iOwradM1YI0gkehDEKJx6exv137swH0aT6E7SKUIhwKHCoW+rb+ENbqMMVnp/y8t802d3Sq0llTz9bp2Z6nU+fxHxP69MHfDjR/v9f5uDe+dsESxfbv2feNtEVKb2md5AKkhBGw61oQhWjHPEMewbdTQrW369EoAkQSEIINBiigdY388rAUBWUAgNX5/w4NoKCJCHOJboKhEXduhQ1crjgEXYdOJpZCUn7wXQVd650gegeNq7m0cM3TwBSdfqPsS3D5GBGF04k9rwxoEoRk/3g/wVX1+6u3qnW5f3ICsDMHgPTI0fPIPSAMPT/OoO04Wkwlc+c9meAZjBOF9NktHqWgcEMAzQl+DPgZnCGzLlnlFS5Ekwxza6nOAM319TLvHsSbH1RAyWBWIbSoyKWoeyoICcRtbOvgZAYfwb8FowvUAKruGUxawmS9/zrz0Axk4tlzqOoqrhKltLUclIaUQsCTpeXiqrkpTS1QIg/A+Ulg0l3XHS8LlRF5RTJGG6QLGVB0iGUVgquAtxGqZq6EutchoCqksoMZm/k3NMZkoraR5KroEa3cRVcBaIWSJo/A6OZ3NKq9DQRoEGYNP5c32CoMuRMYMpM3G8mkM3pFhIsYSVaaqwVSRw4k/4WvDdvQ7Dl7GDP7NzvIJAd6U4SnKEWneWqAbyWoOP0wEzvfkEgu9BdJbjBXXSTqwfgPQlenDd8mLf7fQWyH91fQgACxQC5BgHH4CGAbD8t6YNKkUECVQEu4TqgCV6zasDHbLKdVlz3WUBTicdnI6+YrAm/8Ei7D6S4I27nG6n9djRVufjE9cnx1jcEqWwrSPPlj7y3gcSMqcf2hZJDx4y33n3odaTmyiyaMqZhV0FyulfHd+1GKJ430GN2Q73jybLCHpQWHHaQ/4jdtkcg2e48kB/aJno8ufglzntbaW9FZVVSxLPMsA9PAgOLtr+I/Zip7P1jF1C+ap93wW6L1AuGHl56h1URqna74tBMn5llJlZW5l1jOzZ+j+vlu0pgyozV/PfuYb/amQJy1sf28/NVP83VW+K1AXU1vK3XWUvjc0dLLXLqKlddAp/OWZs/KuIqbzyeDAqGJMDZcjM7G/wUyEPebwcLTVa1xn01NMkfAa/3v3MD4I2v++b/b4s3/zd3A3USCP4/hapvA9r/X88KbhgtyLehky2k9IUnZpFdkhH3qlrHcaKqHlOeF+bQ5bI5aVExZ3Po4aphc7VrrJM15vvAUaIandrUEJVKVaFBj16iTh2wUAGCBYuVpkGdBu1q4RwWxo+1QwQF7VgZ0+f6pOpByZoMnW0seINsUNAOEdFI4uRiYfzVEvVdIo356WJ4sgS2m/RPPLFnWZDrO3UZthc1adZ3+OhFL8XyVMlUieP6K+cEGVTAazqADrYwLsE0AA==); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAQQABEAAAAADFgAAAO4AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgWSBWgsGAAE2AiQDCAQgBYJeByAMFBsbC1GUDUqH7Odh7IxoGdAyZ+VKI31IG+puNXjodbX387MnouFEl1MRRHRhqES1VKlMtIKOISiD241DCQiDhm2jwug4h/F0czljYSdX3cOj22euhLmER84fKB1c8IKrNX2Z/QvKuEhg43KZ35CxMYpRITpAoVCYRMnYAuuqKkBZq8nI/qhehcHM328JArABAASgIBAIwAofPkRBUUUDFqgAug4wcreUd1uJARQUQExIladIyGJIEWZI4QF2grmKLW4m5xfRR5UT9AkgJ7CyRxU73jwBxaD8BxoDoAAScCERqVxFA1UgmucW6TrL58/dvGjABX/Jg2XGhmLV0FeID6vQ7wpM/oeF7F5aBRoB/MWJ6LEKMiowAq2CjRCIDA76ZBhCLSzdh1oA581e1ODU3XmvQ9haAuGjCwg/oeRw1l06MJetQvYgaipshXm4riZXN3nNv1WosQEiQ7rUIzGZrOQ4ziKCl0tdkksui8xWYbd0p6XbJXVf4GkWQWJih/CAuUmRw8W1lEE4FYZlGMj2QRVQUU5WWTwqg70KU7e7bjKYRSmD4jLOIjurSGNjQN4BGXJY/a5zhEhQGiyibW8zaAfvcvDAZz1JIMihsGT6X3w3HSIiKoaExLZPGXSGzzkUULIFXytA14iGaqEjre17Bj3gRw4TzOzE1wXQK2KjdjjIbvuTQV/4m8MDL/vw1cQYYB77IEBigYIHoetIABQA1Hy2EnSjDTyJkuE484Tf5ramh5g81rocs1ocst7tcNtjscB9g/USz00m68ZGW+G6znOddMGOy9yXBAcrCxu3Ydo4LnlJszd/wmpx0Fo28Wj8j4sxpU9+M9e+5xrm3SWp97uPpC0etX5yQr3BR/ZEJE6cYhE2rW683VRG197ZcNbO7vTaWA/DvhvyT/f61zFWXh4pqealzR72892/TojKtRZ5lvM3pLQ8emCdXG6oaZ1i9rys9AkfYnH0Ubd9xl8La/kV8HTP7yCAD5HBq/WP+q7+kxMBC5QVPjMlpf4dkf7/uU94XjRALmUUGyjKD6GYiHic9Hl3mdNGIlRLIMLzUidwcVmnYMcpnSTK4lV1XGdgBqewmfV50GKkXuON0WukevmaDJpkspHGG0cTL0qsWOkKDOo3aKw+2NMkMLJCnJiwkK5ofm+KfJNQuDeH8QVN7A7xmLAQJ6kV1tLjEgzVZ6Qpt4hqfLc0Hq6DheGmztw6aZ2bq8abYKbpSMONMGX10E1P1FRoUayZxHOlTyBG9RRhI8EPXMAqQyQ=); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAP8ABEAAAAADCgAAAOhAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgTSBNQsGAAE2AiQDCAQgBYJeByAMFBv2ChEVm7/JfibwZHiNAF8Ur3BUq+BQX17m/XLwUO9qvU5ndgfx9SxVHURncF2XBFMJ4ha8Mf2GE5e/OzJuDriphvh1jYEGWBllHwBXlx5m/9IESxfLZX7nIx6hXqk0qx2oguQJo+FmoXDFKEc8zxIduA2s6t+vBAFUBwAEYCAQCKAqqaQi0jLyyghjAgQBwMBxKV+JrVBgYABiWqLRnCI8YIgYpHABB8FMnpNZSZ8bn0g9clowDaJ3snWYKY58/j7ACBlvAEUIMAAJxCERQBwmCjAxEXDjkyAAudzGqxdCxPFHakAkVyMWOVeF2OxqEazWXPXvICKHDolqYESp9PFpvhgW1aCIBrawoxoiojJ82TijxGnoKk952aM8laHGDR/lm40TV+tVoz23tfL5nPHK53dsv49rOQujXbdbVENuQc2k51JOTVhMJ7jEe/4f1VCRXOXLJkVOseMvS7P8PmmuZdsq3X9c5PiP0yzbdaMa+pKupLh4fNJ1gUnRLcQou0GoVHaJBdfzKsmGNk14nuU1dC1RLZAUfTKa2cOycboWy4raa8sa2hYnG9rqJa5lu2lRDRfJLXXS0yzbdqGGF9ewn6tgGQFEKggvEbSMV3iooHGqSpf1YbC37Ld4b9ZAmIwFNrWEdwjaxXs8fAg4X6oh2AgRMwmkNBE+I+gcX/AooeJKqdZgG0TLdNDTTviBoEf8xGOGhZulusJ2uwmQhDFIQgQBEgADADOb7g7kQRP4+0ajxJkbK24lXH5PLLf2ZL5fbcO7xMUve6es7N3y8g0dT1XbtQ+8c6frVbys6iXsF8svVDs1/Mt3rV3guJ3Pb9k5E+UXifPjfm7TZWfDdn7sgazCmMRQKDGv+iXxsVH9pdX/rDi2c03tHV44PGFdZkqvfaF2rx8s/EOrllLD7mYaYkVst7t1qzo1rwIABCBTmwcfMHdorR7/hqvJHwA+2G+NAL6u8fbgm6C5+Z+cDoQxFnj/IEnz3wH1m+8icD3cRJ7glpuG8TNNBSpi7TSveyyWAUiEWQVowUeFURDHS6NBTbRR0gpv2Rw2hphH3VCM+T4ZnPHDp04aPr60f8XoGTPHT52itNdKW211lzZ65OjJI6iudBCR8+20CfLdZUyvz+o/g0PDM5iaV9puEGsT5Nvp1AipZL8OokaMn3WJiFK266aESig/dvbEjTOWuRTt1GnzrcePHTdr+dxFDyp5TmaldJ0F09qo6DYNYjCBT4OWAAAA); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAQAABEAAAAADDQAAAOoAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgUCBRQsGAAE2AiQDCAQgBYJeByAMFBsGC8gepyt6cCTJgI18vrb0D0NcN+91iKiSjdoS803FnNTsZHajTm+qwuDNvd49gIEthEji4fP2ViVWIOuLlVV34SzQIQaejCXOvl/Tk7cJywgHbFx+5l7I2BhDRC4F9ihUlawiXd16QFmrycjeML2Ewfz7loAArAEAQAAcgiAAS168kE1fXA1zPACaBsDI3bS/SJaAAQ4HIDXVNtzJfI1LpqDJA9yIXcUlrw6Z71H6qHSYNgygFUtaebLuwQ2AG7n/AMYEwAEowBlFUg2PgefJePdRTWOVI23ztgln/CUbQOiuQr4MOwlZJKlEm63imQ9ARu/mMBUwGMs1igppDVOBQgXMQpgKHEyvUD99pcFHYjKTCzplpme9bZ0K74cDnffqkqUIpoAWI1PwFkHJlHTuvi5JSg5TQfaQ8nlZghXWt1raFyCv+S9MBRNFTKH+5YYKgzJN1CmZoqQTBJarHCw3KAdFnSBJYSrYWwbSzmSj+33BFdhM0vwOiSoWIG1Jlmt5HwFuk2Wd7CPZF6oEVJ5ZUrF4I/XLVcm08u7hNB9Bh/I+grhK0gmSGKZCiKIZ+VwRqgUpIf6ud/BynpEgSyXXKxxZpWsCdBgSXWnymQwcTftf+G7WItiMA1fquN7jyD49EBAikoRijQGbEFImQy7NXF9w5JJeCajRSGqxtoDtCD0zYJQOrp848kxfBKzYJKtYd2B/vCIAyhzHHfk1FABwAIAHEEAOoAbawIPIOvGxpXzddRVZ7bb6hk3tdNfp+yzlfZ5rr5Ppom/l0r/arvffsMqv7Me33Xdz9VXnadc8gmtqrh3DtD2W1XiU/k1rYoZZJ1remZHDu0+wt+33z6Y8qW0MNBPLcl5Xr7b8FO6t6+KGEyYOpjuGUD7br9ff1LL60Bn+Ei8EWOxIt8g0WYaf/HYY8OAUyUl3i3+OViNMnM+hU5DTmNI7LXap38yt6EsAuLnpvS8APAnxW6Y91YL4v3Q4AHMcACBgktTBfyOq/29De8S8CF6BPqBMx3VvEJDBHD5axgFaM/XokcECQLDbpYlwdtzEsaWaqHDycX7cZGIcx4Sp9XmAgVGboQZpY1QlR60uI4xkNNQQTIxwUaKkEHXp0GWwdrhgYoWyVrTI0A9T+vmLUXKMgIm2HENbTNQOmciwFS2+lWDp5WKFaWc06hYpxs+XzBOVsNVj9MwzR6wLcN1Qw4y3NerRa9TxHTe9lSlmkKcO5fnShiFSX0W/hEhhQyyCEA==); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAQ8ABEAAAAADIgAAAPhAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKghSCAgsGAAE2AiQDCAQgBYJeByAMFBtDC8iOw7jhK61Mllg8cBRB/V639y6lq9CK/nlUoXFdli4cg0JabNRXEo/Q6Bz/XjZZo+BLQS5KpfLWuu2dc7ByzslfoP/g/fs5jczLLxkJbFx/L+9S42sMIY/QojCrkrPTBHaK5ayen5DLqF6lwcq/X4nABBAoQgiM7LKBXejS8oCnAysTDFydeR2bB2yKgvhMlC0EBW9FCQ5kuABWYcvVvb4Q4pbv6Ryzw9QBonvAvEoWtvbZPYDSZfzH4ZYusjMxxxSJEssh6LDRXr43mXDmemv1ctfc+5EtQL2kQXRXtA/D5hA0ZppCg2bvKIjkW7k3DVhFSGvQUFilNw2MSgPW4N40MCvSUUxnXU6RI4FIRCbXkkiHGqtqKZZz4mh9UR1J+CIKcu8NiIK8e5yKI6ydHXUEEeFNA2sLwoqTBMygpsWkyUFu88+bBnZNRRTTJasou4gyaqyxX0O34DjSUmeyioLDGmucILxp4FzSkVRGDRbXBW6C05Awb4NALnOQMkGSlbgjDjeQpDXpSFhLaQyoNC5Fw+zVTGctjRmz2ptGR9waxR1xcRvCGic03jTwa2pukVZjjeMEUIBgOQ28z5XyKCGIiFB4MYOW4KU8ZCDnZHIFG0eBJeP/gvemlQgVpQYzohbenEFb4C15WIE1ZyVWG0DbIuwoe0DEXnicQTvgHXk4gTPnJFYXQLsi3Ch38CDuwnsyaC+8Nw8f8OV8xOoHzP3fEUAaKDZhK5MEBXSQ+AC+QBO8QlYbyxLSbInV/oK72Lj5VuFM58VgVC06KCAXgdH2jnox89+TiYtAB5pNt/OqpuUd7jIZu7SuXp1/OXJMLC4TCKbH82Z1OzfwL4XKQ/l33BcnDy3v+oNu70K2+dtOzua1c/KC7V7/mDBhWoNIcSVpk751rlwRJp7yOcfPbxrLw7lHxWBbWOLL+OO8F1Nlu7d5cY16n87javWMcdatXlk0zjYbS/OfMGnK9oOfQhb+EqeLa6JErjcE3cI8fqH8wp3HYgYmu2qWhv2P3jZ33Y2Pb3yqkEZ94wmZ7wH43fjVCYA/T+cFptcm987f7AQwUBa4/zPxzv+A4v/n84LrQiP5AylsVMoncMUkIufS7V7V94gpOnyg8bDQhblLumKm1aVj5NHOsK7rmyLQM98H7hlUadeiikGuRAXqdOlm0K4NEsiHP3+RNOrUqNOqGg6QIF6sFMAvsMOQbvqgR6IuGKjKoL2E+G8Q8QtKAUIaAZRcLIi3agY9lwghfrYIHsiBpQa9E0/tWubgqnYdBk0NGjTqObr9opciaYroFWJyba06+Km34LaQYAcqECRhAQAAAA==); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAPcABEAAAAADBAAAAODAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgRyBIQsGAAE2AiQDCAQgBYJeByAMFBviCsieg3HzcaR6hDg+8REeiGxd22NrRzw8LW3vz0yuNFWbS/a67VVeR9g9h0RYhAYbHyXRIDR6/U9d+bTeIwigbyZfB4heB8k6Ym8AqFOY2lwqXSqFsGQowx3B4M293j2AgZXFidf/5P6F/+/Uw/xcp9jYYr2+/C7RCu1JYwONCTSBSlgNdy3gYJUr3ohih7FLHMZXIjACCCQhBIbMi8HO7AkzEKxA0wAj+3O+y3aBIkmIOtX1cEZwX4pA5PAAHkGiu+fRs1Hd/dH9kev/NeQau1q9cfLNE0gtzz8sC0BCxjhDQHuvZVC46HV/NFhl2uDmtZZx/yN7QHWrIT45/YztEJr9n8a1cJYof2vO0GBF5HMtxVozNFRpsM0zNFyRrYwEe5oTJ0guy+tOSTb1tnUqbwIOdD7VJUUWKfezS8rzzNWRMN25LiFKMzSyB/Xm5QuskH819QfIKX8zNKoaTyonTnGmOmqjZeInLWFyTj51ZYqjrlgmFyJDo28ZSOvr3OH3BaZAt0ma3SExnQVITUhZy8dxOCalKdeE3aoDVFld0hYPGgk+zTZO6e5sjOMmOiWOx3FhcmFlaFw1frrjs4SWiwT/u77BKllGAJEK7pcIWsYrAlTQeFWtc9UMZz9+y3ezBsJkLLCp5X6HoF28J8CHgPflGgI2QsRMAilN3J8RdI4vBJRQ8aVca8A2iJbpoKed+weCHvGTgBkWfpbrChy3NiA79yXTWAMZJFDyxC6DI6AsJ6TlQQvk6SNs01HzydLJeDtYyveezH4S1ncY/4xDMx4O3/d7xjb7AGNHkw6OPnpkf9//OfhG93bYFn/IkFU25MxRfczlwf4MPqpu8NGw8fc9FZcaOmlD2FfYU+0Cz9+T8fZvLXCw/1HtS7bEGDzn8UQdCQQI5PmU/8leWUvU3tfgYeMdwJ9fX+IB/nUS9jRJKX/yF2BAAkGu/9dQ/jf9U/kjeOE5d+Sf+DCk9BFJAOB2aAp5+/q9MkQJAW3PS3MYd8ucjOmZsw1ysYybW74bmOgz0sEzV5sF5mrjmq7OLF0WW8K1wHwkT6YcOcpYunToMk87FCP50pFc2WG1jD1/dqk6i3Vpw7CgSnJ2yGTjaq7CVoLS3fJlaOdaeosU8c1KeWIarPZYNnPt4nUBrl9goVX2rh69li723VSUTOAYbTaD56+pZWv10HYkxGACXwQdAA==); } @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAARgABEAAAAADLAAAAQFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgjyCJAsGAAE2AiQDCAQgBYJeByAMFBtlC8geg+NuKcNiiSWmINp9/h4P/7/2+33unYdYMm1mkUxzD3EioVDJ8E0aq0+JP9K/aP2V+fk68/1MyFX0Z0EGS2Tqhdik9dS6wVNPzZN0uNEFQe7//2UO7p2/hResdLH9e+ZtE12R+Vsr1qKlpWoFCmE0VJrleDpHOeIZYcwwdonD+JUIdAACSQiBNsMM0KqtsBKECqhrGHk45y+xGngkCVGmlgpiQziXokkOD0LC1vqxvQYyHxF9VaL8X4JcwuprLnr79ilIjfSMcTwkZHQjBDJzjaPQxfAx/testL95s6Eb/8gKYHaNBem24yhCdxSL/t+yYBk5A1L5alYYC2gWY2urhUFzwljgzLKApskwFohZbGMIP1u5w4fCNKbzGmhswy21DQzXD4vOFzXSVARmoOK4FTNQeUwymZTe3dNIUclhLHD3YNwVmsI23LaatQnymX/DWODNFmCG8C91lDkYp0XPZFooPUliK3O51MFctuhJigpjgX9LkbYmWz3uC0GVP00Kwh2yFUyQJkXTtYoPCddoWk/7UPZSFgE1ZNZZWLxI+FlZ5Czt7jt9SD16jg/pQ1J6krKEsSCaLahwWC1CpQJmxb8bGYQGISeBlEmCL5PIcrpCgRIqWWlS6zI58Of8W/DdvIag5XRwY7rgu0tkD7qnAi/oZS+tGgBvJJg4MzAzB5+UyN50HwW+8JN9teoP+ABCIBeEYBYU/BCJHEoPUxCOCDlcq5HAN+oTAWQtkn6ormWQQIGMErgFbfiuPBtgrKGR62nBuadPkWujuPJRG73bbSNyuW+7JTn99NZpyTJw7jOPSs+zvqzv/V633VuRSz8tI6ag1bpA3U1Pa56Kmx/rNoCzez08mlw/faOb/wuvTlVs7aiy3vgMzgr/a8J6zuHN2vXNP6nMhUXvnuobI6bJUUvXvTyX686ZU3C7XTARk1KNijiaekGUyc0tMyCjlvK3n/qyvBpVlvoWSDWhwmI3N0ltUvIufnJyncBL5B9qEQ4RC7n5XtM4XXlS9ejtFfGS3q/KXQ/DRFsDQrSdeuNfdIhB73uNvhExAo2hPVY9/ywABPJwkJ0zcu1KkfpVKMm/4OnjO18Avs74rf2/Dir+5F4ALRIIcvm/BMX/+vO/4o/gJZyH8mtwQEjprwmrjmEZJOihZqcIUbRi2ovSGbrddCZdKmc2jz5ZjDsbbqizTeY7wLFWtbp1qNWqQo5qjfr0a9WtCxYjXJQoKSwa1YeNTnVohsUKZY1okUiFedv82YAcfTBbm6O7gUXtUIwMG9HiW1mcXi1WmDqtBm6Rx/xiyTxbDhvNBmee27dOcGu3HqPerZq1GDi576bXYoUc7GoQvGh1KVK3EjgjYYIW4hrMAAAAAA==); } @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAAHwAA0AAAAABBAAAAGhAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGx4cNAZgADQRCAoALAsGAAE2AiQDCAQgBYMYByAbUwPIrgpscEcPjAqbbfFGeKx5Kz5EU3R4bDzUL93bvX8JXUVSmorE9SJxvRjNeBQOYXEOHSway/n/P+buVKO/qf2JJVWsT8RCwUokBQ4hUxIh0zx2kOoSixA6//37cw+I33LHb5EcSZbiLwn1l1CELdAXC7/Ia2HUcht7no7PES0JadRRYMAoA87WTvMJYgUaIDBgDsM3u00398MKuofDeAnda/+0gQ7Y6yWfIrW+/EzgUNU4x/xDBFjZOqq08QNClf+f6uoSTsInxFsCk8RIVOjgCel8k6AoApMN3NH0cADRkCBBwaAYFwg+3u9CxZ9YxvsDevfuFsDP16+mlcs86JMgeJ5qrXFd4uBUWQ2UIgTSN4QgEQJrAGg7xhNFAl79NkLHN9KIL1S6XlHMGqC2wm7dMgu23Qz1rcxNbG2cBDwYmzpb6Tt4MXZwNLe1QSKCwvXjrIqVu52ZIxIVxBC3KIZJ8px7SJ61Fz2qaMtGEnnLBb26c3cwNzVzQtyGPAgTxsSQgTtKV44c9F0FkZyVFcrjcfBYND7qYmwkiAc0qxEAAA==); }</style><rect x="0" y="0" width="632.0353021317197" height="468.12524655748945" fill="#ffffff"></rect>버그 심각도코드 단순성<mask></mask><mask></mask>
복잡도를 올리는 방향으로는 점진적으로 빈도와 심각도를 낮출 수 있지만 수렴하는 위치가 최적이 아닌 문제가 있고, 복잡도를 낮추는 방향으로 가면 점진적인 접근을 시도하기 어려워서 문제를 해결하기까지의 비용이 쉽게 예상되지 않는 문제가 있다.
회사에서 복잡도를 높이는 방향으로 문제 해결을 요구받는 일이 많은데 최적해로 가길 원하는 엔지니어로서의 자아와 늘 충돌하게 된다.
개인시간을 희생해서 문제를 푸는 데에도 한계가 있고 (풀어서 갖고와도 도입하는데 많은 설득비용을 써야함).. 그냥 회사에서는 자아실현을 포기해야 하는지 싶음.
이 글 보고 ㅋㅋㅋ 민희 니가 여기 가면 생활코딩 되는 거 아니냐고 조크 던지려다가 제지당해서 서울지구와서 씀
@hongminhee洪 民憙 (Hong Minhee) 너무 가고 싶은데 육아 때문에 갈 수가 없어서 너무 아쉽습니다. 마음 같아서는 유튜브 라이브 해달라고 하고 싶어요.
@curry박준규
@hongminhee洪 民憙 (Hong Minhee) 아이를 델고오셔서 인류 최초의 네이티브 하스켈 스피커로 키워보는건 어떨까요?
해커스펍의 정체… (거대토끼의 맥미니 위에서 돌아가고 있습니다.)
무슨 이야긴가 궁금해서 찾아보고 …. 너무 귀여워서 비명을 질렀어요…. 토끼가 전선을 갉아먹어서 서버가 다운되다니……..
저… 제가 아마도 해커스펍 개발자분보다도해커스펍 서버와 가장 가까이서(2미터 거리) 쓰고 있는 유저인데…
느려요.
RE: https://hackers.pub/@hongminhee/0195d567-06d6-7437-a4eb-cf567adf9714
Hackers' Pub은 과연 언제까지 우리집 홈서버에서 버틸 수 있을 것인가…!? (걱정하시는 분들을 위해: 백업은 6시간마다 정기적으로 하고 있습니다.)
@hongminhee洪 民憙 (Hong Minhee) 이거 누르면 어떻게 되나요
코딩을 취미로 하면 학습, 창조, 해결의 즐거움을 느낄 수 있다.
결론 : 코딩하고 싶다. ㅠㅠㅠ
한국 연합우주 개발자 모임(FediDev KR)은 이름 그대로 한국에서 연합우주(fediverse)와 관계된 개발(프로그래밍 뿐만 아니라 문서화, 번역 등을 포함)을 하는 사람들의 모임입니다. 실제로 Hackers' Pub의 개발 논의도 이 모임에서 처음 나왔었고요. Hackers' Pub을 통해서 ActivityPub이나 연합우주에 관심이 생기셨다면 한 번 참여해 보셔도 좋을 것 같습니다.
참고로 올해에는 아직 개최한 적 없지만 비정기적으로 스프린트 모임도 하고 있습니다. @sprints.fedidev.kr한국 페디버스 개발자 모임 계정을 팔로하시면 스프린트 모임이 열리기 전에 미리 공지를 올릴테니 미리 확인하실 수 있을 거예요.
Juntai Park 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 를 가질 수 있어야 한다. 가령 온라인 게임을 환경으로 삼는다면, 환경은 네트워킹을 할 수 있어야 한다. 또, 에이전트는 매번 똑같은 선택이 아닌 확률적 선택을 하고 싶을텐데, 이는 순수 함수로써는 불가능하다.
그러면 부수효과를 허용하면 되는거 아냐?
맞다. 나처럼 시간이 많다면 직접 해보는 것도 나쁘지 않다. 하지만 정의가 점점 지저분해지는 것을 보게될 것이고...
시간을 아껴주기 위해 정답을 알려주겠다. 환경은 에이전트가 실행될 수 있는 모나드여야 한다. 딱 거기까지여야 한다. 환경과 에이전트 사이에 그 이상의 관계는 부적절하다.
글이 생각했던 것보다 길어져버려서, 오늘은 여기까지 해야겠다. 이어지는 글에서 거꾸로 상태 모나드가 이걸 어떻게 해결하는지 소개한다.
사실 아까 환경이니 에이전트니 어쩌고 할때부터, 진작에 강화 학습을 마스터한 학생들이 이미 다 아는 내용에 지겨워 졸기 시작하는게 보였다.
다음 수업은 재밌을테니, 대신 그때까지 모나드를 배워오세요.
옛날에 만들어놓고 저 혼자는 잘쓰고 있는 React 폼 라이브러리 react-form-mozard를 소개합니다.
폼 중에서 Stepper 또는 Wizard라고 하는, 여러 개의 폼을 순차적으로 합친 형태를 다룰때 씁니다. 그래서 하나의 폼에 대해서는 react-hook-form 등 을 쓰고, 그걸 여러개 조합할땐 react-form-mozard를 활용하면 됩니다.
순차적으로 합친 에서 느낌이 오지요? 모나드가... 그대를 부릅니다...
폼 말고 CLI를 만들때를 잠깐 생각해보죠.
const name = prompt("이름이?")
const age = prompt(`{name} 님, 나이가?`)
if (Number(age) < 20) {
console.info("미성년자는 이용할 수 없습니다")
return
}
const gender = prompt(`{name} 님, 성별이?`)
뭐 이런 흐름을 생각해볼 수 있는데요. 보시면 먼저 받은 입력값에 따라 이후의 메시지나, 제어 흐름이 달라질 수 있습니다. 즉, 모나딕하죠. 근데 이런 평범한 로직을 Stepper/Wizard 에서 짜게되면 코드게 쉽게 더러워 지는걸 알수 있습니다.
react-form-mozard의 step
은 위 예제의 prompt
와 같은 역할을 합니다. 그리고 그걸 Generator 위에 얹으면 모나딕한 폼 합성이 가능해집니다.
단점이라면... 지금은 React랑 강결합 되어 있어, XState 등 다른 상태관리 라이브러리를 같이 쓴다면 연동이 깔끔하지 않을수 있습니다. 근데 평소에 쉽게 겪을 문제는 아니라고 보고, 또 추후에 설계를 수정해서 개선이 가능한 부분입니다.
자바 듣다가 졸았다
버그의 입장에서 보면, 개발자가 하는 일이란 하나의 커다란 버그를 여러개의 작은 버그들로 끝없이 바꾸는 작업이다. 언제까지? 사용자 눈에 띄지 않을 때까지.
Juntai Park shared the below article:
Browser-Native Translation and Language Detection APIs Coming Soon

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub
Just reviewed the W3C draft for the Translator and Language Detector APIs. This is genuinely exciting development for web developers.
The proposal would add native browser support for:
- Text translation between languages
- Language detection of arbitrary text
- Both with streaming capabilities
No more relying on third-party translation services or embedding external APIs for basic language operations. All processing happens locally in the browser.
The API design is clean and straightforward:
// Translation example
const translator = await Translator.create({
sourceLanguage: "en",
targetLanguage: "fr"
});
const translatedText = await translator.translate("Hello world");
// Language detection example
const detector = await LanguageDetector.create();
const results = await detector.detect("Hello world");
// Returns array of detected languages with confidence scores
This will be a game-changer for multilingual sites and applications. The browser handles downloading appropriate language models and manages usage quotas.
The spec is still in draft form but shows promising progress toward standardizing these capabilities across browsers. Looking forward to seeing this implemented.
트친들이 이주 다 끝내서 사담은 마스토돈/미스키에서, 개발 타임라인 얘기는 해커스펍에서 했으면 좋겠어
@xiniha 님께서 Hackers' Pub에 눈에 보이진 않지만 큰 기여를 해 주셨습니다. Drizzle ORM 베타 버전에서 쓸 수 있는 릴레이셔널 API v2를 Hackers' Pub 코드 전체에 적용하는 큰 패치가 바로 그것입니다.
기능적으로 눈에 바뀌는 것은 없겠지만, 아마 성능상으로는 약간의 개선이 있을 수 있습니다. 기존에는 복잡한 관계 필터를 서브쿼리 방식으로 해 왔는데, 릴레이셔널 API v2를 쓰면 JOIN
으로 바뀌는 것 같아요. 물론 PostgreSQL의 쿼리 최적화기가 뛰어나다면 두 방식 중 어떤 방식을 쓰든 같은 실행 계획을 수립할 것이므로 성능 차이가 없을 수도 있지만요. 아니면 더 느려질 수도 있겠죠. 거기까지 세세하게 비교 테스트해보진 않았습니다. 😅
참고로 해당 변경은 이미 배포된 상태입니다. 아무튼 고생해주신 @xiniha 님께 박수 부탁드립니다. 👏
Hackers' Pub에 글을 쓸만한게 뭐가 있을까 하고 생각해봤는데, 알고리즘 문제풀이 컨텐츠로 채우는것쯤은 금방금방 가능할 것 같지만 이런식의 양치기보다는 그래도 엑기스를 모아서 정제되어있는 형태의 글을 올리는게 나을 것 같아
이번에는 Grok에게 커밋 메시지[1] 작성을 부탁하다가 Changelog 작성하는 문서[2] 안내를 받았다.
이번에는 Grok에게 커밋 메시지[1] 작성을 부탁하다가 Changelog 작성하는 문서[2] 안내를 받았다.
@curry박준규 저도 커밋 로그로부터 기계적으로 체인지로그를 만들어내는 방법은 안 좋다고 생각해요.
코틀린+스프링 백엔드 개발하다가 지금은 프론트엔드 개발하고 있다는게 다른 사람들에게 꽤 재밌는 이야기로 다가오는 것 같다. 당연히 선택의 이유에 대한 질문을 가장 많이 받는데, 가장 특이한 질문은 OOP가 그립지 않은지(?)라는 질문. (OOP도, AOP도 전혀 그립지 않다.)
코틀린+스프링 백엔드 개발하다가 지금은 프론트엔드 개발하고 있다는게 다른 사람들에게 꽤 재밌는 이야기로 다가오는 것 같다. 당연히 선택의 이유에 대한 질문을 가장 많이 받는데, 가장 특이한 질문은 OOP가 그립지 않은지(?)라는 질문. (OOP도, AOP도 전혀 그립지 않다.)
그리고 이런 입장에서 BE vs FE 같은 대결 구도가 조금... 그렇다. 사실 업무상 관점이 좀 다를 수는 있어도, 다른 직군으로 분류할 정도로 기술적 관심사나 고민의 주제가 그렇게 까지 다른가 싶기도. 나중에 이 생각의 해상도를 좀 더 높여봐야겠다.
소프트웨어 개발자들이 자주 틀리는 외래어 표기법.
영어 | 틀린 표기 | 올바른 표기 |
---|---|---|
app | 어플 | 앱 |
application | 어플리케이션 | 애플리케이션 |
directory | 디렉토리 | 디렉터리 |
front-end | 프론트엔드 | 프런트엔드 |
message | 메세지 | 메시지 |
method | 메소드 | 메서드 |
release | 릴리즈 | 릴리스 |
repository | 레포지토리 | 리포지터리 |
또 있을까요?
소프트웨어 개발자들이 자주 틀리는 외래어 표기법.
영어 | 틀린 표기 | 올바른 표기 |
---|---|---|
app | 어플 | 앱 |
application | 어플리케이션 | 애플리케이션 |
directory | 디렉토리 | 디렉터리 |
front-end | 프론트엔드 | 프런트엔드 |
message | 메세지 | 메시지 |
method | 메소드 | 메서드 |
release | 릴리즈 | 릴리스 |
repository | 레포지토리 | 리포지터리 |
또 있을까요?
@hongminhee洪 民憙 (Hong Minhee) parallel 페러렐 패럴렐, proxy 프록시 프락시, shell 쉘 셸, basic 베이직 베이식... 정도 생각나네요
RHEL도 좋고 Debian도 좋고... Debian은 GNU에 너무 심취해서 문제긴하지만.. 그들이 없으면 그 많은 GNU 프로젝트들에서 소프트웨어가 나오지 못했을꺼라 생각하기도한다. 리눅스 진형도 좋은데... 현실은 MacOS를 사용하는 입장...ㅎㅎㅎㅎ
다들 개발할때 '하느님 제게 왜 이딴 시련을 : 하느님 이런 흥미로운 문제를 풀 기회를 주셔서 감사합니다'의 비율이 어떻게 되시나요? 저는 근 몇달간은 거의 99:1에 육박하는거 같습니다
"es-git은 Node.js를 위한 현대적인 git 라이브러리예요. 간편하고 직관적인 인터페이스 덕분에 복잡한 git 작업도 쉽게 통합할 수 있으며, TypeScript 타입을 내장해 빠르고 안정적인 개발을 지원해요." https://github.com/toss/es-git
Hackers' Pub의 타임라인 탭 중 “언급” 탭이 “언급 및 인용” 탭으로 바뀌었습니다. 날 언급한 글 뿐만 아니라, 내가 쓴 글을 인용한 글도 함께 보이게 됩니다. 본격적인 알림 기능이 생기기 전까지는 이 탭을 잘 활용하시면 좋을 것 같습니다.
'탈중앙'같은 키워드가 대다수 사용자에게는 그다지 매력적이지 않은게 사실이지만, 적어도 나는 오래 전부터 RSS에서 얻고자 했던 것과 얻지 못 했던 것을 ActivityPub으로 얻을 수 있어서 너무 좋다. 특히 콘텐츠 생산자 입장에서는 정말 참여하지 않을 이유가 없을 것 같은데...
요즘말로 '내적 친밀감' 있는 분들이 나와서 영상을 보기 시작했는데, 몇 번 끊어서 겨우 시청. 요즘 10분 안팎인 영상만 봐서 그런가 더 길면 한 번에 보지 못한다
https://www.youtube.com/watch?v=sqxR8zscSDo
https://hollo.social/@hongminhee/0195a85a-6a29-71fa-a60f-3e79c1295b05
나도 MCP 써 보긴 해야 하는데 영 쓸 기회를 못 찾는 중…
링크 미리보기 띄워줄 때 Content-Type
의 charset
파라미터 보고 문자열 디코딩하게 했는데, charset
파라미터 자체를 안 주는 경우가 좀 있는 것 같다. (주로 일본 쪽 미디어…) charset
파라미터 없으면 UTF-8로 가정하게 해놨더니 다 깨진다. 가서 보면 SHIFT-JIS 쓰고 있음. 😇 결국에는 chardet을 쓸 수밖에 없나…
@cojette gravatar라고 핸들마다 프로필이미지를 저장해주는 서비스가 있었는데 그 흔적인 것 같아요
TIL: git에서 revert했던 걸 다시 revert하면 커밋 메시지에 Revert "Revert "XX""가 아니라 Reapply "XX"라고 나오는구나
WSGIは私の青春を燃やした抽象化層だった。@mitsuhikoArmin Ronacher さんのWerkzeugのコードを読んでPythonについて多くの事を学んだ。当時のWerkzeugのコードは今でもPythonで最も価値の有るコードの一つだと思う。
https://zenn.dev/shun_shobon/articles/173450f5bec890
웹어플리케이션 성능 개선하는 해커톤 같은 것도 있구나 와우
Hackers Pub PWA 앱 만드는걸로도 한번 기여해보고 싶다
액펍의 특이점은... 왔다...!!
I just discovered why some of my followers from larger #Mastodon instances (like mastodon.social) would mysteriously unfollow me after a while!
Turns out Mastodon implements the FEP-8fcf specification (Followers collection synchronization across servers), but it expected all followers to be in a single page collection. When followers were split across multiple pages, it would only see the first page and incorrectly remove all followers from subsequent pages!
This explains so much about the strange behavior I've been seeing with #Hollo and other #Fedify-based servers over the past few months. Some people would follow me from large instances, then mysteriously unfollow later without any action on their part.
Thankfully this fix has been marked for backporting, so it should appear in an upcoming patch release rather than waiting for the next major version. Great news for all of us building on #ActivityPub!
This is why I love open source—we can identify, understand, and fix these kinds of interoperability issues together. 😊
KBLaM 이건 또 뭐다냐… 하… 먹고살기 힘드네…
해커스펍 흥한다...! 🚀