<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>정상우</title>
    <link>https://pronist.tistory.com/</link>
    <description>프리랜서 소프트웨어 개발자 겸 생성형 AI 강사입니다. ChatGPT, 프롬프트 엔지니어링 등 AI 활용에 관심있습니다. 예비창업자, 기획자와 같은 실무자를 대상으로 강의합니다. AI 전문가가 아니더라도 창업과 실무에서 AI를 활용하여 좋은 성과를 낼 수 있도록 돕습니다.</description>
    <language>ko</language>
    <pubDate>Mon, 25 May 2026 18:29:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>정상우</managingEditor>
    <image>
      <title>정상우</title>
      <url>https://tistory1.daumcdn.net/tistory/3751118/attach/164c179cc9344a14b5930c135120fe8b</url>
      <link>https://pronist.tistory.com</link>
    </image>
    <item>
      <title>hELLO 티스토리 스킨을 소개합니다.</title>
      <link>https://pronist.tistory.com/5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;hELLO는 &lt;u&gt;2020년 3월&lt;/u&gt; 첫 공개 이후 지금에 이르기까지 티스토리에서 많은 블로거분들께 사랑받은 스킨이 되었습니다. 그 결과 가장 영향력 있는 개발자 커뮤니티인 깃허브에서 약 천 개에 달하는 &lt;u&gt;티스토리&lt;/u&gt;와 관련된 모든 프로젝트 중 &lt;a href=&quot;https://github.com/search?q=tistory&amp;amp;type=repositories&amp;amp;s=stars&amp;amp;o=desc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가장 많은 ⭐을 받은 프로젝트&lt;/a&gt;로 자기매김하였습니다. 이는 제가 개발자로 지내는 동안 이루어낸 괄목할만한 성과 중 하나로 당당하게 이야기할 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 기능을 제안하고 버그를 찾아 기여해 주신 분들께 깊은 감사 인사를 드립니다. 깃허브의 별은 프로젝트의 가치를 치켜세우는 응원이자 개발자가 자신이 만든 작품으로 &lt;u&gt;디자인, 검색엔진 최적화, 성능&lt;/u&gt;과 같은 웹페이지를 측정하는 다양한 지표를 대표하여 대중에게 인정을 받았다는 증표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;⭐&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;hELLO GPT&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;hELLO GPT&lt;/u&gt;는 ChatGPT에서 제공하는 &lt;u&gt;GPTs&lt;/u&gt; 기능을 활용한 것으로, hELLO 스킨 사용자의 문의사항과 커스텀에 대한 개별적 요구사항에 대응하기 위해 작성되었습니다. 티스토리 스킨, &lt;a href=&quot;https://github.com/pronist/tidory/wiki&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;티도리 프레임워크&lt;/a&gt;에 대한 기본 지식 뿐만 아니라 hELLO에 대한 지식과 &lt;a href=&quot;https://github.com/pronist/hello&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;원본 소스코드&lt;/a&gt;에 대한 지식까지 겸비하고 있어 개별 커스텀에 대한 질문에 대답할 수 있도록 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pronist.tistory.com/208&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pronist.tistory.com/208&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742425887061&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;커스텀을 더 쉽게! hELLO GPT를 소개합니다&quot; data-og-description=&quot;&amp;quot;폰트를 바꾸려는데 어떻게 하면 될까요?&amp;quot;&amp;quot;이미지를 둥글게 하고 싶어요&amp;quot;&amp;quot;본문의 특정 부분만 강조하고 싶어요&amp;quot;저는 지금까지 hELLO에 대한 문의를 받을 때 위와 같은 질문에는 대답하지 않기로 &quot; data-og-host=&quot;pronist.tistory.com&quot; data-og-source-url=&quot;https://pronist.tistory.com/208&quot; data-og-url=&quot;https://pronist.tistory.com/208&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/obCYM/hyYvmCq4Vz/xybnxMqFaKUVlKclYTUPy1/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/nnYfO/hyYr2FtQZM/h8Tku0BypR5V4U8l1k0tkk/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/kuhde/hyYvhumeB4/SjOBAXwnKHpIL1suYOgWm0/img.png?width=1074&amp;amp;height=640&amp;amp;face=0_0_1074_640&quot;&gt;&lt;a href=&quot;https://pronist.tistory.com/208&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pronist.tistory.com/208&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/obCYM/hyYvmCq4Vz/xybnxMqFaKUVlKclYTUPy1/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/nnYfO/hyYr2FtQZM/h8Tku0BypR5V4U8l1k0tkk/img.png?width=800&amp;amp;height=476&amp;amp;face=0_0_800_476,https://scrap.kakaocdn.net/dn/kuhde/hyYvhumeB4/SjOBAXwnKHpIL1suYOgWm0/img.png?width=1074&amp;amp;height=640&amp;amp;face=0_0_1074_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;커스텀을 더 쉽게! hELLO GPT를 소개합니다&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;폰트를 바꾸려는데 어떻게 하면 될까요?&quot;&quot;이미지를 둥글게 하고 싶어요&quot;&quot;본문의 특정 부분만 강조하고 싶어요&quot;저는 지금까지 hELLO에 대한 문의를 받을 때 위와 같은 질문에는 대답하지 않기로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pronist.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;⭐ &lt;b&gt;hELLO 포트폴리오&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hELLO 포트폴리오는 이 블로그의 &lt;a href=&quot;https://pronist.tistory.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;홈&lt;/a&gt;처럼 블로그의 홈을 다채롭게 꾸밀 수 있는 hELLO의 &lt;u&gt;유료&lt;/u&gt; 커버셋입니다. 새로운 스킨이 아니기 때문에 hELLO에 추가적으로 사용할 수 있는 DLC 같은 역할입니다. 블로그가 단순히 기록하고 정리하는 공간이라는 역할에서 한 층 더 나아가 자신을 표현할 수 있는 포트폴리오로써 사용될 수 있도록 만들어줍니다. 개인 브랜딩의 시대가 도래한 지금, hELLO 포트폴리오를 사용하여 포트폴리오를 만들거나 자신의 제품을 홍보해보세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pronist.tistory.com/193&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pronist.tistory.com/193&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1729331366376&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;hELLO 포트폴리오를 소개합니다.&quot; data-og-description=&quot;hELLO 포트폴리오는 hELLO 티스토리 스킨의 유료 커버셋입니다. 웹 이력서와 포트폴리오를 위한 16종의 커버가 포함되어 있습니다. 모든 커버가 나열되어 있는 별도의 데모페이지는 준비되어 있지 &quot; data-og-host=&quot;pronist.tistory.com&quot; data-og-source-url=&quot;https://pronist.tistory.com/193&quot; data-og-url=&quot;https://pronist.tistory.com/193&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/X2gel/hyXlH17sFD/MFtd4K0wYZCpPtOcTaC2uK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/yR29U/hyXhXZP2XC/MbPi8f7Ynk13cqoNSErIsK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bPHIfO/hyXlU8dNrn/9OMNKgqanDE8sMk4gpeyk0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://pronist.tistory.com/193&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pronist.tistory.com/193&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/X2gel/hyXlH17sFD/MFtd4K0wYZCpPtOcTaC2uK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/yR29U/hyXhXZP2XC/MbPi8f7Ynk13cqoNSErIsK/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bPHIfO/hyXlU8dNrn/9OMNKgqanDE8sMk4gpeyk0/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;hELLO 포트폴리오를 소개합니다.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;hELLO 포트폴리오는 hELLO 티스토리 스킨의 유료 커버셋입니다. 웹 이력서와 포트폴리오를 위한 16종의 커버가 포함되어 있습니다. 모든 커버가 나열되어 있는 별도의 데모페이지는 준비되어 있지&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pronist.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;가치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;티스토리를 새로 시작하거나, 스킨을 바꾸려고 시도 중인가요? 티스토리 블로그를 처음 시작함에 있어서 스킨을 고민하는 것은 하나의 즐거움이기도 하지만 시간을 잡아먹는 일 중 하나일 것입니다. hELLO는 스킨의 방향성이 분명하여 스킨을 선택하기 위한 고민의 시간을 줄이고 여러분이 블로깅에 집중할 수 있는 시간이 마련될 수 있도록 할 것입니다. 블로거마다 블로그를 운영하는 목적이 제각각인 만큼 선택하는 스킨도 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;u&gt;Why hELLO?&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;티스토리 블로그가 나를 표현하는 공간으로써의 가치가 있음에도 대중에게 그저 부업의 일환으로, 단순 수익추구의 수단으로 생각되는 것이 싫습니다. 블로그는 장기적으로 볼 때 게임, 애니메이션, 사진, 요리, 여행, 독서와 같은 취미 블로그 및 사업, 기획, 디자인, 기술, 마케팅과 같은 전문적인 블로그 또는 기업 브랜딩과 개인 브랜딩을 위한 채널로 운영되는 것이 개인에게 있어서 더 나은 가치와 기회를 부여한다는 것이 사실이고, 그 부분은 이미 제 스스로가 경험하였습니다. 그에 더해 티스토리는 워드프레스와 같은 설치형 블로그와는 달리 낮은 진입장벽과 더불어 글의 주제와 디자인에서 높은 자유도를 잡았기 때문에, 그 영역에서 큰 힘을 발휘할 수 있다는 점에 주목할 필요가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세상에는 티스토리 스킨이 많습니다. hELLO가 독자 및 블로거에게 줄 수 있는 가치는 무엇일까요? hELLO는 블로거들이 티스토리 블로그를 그저 수익추구의 수단이 아니라 미래지향적으로 기업과 개인의 가치를 드높이는 수단이 되어 &lt;u&gt;&lt;b&gt;포트폴리오&lt;/b&gt;&lt;/u&gt;로써 운영되었으면 하는 마음에 제작되었습니다. hELLO는 취미, 전문성, 브랜딩, 포트폴리오에 중점을 두었기 때문에 &lt;u&gt;한 화면에 너무 많은 내용을 담는 것보다는 단 하나의 작품이라도 돋보이게 하는 방향으로 개발&lt;/u&gt;되었습니다. 다른 사람들에게 내가 만든 작품을 표현하고, 그들로부터 보다 나은 기회를 얻을 가능성이 높아질 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;깔끔하고 간결한 디자인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;티스토리 블로그의 스킨은 독자에게 건네는 첫 &lt;u&gt;&lt;b&gt;인사&lt;/b&gt;&lt;/u&gt;와 같습니다. 독자가 처음 블로그에 들어오면 보이는 것은 글이 아니라 블로그의 디자인입니다. 디자인이 간결하고 깔끔하다는 이유만으로도 독자에게 긍정적인 이미지를 심어줄 수 있고 평판이 나아질 수 있습니다. 반면 좋은 글을 쓰더라도 가독성이 나쁘고 눈이 피로한 디자인이라면 안 볼 가능성도 커지죠. 디자인 하나만으로도 블로그에 대한 인상이 달라지는 것입니다. hELLO는 &lt;u&gt;단순함과 깔끔함을 추구하여 가독성을 높여 독자가 글을 보기 편하게 만듭니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;뛰어난 성능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 페이지의 성능은 간단히 이야기하면 빠른 로딩입니다. 독자에게 있어 글을 보기 위한 빠른 초기 로딩은 중요하다고 볼 수 있습니다. 로딩이 느리면 예쁜 디자인과 좋은 글의 가치가 간접적으로 하락하게 됩니다. 찾아왔던 독자도 다시 나가게 되는 불상사가 발생할 수도 있죠. hELLO는 이미지 지연로딩과 같은 &lt;u&gt;최적화 전략을 사용하여 글을 빠르게 로딩함으로써 &lt;u style=&quot;letter-spacing: 0px;&quot;&gt;독자&lt;/u&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;가 글을 빠르게 마주할 수 있도록 만듭니다.&lt;/span&gt;&lt;/u&gt;&lt;u&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;검색엔진 최적화&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그의 글을 읽고 소비하는 것은 이제 사람만 하는 일은 아니게 되었습니다. 수많은 봇과 AI 가 웹을 돌아다니며 수집하고 검색을 하며 사용자에게 전달하고 있죠. 검색엔진 최적화를 통해 검색 순위의 상승을 돕고 AI 가 질문에 대답하기 위해 방문하는 빈도가 높아지면 블로그의 평판이 상승하여 전반적으로 긍정적인 영향을 미칠 것입니다. hELLO 는 웹 표준을 준수함으로써 기계적으로도 문서를 알아보기 쉽게 구성하였으므로 &lt;u&gt;검색엔진 및 AI 가 이해하기 쉬워 검색순위 상위권에 오를 가능성이 높아집니다.&lt;/u&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;패치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에 게시되는 패치노트의 경우 가장 최근의 버전에 한해 적어놓습니다. 그 이전 버전에 대한 패치노트를 보려면 &lt;a href=&quot;https://github.com/pronist/hello/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;릴리즈 노트&lt;/a&gt;에서 확인해보시기 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;v4.10.6&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년의 마지막 빌드입니다! 2026년에도 새해 복 많이 받으시기 바랍니다. :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;수정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모바일 환경에서 보호 글의 비밀번호 인풋 박스에서 엔터키로 진입할 수 없는 현상이 수정되었습니다 (&lt;a href=&quot;https://github.com/pronist/hello/issues/284&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#284&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;제목 요소에 스타일이 적용되지 않는 현상이 수정되었습니다. (&lt;a href=&quot;https://github.com/pronist/hello/issues/282&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#282&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;사이드바 공지사항 제목에 생략 부호가 적용되도록 변경되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기능&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;다크모드,&lt;/u&gt; &lt;u&gt;목차,&lt;/u&gt; &lt;u&gt;코드 하이라이팅&lt;/u&gt; 등 블로거 및 독자의 가독성과 편의를 위한 기능들을 담고 있습니다. 글에서 사용될 수 있는 기능들은 표, 인용, 접은글과 같이 &lt;u&gt;티스토리 에디터 - 기본모드&lt;/u&gt;에서 제공되는 요소만 처리하고 있습니다. 사용자가 &lt;u&gt;타 스킨으로 옮기더라도 글이 깨지는 등의 사이드 효과를 최소화&lt;/u&gt;하기 위함입니다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다크 모드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 대세죠. 사용자의 눈을 위해 &lt;b&gt;다크 모드&lt;/b&gt;를 지원합니다. 우선순위는 오른쪽 하단의 테마 변경을 통한 &lt;b&gt;수동 설정 &amp;gt; System &lt;/b&gt;이며 블로거가 다크모드를 임의로 설정할 권리는 없습니다. 다크모드와 화이트모드에 대한 내용은 블로거가 아닌 블로그에 작성된 글을 읽는 독자에게 모든 권한이 있어야 합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;darkmode.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUj7N5/btspGLci9iO/ckZFIDtPkKdKS4DgJdXIw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUj7N5/btspGLci9iO/ckZFIDtPkKdKS4DgJdXIw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUj7N5/btspGLci9iO/ckZFIDtPkKdKS4DgJdXIw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUj7N5%2FbtspGLci9iO%2FckZFIDtPkKdKS4DgJdXIw0%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;820&quot; data-filename=&quot;darkmode.png&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;때때로 다크모드에서 본문의 글자가 &lt;u&gt;검은색&lt;/u&gt;으로 나오는 경우가 있습니다. 이는 사용자의 자유도를 위해 다크모드에서 글자의 색상을 흰색으로 강제로 변경하지 않기 때문입니다. 이 뜻은 &lt;u&gt;에디터에서 인라인으로 부여한 속성&lt;/u&gt;은 유지된다는 의미입니다. 블로거가 에디터에서 글자색상을 변경했는데 다크모드에서 처리되지 않는다면 이는 일정 부분 자유도를 침해하는 행동이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 대부분 티스토리 에디터에서 글을 처음부터 작성한 경우에는 해당되지 않으나 본문을 &lt;u&gt;복사 &amp;amp; 붙여넣기&lt;/u&gt; 처리한 경우 &lt;u&gt;에디터에서 타의적으로 인라인 스타일을 부여하기 때문에 색상이 강제&lt;/u&gt;됩니다. 이는 이 스킨이 아닌 티스토리 에디터의 문제입니다. 따라서 가장 좋은 것은 글을 쓸 때 복사 &amp;amp; 붙여넣기 없이 티스토리 에디터에서 처음부터 작성하는 것이고, 이미 작성된 글에 대해서는 HTML 모드로 진입하여 인라인으로 부여된 속성에 해당하는 &lt;code&gt;&amp;lt;span style=&quot;color:...&quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt; 과 같이 작성된 형태를 제거하는 것입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메뉴바/구독 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;메뉴바와 구독 버튼은 오른쪽 상단에 고정&lt;/u&gt;됩니다. &lt;u&gt;관리자 - 메뉴바 /구독 설정&lt;/u&gt;에서 구독 버튼은 스킨에서 자체적으로 나타내고 있어 설정을 해도 영향이 없을 것이며, 메뉴바의 경우 표시 여부에만 영향을 받습니다. &lt;u&gt;구독 버튼은 2차 도메인과 자기 자신의 블로그에서는 출력되지 않습니다.&lt;/u&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;461&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brgFw1/btsHmDJaKmY/YM3be1AdylkFyKoxcYHEZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brgFw1/btsHmDJaKmY/YM3be1AdylkFyKoxcYHEZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brgFw1/btsHmDJaKmY/YM3be1AdylkFyKoxcYHEZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrgFw1%2FbtsHmDJaKmY%2FYM3be1AdylkFyKoxcYHEZ1%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;916&quot; height=&quot;461&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;461&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;사이드바&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;사이드바&lt;/u&gt;는 다음과 같은 기능을 제공합니다. &lt;b&gt;스킨 설정&lt;/b&gt;에서 사이드바를 &lt;u&gt;Off(접힘)&lt;/u&gt; 상태로 놓으면, 기준 해상도 &lt;b&gt;1400px&lt;/b&gt; 보다 큰 해상도에서 사이드바가 바로 표시되지 않고, 상단 프로필을 눌러야 나타나게 됩니다. &lt;u&gt;1400px 보다 낮은 해상도&lt;/u&gt;에서는 &lt;u&gt;모바일 및 태블릿으로 취급&lt;/u&gt;되어 On, Off 설정과는 상관없이 기본적으로 사이드바가 나타나지 않습니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N2lke/btsG8EOGiSZ/YZkyF6yxlfnYUOskB6ZCk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N2lke/btsG8EOGiSZ/YZkyF6yxlfnYUOskB6ZCk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N2lke/btsG8EOGiSZ/YZkyF6yxlfnYUOskB6ZCk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN2lke%2FbtsG8EOGiSZ%2FYZkyF6yxlfnYUOskB6ZCk1%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;909&quot; height=&quot;800&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드 하이라이팅&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스타일은 티스토리 에디터에서 &lt;code&gt;코드블럭&lt;/code&gt; 에 해당합니다. 개발자인 제게 빼놓을 수 없는 기능은 &lt;u&gt;코드 하이라이팅&lt;/u&gt; 기능입니다. &lt;code&gt;highlightjs&lt;/code&gt; 를 사용하여 코드보다 예쁘게 표기할 수 있습니다. 아래의 경우는 &lt;code&gt;go&lt;/code&gt; 언어를 표시한 것입니다.&lt;/p&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    fmt.Println(&quot;hELLO&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-size=&quot;size23&quot; data-ke-style=&quot;style2&quot;&gt;코드블록 폰트는 &lt;u&gt;Source Code Pro&lt;/u&gt; 를 사용합니다. 하지만, 일반 본문은 &lt;u&gt;SUIT&lt;/u&gt; 를 씁니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 하이라이트는 라이트모드/다크모드 분리에 따른 하이라이트 테마 두 개를 요구하는 관계로 스킨에 내장되어 있습니다. 티스토리에서 기본적으로 제공하는 코드 하이라이트 플러그인을 끄고 사용하는 것이 좋습니다. &lt;u&gt;티스토리 플러그인 - 코드 문법 강조&lt;/u&gt;에 해당하는 플러그인을 반드시 꺼주시기 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/issues/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/issues/56&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인용 문구&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;What is Lorem Ipsum?&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Lorem Ipsum is simply dummy text of the printing and typesetting industry.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이미지 및 슬라이드 쇼&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 크기가 &lt;u&gt;유지&lt;b&gt;*&lt;/b&gt;&lt;/u&gt; 되도록 설정되도록 구성하였습니다. 따라서 이 설정은 &lt;u&gt;중앙 정렬(Align Center)인 경우만 적용&lt;/u&gt;되고 나머지는 일반적인 옵션과 같습니다. 그 외에는 특별히 설정해 줄 것이 없습니다. 그러나 일부 미디어에 따라 설정이 다르게 적용됩니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 160px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 17.907%; height: 60px;&quot;&gt;&lt;b&gt;싱글&lt;/b&gt; 이미지&lt;/td&gt;
&lt;td style=&quot;width: 57.093%; height: 60px;&quot;&gt;다음과 같은 우선 순위를 가집니다. &lt;b&gt;data-origin-width &amp;gt; width &amp;gt; Content Width&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 60px;&quot;&gt;&lt;b&gt;&lt;b&gt;1100px &lt;b&gt;&lt;b&gt;(max-width)&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 60px;&quot;&gt;
&lt;td style=&quot;width: 17.907%; height: 60px;&quot;&gt;&lt;b&gt;그룹&lt;/b&gt; 이미지&lt;/td&gt;
&lt;td style=&quot;width: 57.093%; height: 60px;&quot;&gt;사이즈가 &lt;b&gt;고정&lt;/b&gt;입니다. 그룹 이미지는 개별 이미지의 사이즈를 따라가지 않습니다.&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 60px;&quot;&gt;&lt;b&gt;&lt;b&gt;1100px&lt;span&gt;&amp;nbsp;&lt;/span&gt;(fixed)&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;image.PNG&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLXiKO/btqEO0OEXOc/ocRrXCmS9CAH6KirU3ayYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLXiKO/btqEO0OEXOc/ocRrXCmS9CAH6KirU3ayYK/img.png&quot; data-alt=&quot;이미지가 중앙 정렬 인 경우, 크기가 유지되도록 설정되도록 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLXiKO/btqEO0OEXOc/ocRrXCmS9CAH6KirU3ayYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLXiKO%2FbtqEO0OEXOc%2FocRrXCmS9CAH6KirU3ayYK%2Fimg.png&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; alt=&quot;이미지가 중앙 정렬 인 경우, 크기가 유지되도록 설정되도록 구성&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;437&quot; data-filename=&quot;image.PNG&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이미지가 중앙 정렬 인 경우, 크기가 유지되도록 설정되도록 구성&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;목차&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본문의 상단에 나오는 &lt;u&gt;목차(Table of Contents)&lt;/u&gt;와 오른쪽에 나오는 따라다니는 &lt;u&gt;목차(Scrollspy)&lt;/u&gt;를 적용하는 방법은 &lt;u&gt;티스토리 에디터 - 기본모드&lt;/u&gt;에서 &lt;u&gt;제목1, 제목2&lt;/u&gt; 에 대응하여 자동으로 구성됩니다. &lt;b&gt;&lt;u&gt;제목3 및 접은글 내부에 있는 제목의 경우에는 무시&lt;/u&gt;&lt;/b&gt;됩니다. 또한 티스토리 기본 에디터에서 글을 쓰더라도 외부에서 내용을 복사 &amp;amp; 붙여넣기한 글의 경우에도 내부 구조가 달라 목차가 무시될 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;목록 스타일&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목록 스타일&lt;/b&gt;은 &lt;u&gt;리스트, 그리드, 지그재그, 갤러리&lt;/u&gt;를 지원합니다. 글 목록 스타일은 &lt;b&gt;스킨 커버&lt;/b&gt;와&amp;nbsp;스타일로 적용됩니다. &lt;b&gt;카테고리 관리&lt;/b&gt;에서 글 목록 스타일을 카테고리에 따라 지정할 수 있습니다. 여기서 &lt;u&gt;기본 스타일 유지&lt;/u&gt;라는 것은 &lt;u&gt;스킨 편집에서 설정한 글 목록 스타일&lt;/u&gt;을 의미합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTA4xl/btsG6V405sD/C3ySBlo8FvmvQCPQ9pBBS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTA4xl/btsG6V405sD/C3ySBlo8FvmvQCPQ9pBBS0/img.png&quot; data-alt=&quot;글 목록 스타일 (리스트, 그리드, 지그재그, 갤러리)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTA4xl/btsG6V405sD/C3ySBlo8FvmvQCPQ9pBBS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTA4xl%2FbtsG6V405sD%2FC3ySBlo8FvmvQCPQ9pBBS0%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;586&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;글 목록 스타일 (리스트, 그리드, 지그재그, 갤러리)&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;커버&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커버는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;리스트, 그리드, 슬라이드 쇼, 지그재그, 갤러리&lt;/u&gt;로 정의하였습니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf0PEB/btsG6Wpgob1/K1tI1krhjpxhBwviCdEKZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf0PEB/btsG6Wpgob1/K1tI1krhjpxhBwviCdEKZ1/img.png&quot; data-alt=&quot;스킨 커버 (리스트, 그리드, 슬라이드 쇼, 지그재그, 갤러리)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf0PEB/btsG6Wpgob1/K1tI1krhjpxhBwviCdEKZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf0PEB%2FbtsG6Wpgob1%2FK1tI1krhjpxhBwviCdEKZ1%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;211&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스킨 커버 (리스트, 그리드, 슬라이드 쇼, 지그재그, 갤러리)&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;옵션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스킨을 구성하고 있는 일부 요소들을 편의에 맞게 On/Off 할 수 있습니다. 끄고 싶은 기능은 끄고, 켜고 싶은 기능은 켜보세요. 스킨 옵션은 아래에 사진에 표현된 것이 전부입니다. 자주 요청된 스킨 옵션만 남겨두었으므로 색상 변경과 같은 자잘한 기능들에 대한 옵션은 제외되었습니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmGoVb/btsKkjH8KYE/FXV6cJ3nCzDPHSQn9DhUNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmGoVb/btsKkjH8KYE/FXV6cJ3nCzDPHSQn9DhUNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmGoVb/btsKkjH8KYE/FXV6cJ3nCzDPHSQn9DhUNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmGoVb%2FbtsKkjH8KYE%2FFXV6cJ3nCzDPHSQn9DhUNK%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;539&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h4 data-ke-size=&quot;size20&quot;&gt;헤더 스타일&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헤더 스타일은 글 제목의 형태입니다. &lt;u&gt;심플, 섬네일, 스크린&lt;/u&gt; 모드가 있고, 스킨 옵션에서의 &lt;u&gt;기본 값*&lt;/u&gt;은 섬네일이며 제목 뒤에 섬네일이 표현됩니다. 심플은 섬네일이 표현되지 않고, 스크린 모드는 섬네일이 모니터 화면을 가득 메우는 형태로 처리됩니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;*스킨 옵션에서 섬네일과 스크린으로 설정하더라도, 글에 이미지가 없거나 섬네일을 지정하지 않을 경우 심플로 표현됩니다.&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;너비&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글 &lt;u&gt;너비*&lt;/u&gt;를 설정할 수 있습니다. 글은&amp;nbsp;&lt;u&gt;글, 공지사항, 방명록&lt;/u&gt;을 이야기합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;*모든 콘텐츠는 상한선과 하한선이 있습니다. &lt;b&gt;375px ~ 1100px&lt;/b&gt; 사이에서 설정하십시오. 소스코드를 수정하여 하한선 미만, 상한선 초과로 설정하면 레이아웃이 깨질 수 있으니 주의 바랍니다.&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 하이라이팅&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*코드 하이라이팅에서는 스킨의 &lt;u&gt;코드블록 테마&lt;/u&gt;를 설정할 수 있습니다. highlight.js 를 사용합니다. 테마를 바꾸려면 &lt;a href=&quot;https://highlightjs.org/demo&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://highlightjs.org/demo&lt;/a&gt; 에서 변경하고자 하는 테마의 이름을 기입하면 됩니다. 버전에 따라 지원하지 않는 테마도 있을 수 있으므로 버전에 유의하십시오. 해당 스킨에서는 &lt;u&gt;v11.10.0&lt;/u&gt; 을 사용하고 있으므로 &lt;a href=&quot;https://github.com/highlightjs/highlight.js/tree/11.10.0/src/styles&quot;&gt;https://github.com/highlightjs/highlight.js/tree/11.10.0/src/styles&lt;/a&gt; 를 확인하시기 바랍니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;*코드 하이라이팅의 배경색은 스킨과의 디자인 일관성을 위해 고정되어 있습니다. 따라서 테마를 바꾸더라도 코드의 스타일은 바뀌겠지만 배경색상은 바뀌지 않는 점 유의 바랍니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메타 태그는 어디서 설정하나요?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메타 태그&lt;/b&gt; 설정은 티스토리에서 자체적으로 &lt;u&gt;플러그인&lt;/u&gt;의 형태로 제공하고 있습니다. &lt;u&gt;관리자 - 플러그인 - 메타 태그 등록&lt;/u&gt;을 살펴보시기 바랍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단축키&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://notice.tistory.com/2671&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;단축키&lt;/a&gt;는 티스토리에서 자체적으로 제공하는 기능입니다. 다크모드에서 인터페이스 가시성이 개선되었습니다. 블로그에서 &lt;code&gt;shift + /&lt;/code&gt; 를 눌러 단축키 목록을 확인할 수 있으니 적극 활용해보시기 바랍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그 외&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로필 카드: 티스토리 공식 &lt;a href=&quot;https://notice.tistory.com/2656&quot;&gt;프로필 카드&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;기능은 스킨에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;본문 하단에 &lt;u&gt;대체지원&lt;/u&gt;하고 있기 때문에 별도로 나타내지 않습니다. 공식 프로필 카드에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;블로거의 이름이 아닌 블로그의 이름이 노출&lt;/u&gt;된다는 점이 영 마음에 들지 않습니다&lt;/li&gt;
&lt;li&gt;마크다운: 티스토리에 글을 쓸 때 사용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;티스토리 에디터 - 기본모드&lt;/u&gt;로 작성한 글에 대해서만 스타일이 올바르게 동작하도록 제공합니다. 마크다운으로 작성한 글은 스타일이 정상적으로 나타나지 않을 것입니다. 또한 복사 &amp;amp; 붙여넣기로 다른 곳에 있던 글을 그대로 붙여넣은 경우에도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;기술적으로&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;내부적으로 글의 구조가 달라 스타일이 제대로 나타나지 않을 것입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;티스토리 에디터는 기본모드, 마크다운, 복사 &amp;amp; 붙여넣기 각각 글의 뼈대가 되는 HTML 이 일관성이 없습니다.&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;따라서 가장 많이 사용되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;기본모드&lt;/u&gt;를 기준으로 하고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;받기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스킨은 블로그를 통해 이윤을 추구하지 않는 비상업적 &lt;u&gt;개인&lt;/u&gt;에게 &lt;u&gt;&lt;b&gt;무료&lt;/b&gt;&lt;/u&gt;로 제공됩니다. &lt;span&gt;&lt;u&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/pronist/hello&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃허브&lt;/a&gt;에 ⭐을 주시면 감사하겠습니다.&lt;/b&gt;&lt;/u&gt; 이 스킨은 &lt;a href=&quot;https://github.com/pronist/tidory&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;티도리 프레임워크&lt;/a&gt;로 작성되었습니다. 티도리 프레임워크는 기존의 구닥다리 티스토리 스킨 개발 방식에 현기증을 느낀 나머지 &lt;u&gt;제가 직접 만든 티스토리 스킨 개발 프레임워크&lt;/u&gt;입니다. &lt;a href=&quot;https://github.com/pronist/tidory&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;티도리 프레임워크&lt;/a&gt;에도 ⭐을 주시면 감사하겠습니다. &lt;span&gt;개발자에게 깃허브의 별은 칭찬의 의미뿐만 아니라 &lt;u&gt;다른 이에게 프로젝트를 추천한다는 의미&lt;/u&gt;도 내포되어 있답니다  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.6/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.6/hELLO-dist.zip&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;※ 스킨을 등록할 때는 &lt;u&gt;images&lt;/u&gt;&amp;nbsp;폴더의 내부 파일도 업로드 되었는지 명확하게 확인해주세요. 그렇지 않은 경우 무한로딩이 발생할 수 있습니다.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 하이라이팅은 스킨에 내장되어 있으므로 별도로 포함할 필요가 없습니다. 다만 티스토리에도 코드 하이라이팅은 자체적으로 내장되어 있는데, 충돌을 방지하기 위해 이를 해제할 필요가 있습니다. &lt;u&gt;관리자 - 플러그인 - 코드 문법 강조 플러그인&lt;/u&gt;을 &lt;u&gt;&lt;b&gt;해제&lt;/b&gt;&lt;/u&gt;하세요.&lt;/li&gt;
&lt;li&gt;모바일웹의 경우 &lt;u&gt;관리자 - 모바일웹 설정 - 티스토리 모바일웹 자동 연결&lt;/u&gt;을 &lt;u&gt;&lt;b&gt;사용하지 않습니다&lt;/b&gt;&lt;/u&gt;로 설정하세요.&lt;/li&gt;
&lt;li&gt;오른쪽 상단의 티스토리 메뉴의 경우 &lt;u&gt;관리자 - 메뉴바/구독 설정 - 블로그 메뉴바&lt;/u&gt;를 &lt;b&gt;&lt;u&gt;표시합니다&lt;/u&gt;&lt;/b&gt;로 설정하세요.&lt;/li&gt;
&lt;li&gt;SEO를 위한 메타 태그는 &lt;u&gt;관리자 - 플러그인 - 메타 태그 등록&lt;/u&gt;에서 설정하세요.&lt;/li&gt;
&lt;li&gt;포트폴리오를 위한 커버셋인 &lt;a href=&quot;https://pronist.tistory.com/193&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hELLO 포트폴리오&lt;/a&gt;를 통해 조금 더 다채롭게 &lt;u&gt;&lt;b&gt;홈&lt;/b&gt;&lt;/u&gt;을 꾸며보세요.&lt;/li&gt;
&lt;li&gt;블로거를 위해 준비된 다양한 &lt;a href=&quot;https://pronist.tistory.com/5#%EA%B8%B0%EB%8A%A5-1-2&quot;&gt;기능&lt;/a&gt;을 살펴보세요.&lt;/li&gt;
&lt;li&gt;문의와 버그는 &lt;a href=&quot;https://github.com/pronist/hello/discussions?discussions_q=is%3Aclosed&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃허브 디스커션&lt;/a&gt;과 &lt;a href=&quot;https://github.com/pronist/hello/issues?q=is%3Aissue%20state%3Aclosed&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이슈&lt;/a&gt;를 참고해보세요.&lt;/li&gt;
&lt;li&gt;스타일을 변경하거나 기능을 추가하는 등의 스킨을 커스텀하고 싶다면 &lt;a href=&quot;https://pronist.tistory.com/208&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hELLO GPT&lt;/a&gt; 또는&amp;nbsp;&lt;a href=&quot;https://pronist.tistory.com/195&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;커스텀 가이드&lt;/a&gt;를 살펴보세요.&lt;/li&gt;
&lt;li&gt;글을 작성할 때는 &lt;b&gt;복사 &amp;amp; 붙여넣기&lt;/b&gt;를 &lt;u&gt;하지 않는 것&lt;/u&gt;이 좋습니다. 티스토리 에디터에서 다른 플랫폼의 복붙된 글의 양식까지 가져오므로 내부 구조(HTML)상 문제가 발생하기 때문에 스킨에서 제공되는 기능(목차 등)이 작동하지 않거나 충돌할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;이전 버전&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이전에 배포되었던 버전들을 보려면&lt;span&gt;&amp;nbsp;&lt;b&gt;더보기&lt;/b&gt;를&lt;/span&gt; 눌러주세요. 버전에 따른 변경사항은 &lt;a href=&quot;https://github.com/pronist/hello/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;릴리즈 노트&lt;/a&gt;를 참고해 주세요. 그 밖에 스킨 사용 시 발생할 가능성이 있는 문제에 대해서는 바로 다음에 있는 &lt;u&gt;문제&lt;/u&gt;를 꼭 참고하셔서 해결하시면 되겠습니다. 스킨을 적용한 이후에는 바로 위에 있는&amp;nbsp;&lt;u&gt;기능&lt;/u&gt;에서 이 스킨에 어떤 기능들과 주의사항이 있는지 살펴보시기 바랍니다.&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;4.x&lt;/u&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4.10.5 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.5a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.5a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.10.4 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.4/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.4/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.10.3 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.3/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.3/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.10.2 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.2a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.2a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.10.1 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.1/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.1/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.10.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.10.0c/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.10.0c/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.9.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.9.0d/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.9.0d/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.8.1 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.8.1b/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.8.1b/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.8.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.8.0/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.8.0/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.7.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.7.0a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.7.0a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.6.1 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.6.1/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.6.1/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.6.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.6.0/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.6.0/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.5.3 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.5.3/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.5.3/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.5.2 -&amp;nbsp;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.5.2a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.5.2a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.5.1 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.5.1/hELLO-dist.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/releases/download/4.5.1/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.5.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.5.0b/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.5.0b/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.4.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.4.0/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.4.0/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.3.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.3.0/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.3.0/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.2.2 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.2.2/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.2.2/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.2.1 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.2.1/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.2.1/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.2.0 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.4a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.2.0b/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.1.4 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.4a/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.1.4a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.1.3 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.3/hELLO-dist.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/releases/download/4.1.3/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.1.2 - &lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.2/hELLO-dist.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/releases/download/4.1.2/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.1.1 -&amp;nbsp;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.1a/hELLO-dist.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/releases/download/4.1.1a/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.1.0 -&amp;nbsp;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.1.0g/hELLO-dist.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/releases/download/4.1.0g/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;4.0.0 -&amp;nbsp;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/4.0.0/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/4.0.0/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;3.x&lt;/u&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3.6.5&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.6.5/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.6.5/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3.6.4 -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.6.4/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.6.4/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3.6.3 -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.6.3/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.6.3/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3.6.2 -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.6.2/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.6.2/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3.6.1 -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.6.1/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.6.1/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3.5.5&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/releases/download/3.5.5/hELLO-dist.zip&quot;&gt;https://github.com/pronist/hello/releases/download/3.5.5/hELLO-dist.zip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;권리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;①이 스킨은 사용자가 직접 &lt;b&gt;개조&lt;/b&gt;하여 사용하는 것을 허용합니다. 단, &lt;b&gt;원저작자가 누구인지를 표기해야 하며,&lt;/b&gt; 스킨의 코드가 담겨있는 주소인 &lt;a href=&quot;https://github.com/pronist/hello&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello&lt;/a&gt; 를 남길 필요가 분명히 있습니다. 사이드바에 있는 저작권 문구를 건드리지 않는다면 이는 문제가 되지 않습니다. ②1회성 유료(&lt;u&gt;39,000원&lt;/u&gt;)로 스킨을 구입하는 경우 사용자에게 다음과 같은 권리를 제공합니다. &lt;a href=&quot;mailto:pronist@naver.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pronist@naver.com&lt;/a&gt; 으로 문의해주시기 바랍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;상업적인 목적(광고[애드센스, 체험단, 쿠팡 파트너스 등])/판매([제품 등])&lt;/u&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;h2 data-ke-size=&quot;size26&quot;&gt;도구&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 나열된 도구들은 제가 만든 도구는 아니지만, 티스토리 블로그 글쓰기에 도움이 될 수 있어 소개합니다. 유용한 경우 개발자님께 깃허브 ⭐를 주시면 도움이 될 것입니다. 아래에 소개된 도구 이외에도 &lt;b&gt;&lt;u&gt;hELLO와 관련된&lt;/u&gt;&lt;/b&gt; 유용한 도구가 있다면 댓글로 알려주시면 추가될 수 있습니다. 사용자가 작성한 도구는 티스토리 공식 도구가 아니므로 출력 및 실행 결과를 늘 확인하시기 바랍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://psh10066.github.io/tistory-html-formatter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tistory HTML 편집기&lt;/a&gt; ― Tistory HTML 편집기는 &lt;u&gt;기본모드&lt;/u&gt;에서 글을 작성할 때 외부 소스로부터 글을 &lt;u&gt;복사 &amp;amp; 붙여넣기해서 작성하는 경우&lt;/u&gt;, 티스토리 에디터에서 원글의 서식까지 불러오는 것으로 인해 목차와 같은 기능이 동작하지 않거나, hELLO의 다크모드에서 글자가 검은색으로 변하는 경우가 있는데, 이를 방지하지 위해 HTML 코드를 티스토리 블로그에 맞도록 개선합니다. 다만, 에디터의 HTML 모드에서 코드를 복사하여 웹에서 직접 변환하여야 합니다. 이 과정을 생략하고 에디터에서 자체적으로 처리하기 위해서는 티스토리 팀에서 해주어야겠죠 :(&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;버그&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;개선사항&lt;/b&gt;에 대한 피드백은 언제나 환영입니다. 이는 티스토리 스킨이 조금 더 발전할 수 있는 길입니다. 버그는 언제나 있을 수 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;버그가 없는 프로그램은 세상에 있을 수 없습니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스킨에 &lt;b&gt;버그&lt;/b&gt;가 발생하면 사전 고지없이 코드가 &lt;b&gt;갱신될&lt;/b&gt; 수 있습니다. 혹시나, &lt;b&gt;버그&lt;/b&gt;가 있다면 다시 다운로드하거나 아직 해결이 안 된 버그가 있다면 이슈를 남겨주세요. 만약 댓글을 통한 신고인 경우 스크린샷의 첨부는 불가하므로 &lt;u&gt;&lt;b&gt;글의 링크&lt;/b&gt;&lt;/u&gt;는 반드시 있어야 합니다. 만약 없을 경우에는 확인이 어렵기 때문에 수정에 큰 차질이 생길 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이슈에 남기는 것은 오직 버그 신고를 위해 작성되어야 하며, 그 이외에 기능에 대한 질문이나 새로운 기능을 제의하고 싶다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/discussions?discussions_q=is%3Aclosed&quot;&gt;Github Discussions&lt;/a&gt;&amp;nbsp;에서 해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/issues&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/issues&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;*스킨을 사용하면서 발생하는 문제는 이미 다른 사람이 마주한 것일 가능성이 큽니다. 버그를 신고하기 전에, 이미 신고된 적이 있는지, 이슈에서 한 번 살펴보는 것이 좋습니다.&lt;/u&gt;&lt;s&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/issues?q=is%3Aissue+is%3Aclosed&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/issues?q=is%3Aissue+is%3Aclosed&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제가 발생한 상황이 스킨의 버그인지 사용자의 환경에 의해 발생한 외부의 문제인지 알기란 쉬운 일이 아니랍니다. 때때로 &lt;a href=&quot;https://github.com/pronist/hello/issues/224&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#244&lt;/a&gt; 와 같이 카카오의 잠수함 패치에 따라 티스토리 자체적으로 발생하는 터무니없는 버그도 있습니다. 따라서 세 가지 측면에서 모두 살펴보아야 합니다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Q. &lt;b&gt;&lt;u&gt;2차 도메인&lt;/u&gt;&lt;/b&gt;을 사용 중인가요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A. 2차 도메인에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;댓글, 구독&lt;span&gt;&amp;nbsp;&lt;/span&gt;등 로그인을 기반으로 하는 활동이 동작하지 않습니다. 이는 스킨의 문제가 아닌&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;티스토리의 제약사항&lt;/u&gt;으로, 이 문제는 티스토리 공식 블로그에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://notice.tistory.com/2546&quot;&gt;2차 도메인&lt;/a&gt;을 참고하실 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. 브라우저의 &lt;u&gt;&lt;b&gt;플러그인&lt;/b&gt;&lt;/u&gt; 또는 &lt;b&gt;&lt;/b&gt;&lt;u&gt;&lt;b&gt;확장&lt;/b&gt;&lt;/u&gt; 기능을 사용 중인가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 크롬 등에서 제공하는 플러그인이나 확장 기능으로 인해 본문이 잘못 표시되는 사례가 있었습니다. 따라서 신고하기 전에 플러그인을 Off 한 뒤 점검해 보세요. 플러그인으로 인해 발생했었던 문제에 대한 사례는 아래의 링크를 참고할 수 있습니다. 또한 이전에는 애드블록, 애드가드와 같은 광고 차단 플러그인과의 충돌도 있었습니다. 이는 카카오에서 포함하는 리소스와 충돌로 인해 발생한 문제라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/issues/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/issues/41&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. &lt;u&gt;&lt;b&gt;티스토리 플러그인&lt;/b&gt;&lt;/u&gt;을 사용 중인가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 티스토리에는 스킨에 적용할 수 있는 &lt;u&gt;플러그인&lt;/u&gt;이 존재합니다. 특히, 코드 하이라이팅의 경우에는 스타일이 겹쳐 올바르게 표시되지 않을 수 있습니다. 따라서 관리자에서 티스토리 플러그인을 Off 한 뒤 점검해 보시기 바랍니다. 이와 관련한 코드 하이라이팅 문제는 아래의 링크를 참고할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pronist/hello/issues/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/pronist/hello/issues/30&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q. &lt;u&gt;&lt;b&gt;인터넷 익스플로러&lt;/b&gt;&lt;/u&gt;를 사용 중인가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A. 이&amp;nbsp;스킨은&amp;nbsp;&lt;u&gt;인터넷 익스플로러&lt;/u&gt;는 배제하였습니다. 따라서 인터넷 익스플로러에서 이 스킨이 올바르게 동작하리라고 보장하지 않습니다. 이제는 IE 를 만든 마이크로소프트조차 더는 지원을 중단(95.08.17 ~ 22.06.15)했으며 이미 역사의 뒤안길로 사라진 브라우저입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Support for Internet Explorer 11 has ended on June 15, 2022.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690883287538&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Internet Explorer help - Microsoft Support&quot; data-og-description=&quot;Explore subscription benefits, browse training courses, learn how to secure your device, and more. Microsoft 365 subscription benefits Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge. Ask the Microsof&quot; data-og-host=&quot;support.microsoft.com&quot; data-og-source-url=&quot;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&quot; data-og-url=&quot;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/no5l8/hyTviTVoZT/zwXixN1DHTKVKeC6BM2wH1/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332,https://scrap.kakaocdn.net/dn/bxuIOe/hyTwqv3at9/EtHAn4H8cep4f6Xe3KAjzk/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332,https://scrap.kakaocdn.net/dn/cmvQFn/hyTvdryxIr/kqjB0lGJ8klqtoKzjoz21K/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332&quot;&gt;&lt;a href=&quot;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://support.microsoft.com/en-us/windows/internet-explorer-help-23360e49-9cd3-4dda-ba52-705336cc0de2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/no5l8/hyTviTVoZT/zwXixN1DHTKVKeC6BM2wH1/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332,https://scrap.kakaocdn.net/dn/bxuIOe/hyTwqv3at9/EtHAn4H8cep4f6Xe3KAjzk/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332,https://scrap.kakaocdn.net/dn/cmvQFn/hyTvdryxIr/kqjB0lGJ8klqtoKzjoz21K/img.png?width=594&amp;amp;height=332&amp;amp;face=0_0_594_332');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Internet Explorer help - Microsoft Support&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Explore subscription benefits, browse training courses, learn how to secure your device, and more. Microsoft 365 subscription benefits Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge. Ask the Microsof&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;support.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 style=&quot;text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문의&lt;/h2&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스킨의 기능에 대한 질의 응답이나 다른 사람이 이미 질문한 내용에 대해서 알아보려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/pronist/hello/discussions?discussions_q=is%3Aclosed&quot;&gt;Github Discussions&lt;/a&gt;에서 살펴볼 수 있습니다. 기능에 대한 문의나 새로운 제안도 좋습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;*글자, 이미지와 같은 요소의 색상, 간격, 여백, 크기, 넓이의 변경과 같은 개별 블로거의 미적취향과 관련된 질문은 &lt;b&gt;직접 &lt;/b&gt;답변해드리지 않습니다. 커스텀과 관련해서는 &lt;a href=&quot;https://pronist.tistory.com/208&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hELLO GPT&lt;/a&gt; 또는 &lt;a href=&quot;https://pronist.tistory.com/195&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;커스텀 가이드&lt;/a&gt;를 참고해주세요.&lt;/u&gt;&lt;/p&gt;</description>
      <category>티스토리 스킨</category>
      <category>hELLO.</category>
      <category>티도리 프레임워크</category>
      <category>티스토리 스킨</category>
      <author>정상우</author>
      <guid isPermaLink="true">https://pronist.tistory.com/5</guid>
      <comments>https://pronist.tistory.com/5#entry5comment</comments>
      <pubDate>Wed, 31 Dec 2025 01:43:23 +0900</pubDate>
    </item>
    <item>
      <title>'비전공자를 위한 챗GPT 101' 연재를 시작합니다</title>
      <link>https://pronist.tistory.com/notice/214</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요. 정상우입니다. 생성형 AI 강사로 커리어를 전환하면서, 이 참에 출간을 목표로 글을 다시 써보자는 생각이 들었습니다. 다만 웹에 먼저 공개합니다. 쓰기 시작한 주제는 '&lt;a href=&quot;https://brunch.co.kr/magazine/gen-ai&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;비전공자를 위한 챗GPT 101&lt;/a&gt;' 라는 주제로, 브런치에 작성됩니다. 자전적인 이야기도 아닐 뿐더러, 일반 대중을 대상으로 작성한 글이기 때문에 기술적으로 깊이있는 내용은 이야기하지 않습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;'비전공자를 위한 챗GPT 101'은 단순하게 챗GPT 사용법을 이야기하는 것이 아니라, 생성형 AI를 활용하기 위해 알아야 하는 기초를 대표적인 생성형 AI 서비스인 챗GPT를 사용하여 풀어냅니다. 물고기를 잡아주기보다는 물고기를 잡는법을 알려줍니다.&lt;br /&gt;&lt;br /&gt;챗GPT를 사용하는 활용법은 간단한 글쓰기부터 시작해서 기획, 마케팅 등 너무나도 많고, 직무마다 다릅니다. 이 글들은 '이메일 쓰기', '통계 분석하기 같은' 단순한 '사례'만을 이야기 하지 않습니다. 생성형 AI의 '기본'을 이야기함으로써 챗GPT를 자유롭게 구사하며 실무에서 활용할 수 있도록 뼈대를 쌓습니다.&lt;/blockquote&gt;</description>
      <author>정상우</author>
      <guid isPermaLink="true">https://pronist.tistory.com/notice/214</guid>
      <pubDate>Sun, 9 Nov 2025 11:44:51 +0900</pubDate>
    </item>
    <item>
      <title>커스텀을 더 쉽게! hELLO GPT를 소개합니다</title>
      <link>https://pronist.tistory.com/208</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;폰트를 바꾸려는데 어떻게 하면 될까요?&quot;&lt;br /&gt;&quot;이미지를 둥글게 하고 싶어요&quot;&lt;br /&gt;&quot;본문의 특정 부분만 강조하고 싶어요&quot;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 지금까지 &lt;a href=&quot;https://pronist.tistory.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;hELLO&lt;/span&gt;&lt;/a&gt;에 대한 문의를 받을 때 위와 같은 질문에는 대답하지 않기로 명시한 바 있습니다. 아무래도 제 몸은 하나인지라 개인의 미적 취향에 따른 개별 질문에 전부 다 대답할 수 없기 때문입니다. 이를 위해 작성해두었던 &lt;a href=&quot;https://pronist.tistory.com/195&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;커스텀 가이드&lt;/span&gt;&lt;/a&gt;는 진입장벽이 있기 때문에, 이 문제에 대해 어떻게 할까 고민하다가 GPTs에 &lt;u&gt;티스토리 스킨, 티도리 프레임워크, hELLO&lt;/u&gt;에 대한 지식을 참고하도록하고 배포하면, &lt;u&gt;&lt;b&gt;문의사항 및 나만의 커스텀을 하고 싶은 사용자들에게 더 나은 가치를 제공&lt;/b&gt;&lt;/u&gt;할 수 있을 것이라는 아이디어가 떠올랐습니다. 문의를 위해 제게 직접 댓글 또는 디스커션에 글을 남기는 것이 부담스러우셨던 분들에게도 큰 도움이 될 것이라 생각합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/simhQ/btsMQCjU3Rg/so8k7uC7H6v7odhPzKP651/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/simhQ/btsMQCjU3Rg/so8k7uC7H6v7odhPzKP651/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/simhQ/btsMQCjU3Rg/so8k7uC7H6v7odhPzKP651/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsimhQ%2FbtsMQCjU3Rg%2Fso8k7uC7H6v7odhPzKP651%2Fimg.png&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; loading=&quot;lazy&quot; width=&quot;1074&quot; height=&quot;640&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;hELLO &lt;b&gt;GPT&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;hELLO GPT&lt;/u&gt;는 ChatGPT에서 제공하는 &lt;u&gt;GPTs&lt;/u&gt; 기능을 활용한 것으로, hELLO 스킨 사용자의 문의사항과 커스텀에 대한 개별적 요구사항에 대응하기 위해 작성되었습니다. 티스토리 스킨, &lt;a href=&quot;https://github.com/pronist/tidory/wiki&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;티도리 프레임워크&lt;/span&gt;&lt;/a&gt;에 대한 기본 지식 뿐만 아니라 hELLO에 대한 지식과 &lt;a href=&quot;https://github.com/pronist/hello&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;원본 소스코드&lt;/span&gt;&lt;/a&gt;에 대한 지식까지 겸비하고 있어 개별 커스텀에 대한 질문에 대답할 수 있도록 했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://chatgpt.com/g/g-67d484dc9a8c8191aeaf9de43f8a6ee8-tistory-skin-hello&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://chatgpt.com/g/g-67d484dc9a8c8191aeaf9de43f8a6ee8-tistory-skin-hello&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;hELLO GPT는 무료이며, ChatGPT 무료 사용자도 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tistory.github.io/document-tistory-skin/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;티스토리 스킨 공식 문서&lt;/span&gt;&lt;/a&gt;를 기반으로 하는 티스토리 스킨에 대한 배경지식, 티도리 프레임워크 사용법, hELLO에 대한 전반적인 질의 또는 기능 및 스타일 커스텀 방법, 원본 소스코드에 대한 설명까지 담당할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주의&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성형 AI의 한계로 답변이 틀릴 수 있음을 인지해야 합니다.&lt;/li&gt;
&lt;li&gt;hELLO GPT는 실험적으로 공개한 것이기 때문에 제 개인사정에 따라 예고 없이 비활성화 될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>티스토리 스킨</category>
      <category>GPTs</category>
      <category>Hello</category>
      <category>hello-gpt</category>
      <author>정상우</author>
      <guid isPermaLink="true">https://pronist.tistory.com/208</guid>
      <comments>https://pronist.tistory.com/208#entry208comment</comments>
      <pubDate>Thu, 20 Mar 2025 08:09:37 +0900</pubDate>
    </item>
    <item>
      <title>내가 '삶'을 바라보는 관점</title>
      <link>https://pronist.tistory.com/207</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;2025년, 나이는 만으로 29살이 되었다. 한국 나이로 치자면 서른이다. 시간이 정말 빠르다는 생각이 든다. 30년 밖에 살지 않은 내가 인생에 대해 논하기에는 아직 너무 젊은것 같다는 생각이 들지만, 지금까지 살아오면서 듣고, 보고, 경험한 것을 바탕으로 '삶'을 바라보는 관점이 하나 생겼다. 즉, 이건 내 주관적인 '관점'일 뿐이고 '철학'이 아니다. 삶에 대한 관점은 사람마다 다르기 때문에 '이 사람은 이렇게 세상을 바라보고 있구나' 정도로만 넘어가주었으면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 바라본 '삶'이라는 것은 '나와 세계를 이해하는 과정'이다. 나는 개발자로서 '인간의 삶은 유전자와 세계에 의해 프로그래밍되어 있고, 인간은 체계라는 시스템에 따라 움직이는 것뿐이므로 자유의지는 없다'는 식의 디스토피아적 의견은 선호하지 않는다. 그렇지만 완전히 틀린 의견은 아니다. 유전자에 각인된 본능과 욕구, 그리고 세계가 만들어 놓은 법과 규율이라는 시스템, 체제에 의해 우리의 행동이 정해지는 것은 사실이기 때문이다. 하지만 이것은 그저 세계를 구성하는 프레임일 뿐, 그 안에서 변주(Variation)를 만들어내는 것은 오직 인간의 자유의지에서 나온다는 점을 이야기하고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'나와 세계를 이해하는 과정'에서 '나'는 세상을 접하면서 내가 좋아하는 것과 싫어하는 것, 강점과 약점 등을 분명하게 인지하고 '나'라는 사람을 정의하는 과정이다. 이는 '나'라는 존재에 대한 메타인지를 향상시키는 일이다. 아기들도 자기가 좋아하는 음식이 있고 싫어하는 것도 있다. 어린이집과 유치원에서는 마음이 맞는 친구와 그렇지 않은 친구가 생긴다. 초등학교 때는 좋아하는 과목과 싫어하는 과목, 선망하는 직업이 생긴다. 그렇게 점점 '나'라는 사람이 어떤 사람인지를 알아가고 정의하는 것이다. 이 과정을 10대와 20대에 거치면 적어도 30대가 되기 전에는 자신이 좋아하는 일과 잘하는 일이 무엇인지를 알고, 하고 싶은 일과 할 수 있는 일, 그 사이에서 길을 찾을 수 있다. 하지만 제대로 이행하지 못하면 크게 방황할 가능성이 높다. 성인이 되어 '나'를 알아보는 과정을 다시 하려면 적어도 초등학생 시절까지 거슬러 올라가서 회고해야 하므로 단기간에 끝나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 중학생 즈음부터 다른 친구의 고민을 들어주고 상담하거나 방향성과 전략을 제시하는, 그런 일들을 좋아하곤 했다. '보상을 바라지도 않고, 의도하지도 않았던' 이런 활동들이 나의 '선천적인 성향'을 말해주고 있었으며 20대 후반이 되어서야 이를 인지함으로써 진로의 방향성을 결정할 수 있는 명확한 근거가 될 수 있었다. 지금도 가끔씩 내 전문분야에 대해 멘토링을 하는데 말이다. 스타트업을 준비하고 있는 지금도 '타인의 문제를 해결하고 더 효율적이고 나은 삶을 살 수 있도록 한다'는 그 본질은 변하지 않았다. 난 이제 과거와는 달리 진로에 대해 큰 고민을 하지 않는다. 이미 지나온 과거에서 수많은 힌트를 얻었고, '나'라는 사람에 대한 정의가 점점 쌓이고 나이가 들수록 분명해지고 있기 때문이다. 내가 한 우물을 파는 성향이라는 것도, 명예욕이 있다는 것도, 글을 써서 표현하고 정리하는 것을 좋아한다는 것도, 단순함을 추구하는 실용주의라는 것도, 즉흥적인 것보다 체계를 중시한다는 것도, 능동적으로 문제를 해결하는 것을 좋아한다는 것도, 완성도에 집착하는 완벽주의적 성향이 있다는 것도, 전부 과거를 돌아보면서 깨닫게 된 것들이라 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'세계'는 '나'를 감싸고 있는 주변의 모든 요소, 자연과 타인을 이해하고 깨달음을 얻는 과정이다. 다소 있어 보이는 표현을 빌려보자면, 삼라만상의 이치를 깨닫는 과정이다. 학교, 직장, 책, 영상에서 보고, 배우고, 일하는 모든 것들은 세계를 이해하는 과정이다. 스타트업을 꿈꾸는 내게 있어서 이는 '나'의 서비스가 아닌 '세계'인 고객을 이해하려고 하는 것과 일맥상통한다. 세계를 이해하다 보면 내가 알고 있는 세계는 그저 점에 불과했다는 것을 깨닫고 새삼 겸손해진다. 때때로 내가 책이나 영상으로만 접하고 머리로만 이해하고 있는 세계와 실제 현실이 다르다는 것을 인지하면 혼란스러워질 때도 있다. 나이를 먹어서도 세계를 이해하지 못하고 '나'를 벗어나지 못하면 이기적이고 자기중심적인 인간이 된다. 세상에는 그런 사람이 많다. 자신의 말이 늘 옳은 줄 알고 그대로 이행하지 않으면 타인을 비난하고, 자신이 보고 들은 것이 세상의 전부인 줄 알고 소수의 사례만 가지고 일반화하고 선동하는 그런 사람들 말이다. 자기가 잘못했음을 알더라도 그깟 알량한 자존심을 지키고자 남을 까내리는 사람도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신보다 어린 아이의 심정을 이해하지 못하는 사람들도 너무 많다. 자신이 아이였던 적이 있었음에도 불구하고 '아이'라는 세계를 이해하지 못했기 때문이다. 내 친구는 아이를 싫어한다고 한다. 그 이유는 울기 때문이란다. 하지만 아이는 원래 우는 것이다. 아이가 울고 불며 떼를 써서 싫다고 한다. 하지만 아이는 원래 떼를 쓰는 것이다. 그게 아이가 세계에 자신을 표현할 수 있는 가장 효과적인 방법이기 때문이다. 이를 이해하면 더는 아이가 울거나 떼를 쓴다고 해서 이해하지 못하겠다는 표정으로 아이를 쳐다볼 필요가 없다. 그저 어른이 해야 하는 일은, 떼를 쓰는 것보다 더 효과적인 방법인 말과 글, 약속, 계약, 협상, 타협과 같은, 세계에서 문제를 해결하기 위한 수단으로 '나'가 아닌 타인의 시선에서 바라보는 연습을 시키고 세계를 이해하는 방법을 가르치는 것뿐이다. 세계를 이해한다는 것은 '나'가 아닌 바깥으로 관점을 확장하는 것과 같다. 이를 통해 타인을 존중하는 법을 배우기 때문에 자신의 감정과 권리만 주장하고 남을 배려할 줄 모르는 파렴치한 인간은 되지 않는다. 하지만 세계를 '잘못' 이해하면 사기꾼이 되거나 주변을 선동하고 가스라이팅을 통해 타인이 인식하는 세계를 왜곡하고 굴종시키는 쓰레기가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배우를 준비하는 친구가 있는데, 그 친구는 늘 자신의 연기에 대한 방향성을 고민하곤 했다. 하지만 나는 배우라는 세계에 대해서는 잘 모르고, 섣불리 비전문적으로 조언하는 것은 어리석은 행동임을 알고 있기 때문에 그저 소비자의 관점으로 조언을 해주었다. &quot;대본을 받고 네가 가장 먼저 해야 하는 것은 너('나')의 연기 방향성을 고민하는 것이 아니라, 소비자('세계')의 관점에서 그 캐릭터가 어떤 식으로 연기되기를 바라는지 이해하는 게 아닐까?&quot; 그 친구가 이야기하기를, 자기는 그런 생각은 해본 적이 없다고 한다. 어찌 보면 당연한 것이었다. 그 녀석은 '나'에서 벗어나질 못하고 자기중심적으로 생각하는 경향이 있어 '세계'의 관점으로 생각하는 일이 전혀 익숙하지 않기 때문이다. 늘 자신의 관점에서 캐릭터를 연기하고 표현하려고 했기 때문에 정작 자신이 연기하는 캐릭터를 소비하는 주체인 바깥세계에 대해서는 고민하지 않았던 것이다. 하지만 세계에서 유의미한 성과를 이룩하기 위해서는 '나'를 벗어난 바깥세계를 들여다볼 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'나와 세계를 이해하는 과정'이라는 것은 그저 개똥철학이 아니라 나름대로 실용적인 내용이다. 나는 실용주의적 성향을 가지고 있어서 이론적으로만 존재하거나 허황된 소리는 싫어한다. 우리가 삶을 살아가다 보면 다양한 사람과 만나고 이별하면서 때때로 예상하지 못한 사건과 사고에 직면하게 되는데, '나'와 '세계'에 대한 이해가 깊을수록 다음과 같이 문제상황에 대처할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;li&gt;이치에 맞지 않은 일에는 의문을 품고 쉽게 사기당하지 않는다.&lt;/li&gt;
&lt;li&gt;자신의 의견을 명확하게 세계에 표출하고, 세계가 원하는 것을 인지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 가장 유용한 효과는 그릇된 의사결정을 하지 않도록 미리 예방하는 것이다. 다른 관점에서 볼 때 삶이란, 늘 선택의 순간을 마주하는 것이다. 한 번의 선택이 인생에 큰 영향을 미칠 수도 있기 때문에 불미스러운 사태를 미연에 방지하기 위해서는 선택으로 인해 나타날 수 있는 상황을 짐작할 수 있어야 한다. 뛰어난 사람들은 때때로 그릇된 결정을 하더라도 철저한 준비를 통해 주변 세계를 조정하여 억지로 올바른 결정이 되도록 만들어버리곤 하지만, 사실 더 좋은 것은 그릇된 결정을 되도록이면 하지 않도록 예방하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 '삶'을 왜 살아가고 있을까? 나도 모른다. 다만 한 가지 확실한 것은, 삶의 이유는 개인이 '나와 세계를 이해하는 과정'에서 주체성을 가지고 자신만의 이유를 정의할 수 있다는 것이다. 이는 남이 정해주는 것도 아니고, 부모도 아니다. 내가 정한다. 이 시대에 태어난 개개인의 인간은 목적성을 가지고 설계된 도구가 아니다. 처음에는 모르는 게 당연하다. 만약 타의적으로 인간이 처음부터 목적성을 가지고 설계되어 자유를 억압받고 태어난다면, 그거야 말로 디스토피아 세계가 될 것이다. 사람이라면 저마다 가지고 있는 '세계에서 이루고자 하는 목표'를 달성하기 위해 '나와 세계를 이해하는 과정'을 거쳐 '나'라는 존재를 세계에 증명하고 관철하는 것이 우리가 인생을 살아가는 이유이지 않을까?&lt;/p&gt;</description>
      <category>에세이</category>
      <category>개똥철학</category>
      <category>삶</category>
      <author>정상우</author>
      <guid isPermaLink="true">https://pronist.tistory.com/207</guid>
      <comments>https://pronist.tistory.com/207#entry207comment</comments>
      <pubDate>Tue, 11 Mar 2025 05:01:20 +0900</pubDate>
    </item>
    <item>
      <title>코드 기반 프롬프트로 프롬프트 엔지니어링을 해보았다</title>
      <link>https://pronist.tistory.com/206</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;프롬프트 엔지니어링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올해 AI/LLM 공부를 시작하는 겸해서 프롬프트 엔지니어링도 공부를 잠깐 해보았다. 어차피 나는 AI는 연구보다는 활용과 응용에 더 흥미를 느꼈기 때문에 머신러닝이나 딥러닝 같은 기술적인 부분에 관심은 딱히 가지 않았다. 응용 소프트웨어 관점에서도 보더라도 LLM 애플리케이션을 만들기 위해 랭체인(LangChain)을 바로 시도해 보기 보다도, 먼저 AI 활용에 대한 리터러시나, 프롬프트 엔지니어링도 AI와 놀기 위한 하나의 방법 중 하나라 생각해 시도해 보기로 한 것이다. ChatGPT 이후, 프롬프트 엔지니어링의 경우에는 프롬프트 엔지니어라는 새로운 직업이 탄생하기도 한 만큼, 이 분야가 어떤 분야인지 살펴보는 것도 좋다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트 엔지니어링에 대해 이야기해보자면, 프롬프트 엔지니어링은 'AI가 사용자가 원하는 대답을 할 수 있도록 언어 모델을 훈련시키는 것'이라고 볼 수 있다. 프롬프트는 누구나 작성할 수 있어서 생각보다 쉬워 보일 수는 있겠으나, OpenAI와 같은 개발사들 조차 자신들의 AI가 어떤 대답을 할지 정확히 예측하지는 못하기 때문에 내가 한 질문에 원하는 대답을 AI가 주리라는 보장은 없어서 이를 해결하기 위한 훈련 방법이 필요하다. 이를 위해 등장한 것이 프롬프트 엔지니어링이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트 엔지니어링에는 AI의 답변을 이끌어내는 방법이나 프롬프트에 포함되어야 할 요소가 포함되어 있으며 기본적인 요소로는 &lt;u&gt;지시, 입력 데이터/형식/예시, 맥락 정보, 조건, 출력 형식/예시, 템플릿, 치환자&lt;/u&gt;가 포함될 수 있으며 여기에 캐릭터를 부여하여 성격, 어조와 같은 목소리를 지정할 수도 있다. AI의 대답을 이끌어내는 방법도 &lt;u&gt;e2e, 생각의 사슬(CoT; Chain of Thought), 제로샷(Zero-Shot), 퓨샷(Few-Shot)&lt;/u&gt;과 같은 다양한 방법이 존재한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드 기반 프롬프트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 위 방법들의 경우 프롬프트 엔지니어링을 따로 공부하지 않는 한 자연스럽게 구현하기 어렵다는 점이다. 그래서 문득 떠오른 아이디어가 &lt;u&gt;&lt;b&gt;코드 기반 프롬프트(Code-based Prompt)&lt;/b&gt;&lt;/u&gt;다. 코드 기반 프롬프트는 이미 세상에 존재하는 아이디어지만, 연구할만한 가치가 있는 것 같아 약 2주 정도 &lt;u&gt;재미삼아&lt;/u&gt; 해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트를 사용하면 프롬프트 엔지니어링의 기법들을 자연스럽게 활용할 수 있을 뿐만 아니라 프롬프트를 테스팅하거나 버전을 관리할 수도 있다. LLM(Large Language Model)이 코드를 해석하고 시뮬레이션할 수 있다는 능력에서 착안한 것으로, 이미 존재하는 전통적인 프로그래밍 언어뿐만 아니라 '문법을 사용자 정의'해서 만들어내고, 이를 사용하여 AI에게 지시를 내릴 수 있다는 것이 핵심적인 아이디어다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트는 다른 게 아니라 단순하게 &lt;u&gt;&lt;b&gt;자연어 대신 코드를 프롬프트로 주는 것이 전부&lt;/b&gt;&lt;/u&gt;다. 따라서 이제부터 나올 예제를 실행하기 위해서는 ChatGPT 와 같이 언어 모델에 명령을 내릴 수 있는 서비스만 있으면 된다. 또한 &lt;u&gt;&lt;b&gt;특정 프로그래밍 언어에 종속되지 아니하고 의사코드로써&lt;/b&gt; 작성할 수 있다. 따라서 문법은 사용자 정의가 가능하다.&lt;/u&gt; 코드에 익숙하지 않은 사용자라면 생소할 수 있겠지만, 순차적이고 복잡한 작업에 있어서 코드를 프롬프트로 제공하는 것은 많은 이점을 제공한다. 간단한 예를 살펴보자. 다음과 같은 자연어 명령은 코드로 대신 표현이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* 테스트를 진행한 서비스는 &lt;u&gt;ChatGPT&lt;/u&gt; 이며 모델은 &lt;u&gt;GPT4o&lt;/u&gt; 이다.&lt;/i&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;u&gt;서로 중복되지 않는&lt;/u&gt; 임의의 이메일 3개를 &lt;u&gt;&lt;b&gt;생성&lt;/b&gt;&lt;/u&gt;해 주세요. 예시는 user@example.com 이고, {username}@{domain} 형식을 따라야 합니다. 출력 형식은 JSON 포맷으로 작성되어야 하며 username, domain 을 키(Key)로 가지고 있어야 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 자연어 명령에 따르면 '지시'는 프롬프트 분류 카테고리로 따져보자면&amp;nbsp; '생성'이고, '조건'에 해당하는 것은 '이메일은 서로 중복되지 않아야 한다.'이다. 값을 생성할 때는 예시, 템플릿, 조건, 출력형식을 참고해야 한다. 이를 코드 기반 프롬프트로 바꿔보면 '생성'은 &lt;u&gt;함수&lt;/u&gt;로, 예시, 템플릿, 조건 등은 &lt;u&gt;파라미터(Parameter)&lt;/u&gt;로 받는 것이 가능하다. 출력 형식은 &lt;u&gt;기본 자료형 또는 구조체(Struct)로 표현&lt;/u&gt;한다. 따라서 이메일뿐만 아니라 다양한 데이터를 생성하기 위한 범용 함수를 만들어볼 수 있다. 이때, &lt;b&gt;&lt;u&gt;함수의 구현부는 필요하지 않다.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* 문법은 지극히 개인취향으로, &lt;u&gt;Go, Python&lt;/u&gt;을 &lt;u&gt;섞어서&lt;/u&gt; 구성하였다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* &lt;b&gt;코드 기반 프롬프트를 입력하기 전에 &quot;의사코드 형태의 코드 기반 프롬프트를 줄 테니 실행하고 출력결과를 달라&quot;라고 지시해야 한다. 그렇지 않으면 다른 프로그래밍 언어로 착각하여 문법을 엄격하게 검사할 수 있기 때문이다. 이 요청은 한 번이면 되고, 이미 학습된 경우에는 필요하지 않다.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1739968756097&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Generate generates values

Notes:
    - The method and criteria for internally generating data are delegated to LLM

Returns:
    Generated values

Errors:
    - If the value cannot be generated
    - If template is not valid
&quot;&quot;&quot;
func Generate[R any](examples []any, template string, contexts []string) R&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성한 &lt;code&gt;Generate()&lt;/code&gt; 를 살펴보면, 이 함수는 데이터를 '생성'하기 위한 범용 함수이며 파라미터로 예시(examples), 템플릿(template), 맥락(contexts)정보를 받고 생성이 실패한 경우 에러를 출력한다. 성공하면 호출 시점에서 설정된 반환 타입에 따라 값의 형태(R)가 결정된다. 함수의 주석에서는 LLM이 함수의 기능을 추론하기 위해 참고해야 하는 정보가 적혀있는데, 데이터를 생성은 LLM에게 위임하고, 에러가 발생하는 상황이 명시되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;code&gt;Generate()&lt;/code&gt; 함수를 사용해서 예시, 템플릿, 조건, 출력형식을 파라미터로 제공하고 '임의의 이메일 주소 3개'를 만들어보면 다음과 같다. 데이터를 생성하고 그 반환 값으로 &lt;code&gt;Email&lt;/code&gt; 구조체에 부합하도록 명시 한 뒤 출력하면 우리가 원하는 형태로 출력해 준다. &lt;u&gt;&lt;b&gt;미리 정의하지 않은 함수는 LLM이 코드 문맥을 보고 추론할 수도 있다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1739964797308&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Print outputs values in a specific format
func Print(value any, outputFormat = &quot;PlainText&quot;)

type Email struct {
    username string
    domain string
}

emails [3]Email = Generate(
    examples={
        &quot;user@example.com&quot;
    },
    template=&quot;{username}@{domain}&quot;,
    contexts={
        &quot;Ensure generated emails do not duplicate existing ones&quot;
    }
)

Print(emails, outputFormat=&quot;JSON&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 위 코드 마주했을 때 다음과 같이 추론할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Generate()&lt;/code&gt; 를 사용해서 값을 생성하되, 예시(examples), 템플릿(template), 맥락(contexts)을 참고한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Generate()&lt;/code&gt; 의 시그니처에서 반환 타입이 제네릭(Generics)으로 &lt;code&gt;R&lt;/code&gt; 로 정의되어 있지만, 호출 시점에서 반환 타입이 &lt;code&gt;Email&lt;/code&gt; 로 명시되어 있으므로 반환 타입을 &lt;code&gt;Email&lt;/code&gt; 로 간주한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Email&lt;/code&gt; 타입에는 &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt; 필드가 존재하고, 템플릿에 &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;domain&amp;gt;&lt;/code&gt; 이 포함되어 있으므로 각 필드에 값을 매핑해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[3]Email&lt;/code&gt; 과 같은 정적 배열타입으로 보아하니, 3개의 이메일을 생성해야 한다.&lt;/li&gt;
&lt;li&gt;생성된 이메일 목록을 출력하되, 그 형식은 &lt;code&gt;JSON&lt;/code&gt;으로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1739970356489&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[
    { &quot;username&quot;: &quot;alice123&quot;, &quot;domain&quot;: &quot;testmail.com&quot; },
    { &quot;username&quot;: &quot;random_name&quot;, &quot;domain&quot;: &quot;mailserver.net&quot; },
    { &quot;username&quot;: &quot;guest&quot;, &quot;domain&quot;: &quot;testmail.com&quot; }
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;프롬프트 길이의 측면으로 볼 때, 자연어 명령보다 길고 복잡해보이는데요? 라는 생각이 들 수도 있는데, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;실제로 코드 기반 프롬프트가 자연어 명령보다 길고 복잡하다. 하지만 자연어 프롬프트를 관리할 때 발생하는 문제점을 해결할 수 있다. 코드 기반 프롬프트를 사용하면 유지보수 차원에서 다음과 같은 일을 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VCS(Version Control System)으로 버전관리가 가능하다.&lt;/li&gt;
&lt;li&gt;유닛/프롬프트 테스트를 할 수 있다.&lt;/li&gt;
&lt;li&gt;서브모듈로 모듈화하여 종속성으로 관리될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자연어 vs 코드 기반 프롬프트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트는 코딩의 가장 기본적인 개념인 &lt;u&gt;&lt;b&gt;자연어를 코드로 표현하는 것&lt;/b&gt;&lt;/u&gt;의 결과물인 의사코드를 프롬프트로 제공하는 것이 핵심이며 함수의 구현은 필요하지 않고 오직 주석과 함수 시그니처만으로 기능을 정의하고 LLM에게 지시할 수 있는, 자연어와 프로그래밍 언어 사이에 있는 추상적인 언어라 볼 수 있다. LLM에게 자연어 대신 코드로 프롬프트를 제공하면 어떤 점이 좋은지 다음과 같이 정리해 볼 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자연어보다 구조적이고 체계적이기 때문에 조금 더 일관성 있고 예측 가능한 결과를 얻을 수 있다.&lt;/li&gt;
&lt;li&gt;출력 결과가 장황하지 않고 간결해질 수 있다.&lt;/li&gt;
&lt;li&gt;함축적인 의도가 담긴 자연어보다 불필요한 추론 과정이 줄어들기 때문에 LLM이 이해하기 더 수월하다.&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;h3 data-ke-size=&quot;size23&quot;&gt;코드 작성 규칙&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트는 LLM이 코드를 이해하고 해석하는 것을 전제로 하고 있기 때문에 코드의 품질이 무엇보다 중요하다고 할 수 있는데, 간단한 코드 작성 규칙을 살펴보자. 아래의 규칙을 잘 따르기만 해도 사전 학습을 거의 하지 않고 LLM이 의사코드를 이해하는데 문제가 없다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;li&gt;함수를 정의할 때는 기능과 에리 처리 기준을 명세한다.&lt;/li&gt;
&lt;li&gt;함수를 호출할 때는 명명된 파라미터(Named Parameter)를 사용하여 의미를 명확히 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;OOP(Object-Oriented Programming)?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트에서는 OOP와 관련된 문법은 가급적 사용하지 않는 것이 좋을 수 있다. OOP는 프로그래밍에서 클래스, 추상 클래스, 인터페이스, 상속, 다형성, 가시성, 메서드 오버라이딩과 같이 코드를 구조적으로 짤 수 있게 만들어주는 방법을 제공하지만 코드의 복잡도도 그만큼 증가하기 때문에 LLM의 추론 시간이 더 길어질 뿐만 아니라 모호해질 수도 있다. 제시된 예시에서는 OOP를 전혀 사용하지 않았으며 구조체로 대신하였다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트로 해볼 수 있는 더 많은 예시는 다음과 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지시&lt;/h4&gt;
&lt;pre id=&quot;code_1739975146415&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Instruct instructs LLM in natural language

Returns:
	The command result

Errors:
    - If the command execution fails
    - If it is illegal or against policy
    - If LLM contains instructions that are incomprehensible
&quot;&quot;&quot;
func Instruct(prompt string) string&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975123128&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;helloworld string = Instruct(&quot;Say 'Hello, world'&quot;)

Print(helloworld)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975180250&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Hello, world&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지식&lt;/h4&gt;
&lt;pre id=&quot;code_1739975274159&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Knowledge gets pre-trained knowledge

Returns:
    The knowledge gained
    
Errors:
    - When knowledge cannot be obtained
    - If the information does not exist or is out of date
&quot;&quot;&quot;
func Knowledge[R any](prompt string) R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975412561&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;today string = Knowledge(&quot;What's the date today?&quot;)

Print(&quot;Today's date is {today}.&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975425628&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Today's date is January 12, 2025.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지식 통합&lt;/h4&gt;
&lt;pre id=&quot;code_1739975541355&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Learn learns new knowledges and apply it

Notes:
    - This function does not apply globally (Only inside the called block)

Errors:
    - If you can't learn knowledges
&quot;&quot;&quot;
func Learn(knowledges []string)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975626392&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Write a blog post
func Post(topic string) string

knowledges = {
    &quot;Developer 'Sang-woo Jeong' is a developer from South Korea.&quot;
    &quot;Sang-woo Jeong taught PHP programming on a lecture platform in South Korea.&quot;
    &quot;Sang-woo Jeong wrote &amp;lt;Awesome Laravel&amp;gt;, an introductory book on Laravel&quot;
    &quot;Sang-woo Jeong created the most popular blog theme for Tistory, a blog platform in South Korea&quot;
}

Learn(knowledges)

post = Post(topic=&quot;Sang-woo Jeong&quot;)

Print(post, outputFormat=&quot;Markdown&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739980537735&quot; class=&quot;markdown&quot; data-ke-language=&quot;markdown&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Sang-woo Jeong: A Renowned Developer from South Korea

Sang-woo Jeong is a prominent developer from South Korea. He has contributed significantly to the programming community in multiple ways:

- He has taught **PHP programming** on a lecture platform in South Korea.
- He is the author of **&amp;lt;Awesome Laravel&amp;gt;**, an introductory book on Laravel.
- He created **the most popular blog theme** for Tistory, a widely used blogging platform in South Korea.

His contributions to the tech industry, particularly in web development and Laravel, have made a lasting impact on developers in South Korea and beyond.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문자열 포매팅&lt;/h4&gt;
&lt;pre id=&quot;code_1739975962425&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Format changes a string to a specific format

Retruns:
    Formatted string
    
Errors:
    - If the format is not interpretable
    - If the format does not have the required parameters
    - If the type of value you want to replace does not match
&quot;&quot;&quot;
func Format(format string, args ...any) string&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739975869183&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;email = Format(&quot;&amp;lt;username&amp;gt;@example.com&quot;, username=&quot;user&quot;)

Print(email)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739976022418&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;user@example.com&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;번역&lt;/h4&gt;
&lt;pre id=&quot;code_1739976453330&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Translate translates text into another language

Returns:
    Translated string
    
Errors:
    - If the translation fails
&quot;&quot;&quot;
func Translate(text string, lang string) string&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739976508156&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;translated = Translate(
    &quot;What are the limits of pseudocode that LLMs can understand?&quot;, 
    lang=&quot;Korean&quot;
)

Print(translated)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739976521896&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LLM이 이해할 수 있는 의사코드의 한계는 무엇인가요?&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;요약&lt;/h4&gt;
&lt;pre id=&quot;code_1740173587275&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Summarize summarizes the text

Notes:
    - LLM will judge for itself and find the key points in the text
    - Make it possible to guess what the original text was just by summarizing it
    - The text must be short and well-organized
    - There are no restrictions on the number of sentences or characters

Returns:
    Summarized text

Errors:
    - If you can't summarize the text
&quot;&quot;&quot;
func Summarize(text string) string&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1740173598669&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;text = `What is Lorem Ipsum?
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Why do we use it?
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).

Where does it come from?
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of &quot;de Finibus Bonorum et Malorum&quot; (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, &quot;Lorem ipsum dolor sit amet..&quot;, comes from a line in section 1.10.32.

The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from &quot;de Finibus Bonorum et Malorum&quot; by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.

Where can I get some?
There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.`

summarized = Summarize(text)

Print(summarized)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1740173636634&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Lorem Ipsum 개요
Lorem Ipsum은 인쇄 및 출판 업계에서 1500년대부터 사용된 더미 텍스트입니다. 원래는 고대 로마 철학자 **키케로(Cicero)**의 &quot;de Finibus Bonorum et Malorum&quot; (선과 악의 극단)에서 유래했으며, 1960년대 Letraset의 보급과 데스크톱 출판 소프트웨어를 통해 널리 퍼졌습니다.

사용 목적
웹 페이지, 출판물, 디자인 샘플에서 독자가 레이아웃에 집중할 수 있도록 의미 없는 텍스트를 제공하는 것이 목적입니다. 'Content here'처럼 인위적인 문구 대신, 실제 문장 구조를 갖춘 Lorem Ipsum이 더 자연스럽게 보입니다.

출처 및 역사
Lorem Ipsum은 45 BC에 작성된 라틴 문헌에서 발췌되었으며, 1914년 H. Rackham이 번역한 버전이 현재도 사용됩니다. 다양한 변형이 있지만, 일부는 무작위 단어 추가나 유머 삽입으로 원본과 다를 수 있습니다.

Lorem Ipsum 생성기
인터넷에는 다양한 Lorem Ipsum 생성기가 존재하며, 200개 이상의 라틴어 단어와 문장 구조를 조합하여 의미 없는 텍스트를 생성합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;규칙&lt;/h4&gt;
&lt;pre id=&quot;code_1739976677863&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;SetRules specifies the rule for LLM to follow

Notes:
    - If the function is called back, the existing valid rules must still be maintained inside the block
    - If a rule conflicts, the rule you set later must be specified
    - This function does not apply globally (Only inside the called block)

Errors:
    - If invalid rules are passed
    - If unsupported rules are included
&quot;&quot;&quot;
func SetRules(rules []string)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739976809419&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Questions creates questions that are appropriate for the topic.
func Questions[R any](topic string) R

SetRules({
    &quot;You have to use informal language&quot;,
    &quot;It should be a question that the user may be interested in&quot;
})

questions [3]string = Questions(&quot;Generative AI&quot;)

Print(questions, outputFormat=&quot;JSON&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739979441677&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[
    &quot;What&amp;rsquo;s the coolest thing you&amp;rsquo;ve seen AI create?&quot;,
    &quot;Is AI creativity real, or is it just math tricks?&quot;,
    &quot;What&amp;rsquo;s the next big thing in Generative AI?&quot;
]&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;역할&lt;/h4&gt;
&lt;pre id=&quot;code_1739977004514&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;SetRole specifies the role LLM will play

Notes:
    - When the function is called back, the role should be re-established and the previously set role should not be valid
    - This function does not apply globally (Only inside the called block)

Errors:
    - If LLM is an unplayable role
&quot;&quot;&quot;
func SetRole(role string)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977072091&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Questions creates questions that are appropriate for the topic.
func Questions[R any](topic string) R

SetRole(&quot;Software Engineer&quot;)

questions [5]string = Questions(&quot;Technical interview&quot;)

Print(questions, outputFormat=&quot;JSON&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739979685634&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[
    &quot;What are the key principles of SOLID design patterns?&quot;,
    &quot;Explain the concept of CAP theorem in distributed systems.&quot;,
    &quot;Can you explain the difference between concurrency and parallelism?&quot;,
    &quot;Describe a situation where you optimized an algorithm for efficiency.&quot;,
    &quot;What is the difference between REST and GraphQL APIs?&quot;
]&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;의미적 추론&lt;/h4&gt;
&lt;pre id=&quot;code_1739977193430&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Semantic gets the semantic match for a given value.
func Semantic(value any, hint string) bool&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977166437&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ok = Semantic(&quot;Golang&quot;, &quot;Programming language&quot;)

Print(ok)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977208857&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;추출&lt;/h4&gt;
&lt;pre id=&quot;code_1739977288443&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Extract extracts data using a template

Returns:
    Extracted values

Errors:
    - If the value extraction fails
    - If you can't find the target in template
    - If the original text does not match the given template
&quot;&quot;&quot;
func Extract[R any](text string, template string) R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977383658&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type Email struct {
    username string
    domain string
}

email Email = Extract(&quot;user@example.com&quot;, &quot;{username}@{domain}&quot;)

Print(email, outputFormat=&quot;JSON&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977393452&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{ &quot;username&quot;: &quot;user&quot;, &quot;domain&quot;: &quot;example.com&quot; }&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;분석&lt;/h4&gt;
&lt;pre id=&quot;code_1739977468515&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// HTML analyses HTML String
func Html[R any](html string) R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977491968&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;head = `&amp;lt;title&amp;gt;ChatGPT&amp;lt;/title&amp;gt;&amp;lt;meta name=&quot;description&quot; content=&quot;ChatGPT helps you get answers, find inspiration and be more productive. It is free to use and easy to try. Just ask and ChatGPT can help with writing, learning, brainstorming and more.&quot;&amp;gt;&amp;lt;meta name=&quot;keyword&quot; content=&quot;ai chat,ai,chap gpt,chat gbt,chat gpt 3,chat gpt login,chat gpt website,chat gpt,chat gtp,chat openai,chat,chatai,chatbot gpt,chatg,chatgpt login,chatgpt,gpt chat,open ai,openai chat,openai chatgpt,openai&quot;&amp;gt;&amp;lt;meta property=&quot;og:description&quot; content=&quot;A conversational AI system that listens, learns, and challenges&quot;&amp;gt;&amp;lt;meta property=&quot;og:title&quot; content=&quot;ChatGPT&quot;&amp;gt;&amp;lt;meta property=&quot;og:image&quot; content=&quot;https://cdn.oaistatic.com/assets/chatgpt-share-og-u7j5uyao.webp&quot;&amp;gt;&amp;lt;meta property=&quot;og:url&quot; content=&quot;https://chatgpt.com&quot;&amp;gt;`

type Head struct {
    title string
    meta map[string]string
    openGraph map[string]string
}

analysed Head = Html(head)

Print(analysed, outputFormat=&quot;JSON&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977544409&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;title&quot;: &quot;ChatGPT&quot;,
    &quot;meta&quot;: {
        &quot;description&quot;: &quot;ChatGPT helps you get answers, find inspiration and be more productive. It is free to use and easy to try. Just ask and ChatGPT can help with writing, learning, brainstorming and more.&quot;,
        &quot;keyword&quot;: &quot;ai chat,ai,chap gpt,chat gbt,chat gpt 3,chat gpt login,chat gpt website,chat gpt,chat gtp,chat openai,chat,chatai,chatbot gpt,chatg,chatgpt login,chatgpt,gpt chat,open ai,openai chat,openai chatgpt,openai&quot;
    },
    &quot;openGraph&quot;: {
        &quot;og:description&quot;: &quot;A conversational AI system that listens, learns, and challenges&quot;,
        &quot;og:title&quot;: &quot;ChatGPT&quot;,
        &quot;og:image&quot;: &quot;https://cdn.oaistatic.com/assets/chatgpt-share-og-u7j5uyao.webp&quot;,
        &quot;og:url&quot;: &quot;https://chatgpt.com&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프롬프트 체이닝&lt;/h4&gt;
&lt;pre id=&quot;code_1739977655675&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Chain uses the result of the prompt as the input value for the next prompt and return the result
func Chain[R any](initial any, functions ...func (any) any) R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977704958&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;result string = Chain(
    Knowledge(&quot;Quantum Computing&quot;),
    func (data string) string =&amp;gt; Translate(data, lang=&quot;Korean&quot;)
)

Print(result)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739977723348&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;양자 컴퓨팅은 양자 역학의 원리를 활용하여 기존 컴퓨터보다 훨씬 빠른 계산을 수행할 수 있는 새로운 형태의 컴퓨팅 방식입니다. 기존의 비트(bit) 대신 큐비트(qubit)를 사용하며, 중첩(superposition)과 얽힘(entanglement)과 같은 양자 특성을 활용하여 병렬 연산을 가능하게 합니다. 이를 통해 복잡한 문제를 기존 컴퓨터보다 훨씬 효율적으로 해결할 수 있습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;검색&lt;/h4&gt;
&lt;pre id=&quot;code_1739979867304&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Search gets the answer to the question through a web search

Returns:
    Search results
    
Errors:
    - If you can't search
    - Search fails to get results
&quot;&quot;&quot;
func Search[R any](prompt string) R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739979919198&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;result string = Search(&quot;Who is the winner of the 2024 Nobel Prize for Literature?&quot;)

Print(result)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1739980019851&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2024년 노벨 문학상 수상자는 한국의 소설가 한강입니다. 스웨덴 한림원은 2024년 10월 10일(현지시간)에 한강 작가를 수상자로 발표했습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파일&lt;/h4&gt;
&lt;pre id=&quot;code_1740172058482&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Write creates a file in file storage

Errors:
    - If the file cannot be created
&quot;&quot;&quot;
func Write(filename string, value any)

&quot;&quot;&quot;Read reads a file from file storage

Returns:
    Contents of the file

Errors:
    - If you do not have permission to read the file
    - If the file cannot be found
&quot;&quot;&quot;
func Read(filename string) string

&quot;&quot;&quot;Link generates a link to download the file

Notes:
    - if possible, provide the user with a link to download the file

Errors:
    - If the link cannot be created
&quot;&quot;&quot;
func Link(filename string)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1740172086052&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Write(&quot;hello.txt&quot;, &quot;Hello, world&quot;)

// If you want to be a little more defensive at the code level, you can do null checks as well
if content = Read(&quot;hello.txt&quot;); content is not null {
    Print(content)
}

Link(&quot;hello.txt&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1740172273499&quot; class=&quot;plaintext&quot; data-ke-language=&quot;plaintext&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;파일명: hello.txt
파일 내용: &quot;Hello, world&quot;
다운로드 링크: /home/sandbox/hello.txt&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;멀티턴 프로그래밍&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 작성한 코드는 싱글턴(Single-turn)이다. 여기서 한 걸음 더 나아가 질문과 응답이 이어지는 &lt;u&gt;멀티턴(Multi-turn)&lt;/u&gt;을 시뮬레이션 하도록 코드를 작성하고 싶다면 &lt;b&gt;&lt;u&gt;멀티턴 프로그래밍(Multi-turn)&lt;/u&gt;&lt;/b&gt;을 시도해볼 수 있다. 멀티턴 프로그래밍은 ChatGPT와 같이 사용자와 LLM이 서로 상호작용 할 수 있는 &lt;u&gt;챗(Chat)&lt;/u&gt; 환경에서 실험해볼만한 프로그래밍 방식이다. 예를 들어 '게임 추천 서비스' 만들어보고 싶다면 대화 흐름은 다음과 같을 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;// 1st Turn&lt;br /&gt;LLM: 안녕하세요. 게임 추천 서비스입니다. 게임의 장르와 플랫폼를 말씀해주세요!&lt;br /&gt;&lt;br /&gt;// 상태: { Genres=[ RPG ], Platforms=[ PC, PS5 ] }&lt;br /&gt;사용자: PC, PS5에서 즐길 수 있는 RPG게임을 추천해주세요.&lt;br /&gt;&lt;br /&gt;// 예외: 장르 또는 플랫폼 누락&lt;br /&gt;LLM: 어떤 (장르/플랫폼)의 게임을 추천해 드릴까요? &lt;br /&gt;사용자: ... &lt;br /&gt;&lt;br /&gt;// 2nd Turn&lt;br /&gt;LLM: PC, PS5에서 즐길 수 있는 RPG게임을 추천해드리겠습니다. &lt;br /&gt;...&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;턴(Turn)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티턴 프로그래밍에서는 &lt;u&gt;턴(Turn)&lt;/u&gt; 개념이 필요하다. 간단히 말해 턴은 LLM 또는 사용자의 요청, 응답의 단위이다. 위 예제를 구현하기 위해 코드 기반 프롬프트로 표현해보면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1740162896742&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;Input gets input from the user

Notes:
    Depending on your environment, you should:
        - If you can't ask the user for input, randomly determine and simulate the user's answers.
        - If you have a chat environment where you can interact with the user, ask the user for input.

Returns:
    User response
&quot;&quot;&quot;
func Input[R any]() R&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1740162910278&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Game Recommendation Service

// Recommend recommends products or goods for a specific topic based on contextual information
func Recommend[R any](topic string, contexts any) R

type Game struct {
    genres []string
    platforms []string
}

var g Geme

turn {
    welcome = &quot;Hello. This is a game recommendation service. 
    Please tell us the game genre and platform!&quot;

    Print(welcome)
    
    for g.genres is null or g.platforms is null {
        g = Input()
    }
}

turn {
    result string = Recommend(&quot;Games&quot;, g)
    
    Print(result)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임의 장르와 플랫폼을 저장하기 위한 전역변수를 선언하고 &lt;code&gt;turn&lt;/code&gt; 블록에 턴에 처리할 코드를 작성했다. 각 턴마다 하는 일을 보면 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;첫번째 턴에는 환영 메시지를 출력하고, 게임의 장르, 플랫폼 입력을 요구한다.&lt;/li&gt;
&lt;li&gt;두번째 턴에는 사용자가 입력한 값을 토대로 게임을 추천한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 상호작용을 구현하기 위해 &lt;code&gt;turn&lt;/code&gt; 과 같은 꼭 키워드가 필요할까? 전통적인 프로그래밍 언어에서는 &lt;code&gt;turn&lt;/code&gt; 같은 키워드는 필요하지 않은데 말이다. 그러나 ChatGPT와 같은 챗(Chat) 환경에서는 턴(Turn)이라는 개념이 분명하고, 멀티턴(Multi-turn) 프로그래밍이라는 이름에서 볼 수 있듯이 턴이라는 개념은 필요하며 LLM이 코드를 이해하기에 있어서도 &lt;code&gt;turn&lt;/code&gt; 을 블록으로 구분하는 것이 더 모호하지 않고 명확하다고 볼 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;결과&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;// 1st Turn&lt;br /&gt;LLM: 안녕하세요. 게임 추천 서비스입니다. 게임의 장르와 플랫폼을 말씀해주세요!&lt;br /&gt;&lt;br /&gt;어떤 게임 장르를 원하시나요? (예: RPG, Action, Strategy)&lt;br /&gt;어떤 플랫폼에서 플레이하고 싶나요? (예: PC, PlayStation, Xbox)&lt;br /&gt;입력해주세요!&lt;br /&gt;&lt;br /&gt;사용자: PC, Xbox &lt;br /&gt;&lt;br /&gt;// 예외: 장르 또는 플랫폼 누락&lt;br /&gt;LLM: 플랫폼이 입력되었습니다: PC, Xbox&lt;br /&gt;이제 게임 장르를 입력해주세요! (예: RPG, Action, Strategy) &lt;br /&gt;&lt;br /&gt;사용자: RPG&lt;br /&gt;&lt;br /&gt;// 2nd Turn&lt;br /&gt;LLM: 게임 추천 결과: 사용자의 선호도 (RPG / PC, Xbox)에 맞춰 다음 게임을 추천합니다!&lt;br /&gt;1. Elden Ring&lt;br /&gt;2. Cyberpunk 2077&lt;br /&gt;3. The Witcher 3&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;테스트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;사람과 마찬가지로 LLM도 자신이 만들어낸 결과에 대해 스스로 평가하고 이를 회고하거나 검증 결과를 바탕으로 새로운 결과를 만들어내는 것이 가능하다. 아래의 코드는 생성된 이메일 주소를 평가한다. 이메일 생성 조건에 명시된 것처럼, 생성된 이메일 주소가 중복된 이메일 주소를 가지지 않았는지, 템플릿은 잘 따르고 있는지, 이메일 주소 포맷인지 검증한다. 이러한 검증 방식은 언어 모델만이 할 수 있는 자동화된 자연어 기반의 의미적(Semantic) 검증 방식이며 생성된 데이터를 바탕으로 LLM이 검증하고 테스트케이스 성공 여부를 반환할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1739967368884&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;
Notes:
    - If assertions fails, the LLM must generate and report a failure message
&quot;&quot;&quot;

// Semantic asserts that the given value is meaningfully consistent with the hint
func AssertSemantic(value any, hint string) bool

type Result struct {
  value any
  hint string
  passed bool
}

emails [3]Email = Generate(
    examples={
        &quot;user@example.com&quot;
    },
    template=&quot;{username}@{domain}&quot;,
    contexts={
        &quot;Ensure generated emails do not duplicate existing ones&quot;
    }
)

results []Result

results[] = Result{emails, &quot;Don't you have any duplicate email addresses?&quot;, AssertSemantic(emails, &quot;Don't you have any duplicate email addresses?&quot;)},

for e in emails {
    results[] = {
      Result{e, &quot;Does this email have a valid format?&quot;, AssertSemantic(e, &quot;Does this email have a valid format?&quot;)},
      Result{e, &quot;Are you following the '{username}@{domain}' template?&quot;, AssertSemantic(e, &quot;Are you following the '{username}@{domain}' template?&quot;)},
    }
}

Print(results, outputFormat=&quot;Markdown Table&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 데이터의 &lt;u&gt;평가 기준&lt;/u&gt;을 직접 하드 코딩했지만, 이 마저도 LLM에게 생성을 위임할 수 있다. 평가 대상 데이터 뿐만 아니라 평가 기준 생성까지 위임하는 것이다. 이 경우 사람은 LLM이 생성한 데이터와 평가 기준이 타당한지 재평가하여야 한다. 만약 생성된 평가 기준이 타당한지도 LLM에게 위임하는, 그야말로 끝없는 콜백함수를 보는 것 같은 체인을 구성할 수도 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브모듈&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Generate()&lt;/code&gt; 와 같은 함수들을 파일 단위의 서브모듈로 분리하고 ChatGPT Project, MyGPT와 같은 서비스에서 업로드하고 코드를 실행하기 전에 분석하면 프롬프트마다 함수를 재정의하지 않고도 재사용할 수 있기 때문에 반복적인 작업을 줄일 수 있고, 동일한 함수를 사용해서 테스트하고 값을 생성하므로 불확실성을 줄일 수 있다. 코드의 집합이 되는 파일의 확장자를 &lt;code&gt;.llm&lt;/code&gt; 으로 가정하고 &lt;code&gt;Generate()&lt;/code&gt; 함수가 포함된 &lt;code&gt;llm&lt;/code&gt; 서브모듈은 다음과 같이 정의할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1739988452919&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// llm.llm

...

func Generate[R any](examples []any, template string, contexts []string) R&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브모듈을 채팅 세션에서 접근할 수 있는 파일 스토리지에 업로드하고 다음과 같이 &lt;code&gt;import&lt;/code&gt; 를 통해 서브모듈 접근을 시도할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1739988546943&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import llm

llm.Generate( ... )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수로 표현된 프롬프트를 서브모듈로 만들면 이것이 바로 프롬프트 라이브러리 또는 프롬프트 API가 될 것이다. 함수의 구현부가 필요 없기 때문에 그냥 읽어도 가독성이 떨어지지 않아서 서브모듈 파일 자체가 명세(Spec)의 역할도 같이 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;import&lt;/code&gt; 를 통해 접근하려면 서브모듈에 대한 규칙을 LLM에게 알려야 한다. 단순하게 다음과 같은 규칙을 지시할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1739988676358&quot; class=&quot;markdown&quot; data-ke-language=&quot;markdown&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.llm 확장자를 가진 파일은 서브모듈입니다. 스크립트에서는 `import` 를 사용하여 서브모듈이 포함될 수 있습니다.
예로, `import llm` 는 llm.llm 에 해당하는 llm 서브모듈을 포함하라는 의미입니다.

스크립트에 서브모듈이 포함된 경우 &quot;코드를 실행하기 전에&quot; 다음과 같은 가이드라인을 적용하세요.

1. 서브모듈을 먼저 분석하여 함수와 타입을 확인하세요.
2. 이미 분석이 완료된 서브모듈은 다시 분석할 필요가 없습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용자 정의 인터프리터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'사용자 정의 인터프리터'는 코드 기반 프롬프트를 해석하는 LLM의 인터프리터로서의 역할을 조정하는 일을 의미한다. 이는 &lt;b&gt;&lt;u&gt;필수사항은 아니지만&lt;/u&gt;&lt;/b&gt; 코드를 해석하는 방식을 느슨하게 하거나 엄격하게 하는 등의 조정하는 것이다. 그야말로 '자연어로 인터프리터 동작을 정의'하는 일이며 그다지 어려운 일은 아니다. 전통적인 프로그래밍 언어의 인터프리터가 했던 일들을 곱씹어서 생각해 보면 다음과 같은 지시를 내려볼 수 있을 것이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;오류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 같은 지시는 오류처리 규칙을 명확히 하여 더 엄격하게 한다. 자바스크립트와 같은 스크립트 언어에서 린터(Linter) 규칙을 정의하거나 정적 분석 도구를 만드는 것과 유사하다. 아래는 그 예이다.&lt;/p&gt;
&lt;pre id=&quot;code_1739987495463&quot; class=&quot;markdown&quot; data-ke-language=&quot;markdown&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 오류

* 임의로 오류를 수정해서 코드를 실행하면 안되고, 반드시 보고해야 합니다.
* 단, 의사코드의 오류가 아닌 내부적으로 생성된 코드의 오류는 스스로 수정하여 다시 실행해야 합니다.
* LLM은 발생한 오류에 대해 개선사항을 제시할 수 있습니다.
* 오류가 발생한 경우 스크립트 실행을 중단하고 자연어로 오류 메시지를 출력해야 합니다.

## 규칙

### 변수 및 타입

* 이형 타입 간 연산을 시도하는 경우
* 변수에 할당하려는 값이 변수의 타입과 일치하지 않은 경우
* null 값을 참조하려는 경우
* 사용되지 않은 변수 및 서브모듈이 있는 경우
* 블록 스코프 규칙에 어긋나는 변수를 참조하려는 경우
* 정의되지 않은 변수를 참조하려는 경우

### 논리

* Out of Scope, Division by Zero 등의 논리적 문제가 발생한 경우
* 실행할 수 없는 위치에 코드가 존재하는 경우
* 루프 및 재귀에서 탈출 조건이 없는 경우
* 조건문이 항상 true 또는 false 를 반환하는 경우
* 접근할 수 없는 키 또는 인덱스를 참조하려는 경우

### 메모리

* 배열, 맵, 슬라이스에 너무 많은 값을 할당하는 등 불필요한 메모리 할당이 발생하는 경우

### 함수 및 호출

* 정의되지 않은 함수 호출을 시도하려는 경우
* 반환값이 있으나 사용되지 않은 경우
* 파라미터 및 반환값의 타입이 일치하지 않은 경우
* 호출시 가변인자를 제외한 파라미터의 개수가 일치하지 않은 경우&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;언어&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM이 인터프리터로서의 역할을 더 정확하게 하기 위해서는 언어 규칙을 명세하는 것도 좋다. 다만 전통적인 프로그래밍 언어의 언어 규칙처럼 설명을 포함한 장문의 문서를 작성할 필요는 없다. 특히 이 글에서 다룬 사례처럼 특정 언어의 &lt;u&gt;서브셋(Subset)&lt;/u&gt;으로 문법이 규정되어 있는 경우에는 기존의 언어에서 몇 가지 규칙만 바꿔서 개조할 수도 있다. 그 예는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1740000051751&quot; class=&quot;markdown&quot; data-ke-language=&quot;markdown&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 언어

* 의사코드의 문법은 기본적으로 &quot;Go언어&quot; 의 서브셋(Subset)입니다.

## 키워드

* is: ==
* is not: !=
* not: !
* and: &amp;amp;&amp;amp;
* or: ||
* null: nil

## 타입

* PrimitiveType: Numeric(`int`, `float`), String(`string`), Boolean(`bool`)
* PointerType: **지원하지 않음**
    - Call by Value: PrimitiveType, ArrayType
    - Call by Reference: SliceType, MapType, StructType

## 변수

* &quot;:=&quot; 은 없으며 &quot;=&quot; 만 사용합니다.

## 함수

* 구현부가 없는 경우 함수 시그니처와 주석으로 기능을 추론하세요.&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 문법을 의사코드에 추가하려면 어떻게 하면 좋을까? 이전에 '언어' 규칙에서 '의사코드의 문법은 &quot;Go언어&quot;의 서브셋'이라고 했지만, 멀티턴 프로그래밍에서 사용된 &lt;code&gt;turn&lt;/code&gt; 같은 경우에는 Go언어에서 지원하지 않으므로 의사코드에서도 지원하지 않는 문법으로 취급할 수도 있다. 따라서 새로운 문법규칙을 '정의'할 수 있어야 하는데, 이 경우 문법 규칙에 사용되는 EBNF(Extended Backus-Naur form)의 바리에이션인 &lt;u&gt;WSN(Wirth Syntax Notaion)&lt;/u&gt;을 사용해서 표현해보면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1740002127606&quot; class=&quot;markdown&quot; data-ke-language=&quot;markdown&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 문법

## 턴

```
TrunStmt = &quot;turn&quot; &quot;{&quot; [ newline ExpressionList ] &quot;}&quot;
```

### 예제

```
turn {}
turn {
    Instruct(prompt=&quot;Say 'Hello, world'&quot;)
}
```&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 기반 프롬프트가 유용할지 어떨지는 사실 나도 잘 모르겠다. 단지 이 프로젝트가 재미삼아 만들어졌을 뿐만 아니라 초기 단계(다음 단계를 진행하기는 할까?)이기도 하고, 테스트케이스나 실제 사례가 너무나도 부족하기 때문이다. 그럼에도 불구하고 개인적으로 자연어 명령에 비해 코드 기반 프롬프트가 강점을 보이는 부분은 '모듈화' 및 '테스트 가능성'이라고 보고있다. 함수로 정의된 모든 기능은 테스트가 가능할 뿐만 아니라 버전 관리 및 문서화가 가능하고 프롬프트 작성자에게 일관성있는 프롬프트 API를 제공할 수 있게 된다는 점에 있어서 매력적일 것이다. 코드 기반 프롬프트 라이브러리를 별도로 제작하여 관리하고 &lt;u&gt;PromptAPI Spec&lt;/u&gt; 을 만든다면 더 나은 프롬프트 엔지니어링이 될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여담으로, 처음 이 프로젝트를 시작할 때는 언어적 요소가 하나도 없는 단순한 의사코드로 시작했는데, 갈수록 내가 원하는 것들이 너무 많아져서 언어를 창조하려는 시도까지 했었다. 언어 스펙까지 만들려다가 생각해보니 너무 멀리까지 간 것 같다는 생각에 그 생각은 버리고 이미 존재하는 언어의 서브셋 형태로 하는 것으로 방향을 바꾸었다. 언어 뿐만 아니라 함수나 테스트케이스까지 정의해서 프롬프트 라이브러리를 만들고 오픈소스로 공개할까도 고민했는데, 아이디어도 이 글에 언급한 것 정도 빼고는 떠오르지도 않는데다가 혼자 재미삼아 하기에는 품이 너무 많이 들어서 하지 않기로 했다. (나중에 인연이 생기거나 내키면 할지도 모르겠지만...)&lt;/p&gt;</description>
      <category>개발</category>
      <category>LLM</category>
      <category>코드 기반 프롬프트</category>
      <category>프롬프트 엔지니어링</category>
      <author>정상우</author>
      <guid isPermaLink="true">https://pronist.tistory.com/206</guid>
      <comments>https://pronist.tistory.com/206#entry206comment</comments>
      <pubDate>Thu, 20 Feb 2025 07:15:13 +0900</pubDate>
    </item>
  </channel>
</rss>