<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[kdy1: The way I think]]></title><description><![CDATA[kdy1: The way I think]]></description><link>https://kdy1.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 15:30:40 GMT</lastBuildDate><atom:link href="https://kdy1.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[한국의 학벌에 대한 생각]]></title><description><![CDATA[내 블로그의 제목이 kdy1: The way I think 인만큼 앞으로는 내 생각을 더 자주 올리려고 한다.
한국 기준으로, 학벌은 사람을 볼 때 꽤나 유용한 지표이지만, 절대적이지는 않다. 경험적인 얘기일 뿐이지만, 성균관대학교 자퇴생으로서 느낀 것들이 몇 가지 있다.
대학까지 간 사람의 학벌은 학습 능력 x 성실함 에 대체로 비례한다. 그래서 의미가 ]]></description><link>https://kdy1.dev/2026-4-4-korean-edu</link><guid isPermaLink="true">https://kdy1.dev/2026-4-4-korean-edu</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Fri, 03 Apr 2026 23:08:31 GMT</pubDate><content:encoded><![CDATA[<p>내 블로그의 제목이 <code>kdy1: The way I think</code> 인만큼 앞으로는 내 생각을 더 자주 올리려고 한다.</p>
<p>한국 기준으로, 학벌은 사람을 볼 때 꽤나 유용한 지표이지만, 절대적이지는 않다. 경험적인 얘기일 뿐이지만, 성균관대학교 자퇴생으로서 느낀 것들이 몇 가지 있다.</p>
<p>대학까지 간 사람의 학벌은 <code>학습 능력 x 성실함</code> 에 <strong>대체로</strong> 비례한다. 그래서 의미가 있는 것 같다. 나도 대학교 덕분에 사람들 큰 걱정 없이 편하게 만날 수 있었다. 근데 <strong>대체로</strong>가 함정인데, 내가 학교를 다니던 시절 기준으론 성대 정도의 학교도 쉽게 들어올 방법이 꽤나 있었고, 그런 경우 저 곱셈식이 어그러져서인지 대체로 문제가 살짝 있었다.</p>
<p>지금 생각해보면 성대의 특성일 수도 있다. 성대생들은 대체로 저 곱셈식에서 성실함의 비중이 꽤 되는 사람들이기 때문이다. 제대로 노력을 해 본 적 없는 사람들은 자기의 주제를 전혀 모르는데, 내 친구들 중엔 그런 사람이 거의 없었다.</p>
]]></content:encoded></item><item><title><![CDATA[인간 지능에 대한 메모장]]></title><description><![CDATA[최종 업데이트: 2026/03/15


지능의 유전

현재 인류 기준으로, 고지능자는 고지능 유전자가 많이 겹친 사람이다.

지능의 유전엔 X 염색체가 매우 중요한 역할을 한다. 그리고 이게 남자와 여자의 지능 분포 차이를 만든다. 극상위권에 여자가 거의 없는 이유가 이것이다.

고지능 X 염색체가 여자한테서 발현되려면 2개가 있어야 한다. 이는 인간의 생]]></description><link>https://kdy1.dev/human-intelligence</link><guid isPermaLink="true">https://kdy1.dev/human-intelligence</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sun, 15 Mar 2026 02:15:08 GMT</pubDate><content:encoded><![CDATA[<ul>
<li>최종 업데이트: 2026/03/15</li>
</ul>
<hr />
<h2>지능의 유전</h2>
<ul>
<li><p>현재 인류 기준으로, 고지능자는 고지능 유전자가 많이 겹친 사람이다.</p>
</li>
<li><p>지능의 유전엔 X 염색체가 매우 중요한 역할을 한다. 그리고 이게 남자와 여자의 지능 <strong>분포</strong> 차이를 만든다. 극상위권에 여자가 거의 없는 이유가 이것이다.</p>
<ul>
<li><p>고지능 X 염색체가 여자한테서 발현되려면 2개가 있어야 한다. 이는 인간의 생물학적 특성인데, 여자는 X 성염색체가 2개이고 둘 중 하나는 세포군 단위 무작위로 비활성화된다. 이를 바소체 불활성화 또는 바소체 라이언화라고 부르는데, 발현 기댓값은 두 X 염색체의 평균이다.</p>
</li>
<li><p>극상위권에 여자가 적은 것은 이 고지능 X 염색체가 매우 희귀하기 때문이다. 한 사람이 2개나 가지기가 쉽지 않다.</p>
</li>
</ul>
</li>
</ul>
<h2>환경 vs 유전</h2>
<ul>
<li>같은 지능을 타고나도 훈련된 사람이 머리를 더 잘 쓴다. 간단한 예시로 수학 문제 푸는 것이 있다.</li>
</ul>
<h3>P.S.</h3>
<p>개인적으로는 환경 vs 유전 자체가 어불성설이라고 본다. <strong>지능</strong>이라는 것은 근본적으로, 진화라는 느린 과정 없이 런타임에 <strong>환경에 맞춰서 행동을 수정</strong>하겠다는 유전자의 전략이기 때문이다.</p>
<h2>지능의 종류</h2>
<ul>
<li>지능은 단일 수치가 아니다.</li>
</ul>
<h3>메타인지</h3>
<ul>
<li><p>안다고 생각했는데 시험을 보려고 하니까 제대로 아는 것이 아니었다하는 경험이 적을수록 메타인지가 발달한 것이다. 메타인지가 정말 잘 되는 사람이라면 저런 일이 단 한 번도 없을 것이다.</p>
</li>
<li><p>자기가 메타인지가 잘 된다고 착각하는 사람이 많은데, 메타인지가 잘 발달한 사람이라면 공부에선 어지간하면 극상위다. (최상위 x). 극상위가 아니었다면 착각일 확률이 높다. 시험 보기 전에 자기가 뭘 모르는지 아는 사람들은 그것을 공부하면 되기 때문에 공부를 못하기가 쉽지 않다.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Agentic Coding tips 2]]></title><description><![CDATA[This is a translation of https://kdy1.dev/2026-1-31-ai-coding-tips-kr

I recently gave a short presentation about how I use AI. The first part of the slides overlaps with a previous blog post. In this article, I’ll focus on topics that weren’t covere...]]></description><link>https://kdy1.dev/2026-1-31-ai-coding-tips-en</link><guid isPermaLink="true">https://kdy1.dev/2026-1-31-ai-coding-tips-en</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Fri, 30 Jan 2026 23:32:27 GMT</pubDate><content:encoded><![CDATA[<p>This is a translation of <a target="_blank" href="https://kdy1.dev/2026-1-31-ai-coding-tips-kr">https://kdy1.dev/2026-1-31-ai-coding-tips-kr</a></p>
<hr />
<p>I recently gave a short presentation about how I use AI. The first part of the slides overlaps with a <a target="_blank" href="https://kdy1.dev/2026-1-5-ai-coding-agent-tips">previous blog post</a>. In this article, I’ll focus on topics that weren’t covered in that post.</p>
<h2 id="heading-error-messages-and-logging">Error Messages and Logging</h2>
<h2 id="heading-using-concrete-types-and-schemas">Using Concrete Types and Schemas</h2>
<p>The <code>any</code> type is dangerous even for humans—but it’s even more dangerous for AI.</p>
<p>The same applies to things like:</p>
<ul>
<li><p>Unconstrained parsing such as <code>JSON.parse</code></p>
</li>
<li><p>Loose interfaces</p>
</li>
<li><p>Implicit or undocumented data structures</p>
</li>
</ul>
<p>These patterns force AI to make <strong>too many assumptions</strong>.</p>
<p>The real problem is that once an assumption is wrong, <em>all subsequent reasoning can spiral out of control</em>.</p>
<p>So I try to follow these principles as much as possible:</p>
<ul>
<li><p>Use the most concrete types possible instead of <code>any</code></p>
</li>
<li><p>Prefer schema-based parsers over simple parsing<br />  (e.g., Zod or Yup instead of <code>JSON.parse</code>)</p>
</li>
</ul>
<p>With this approach, even if the AI makes assumptions:</p>
<ul>
<li><p>The probability of those assumptions being wrong is lower</p>
</li>
<li><p>When they <em>are</em> wrong, the system fails fast</p>
</li>
</ul>
<p>In other words, this <strong>prevents AI from carrying incorrect reasoning all the way to the end</strong>.</p>
<h2 id="heading-leveraging-github-actions">Leveraging GitHub Actions</h2>
<p>If you look closely, GitHub Actions has some surprisingly strong properties:</p>
<ul>
<li><p>Completely isolated environments</p>
</li>
<li><p>Easy to configure</p>
</li>
<li><p>A large collection of well-prepared examples</p>
</li>
</ul>
<p>Instead of using it only for CI, I started treating it as a <strong>development virtual machine</strong>.</p>
<p>The same idea applies to AI.</p>
<blockquote>
<p>“Whatever a developer can do locally,<br />AI should be able to do in exactly the same way.”</p>
</blockquote>
<h3 id="heading-setting-up-a-development-environment-for-claude-code">Setting Up a Development Environment for Claude Code</h3>
<ul>
<li>Actual code: <a target="_blank" href="https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude.yml">https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude.yml</a></li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">issue_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">pull_request_review_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">issues:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>, <span class="hljs-string">assigned</span>]
  <span class="hljs-attr">pull_request_review:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">submitted</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">claude:</span>
    <span class="hljs-attr">if:</span> <span class="hljs-string">|
      (github.event_name == 'issue_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' &amp;&amp; contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' &amp;&amp; (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
</span>    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">pull-requests:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">issues:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">actions:</span> <span class="hljs-string">read</span> <span class="hljs-comment"># Required for Claude to read CI results on PRs</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">1</span>

      <span class="hljs-comment"># Setup pnpm</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">pnpm</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">pnpm/action-setup@v4.2.0</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Tauri</span> <span class="hljs-string">dependencies</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
            sudo apt-get update
            sudo apt-get install -y \
              libwebkit2gtk-4.1-dev \
              libappindicator3-dev \
              librsvg2-dev \
              patchelf
</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Rust</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">dtolnay/rust-toolchain@stable</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">claude</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anthropics/claude-code-action@v1</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">claude_code_oauth_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.CLAUDE_CODE_OAUTH_TOKEN</span> <span class="hljs-string">}}</span>

          <span class="hljs-comment"># This is an optional setting that allows Claude to read CI results on PRs</span>
          <span class="hljs-attr">additional_permissions:</span> <span class="hljs-string">|
            actions: read
</span>
          <span class="hljs-attr">claude_args:</span> <span class="hljs-string">|
            --allowed-tools Bash,WebFetch,WebSearch,Skill
            --model opus</span>
</code></pre>
<p>With GitHub Actions, you can set things up so that:</p>
<ul>
<li><p>Package managers are installed</p>
</li>
<li><p>Build commands are executed (<code>pnpm build</code>, <code>cargo build</code>, etc.)</p>
</li>
<li><p>Tests are run</p>
</li>
</ul>
<p>Once configured this way, Claude Code effectively operates in an environment that’s <strong>almost identical to a local development setup</strong>.</p>
<p>When the environment is this complete, the quality of AI output improves dramatically:</p>
<ul>
<li><p>It stops guessing</p>
</li>
<li><p>It reasons based on actual execution results</p>
</li>
<li><p>It produces “code that actually runs,” not just “code that should work in theory”</p>
</li>
</ul>
<h3 id="heading-managing-clean-commit-messages-with-ai">Managing Clean Commit Messages with AI</h3>
<p><img src="https://cdn.gamma.app/369hvd746fpmyb6/9780314e609f49c496cb045817adfa33/original/seukeurinsyas-2026-01-30-ohu-5.29.37.png" alt="screenshot" /></p>
<h3 id="heading-preventing-pr-description-spam">Preventing PR Description Spam</h3>
<ul>
<li>Actual code: <a target="_blank" href="https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude-code-review.yml#L34-L55">https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude-code-review.yml#L34-L55</a></li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span> <span class="hljs-string">Review</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">pull_request:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>, <span class="hljs-string">synchronize</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">claude-review:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">pull-requests:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">issues:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">1</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Dismiss</span> <span class="hljs-string">old</span> <span class="hljs-string">Claude</span> <span class="hljs-string">bot</span> <span class="hljs-string">comments</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-attr">GH_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          REPO="${{ github.repository }}"
          PR_NUMBER="${{ github.event.pull_request.number }}"
</span>
          <span class="hljs-string">gh</span> <span class="hljs-string">api</span> <span class="hljs-string">"repos/$REPO/issues/$PR_NUMBER/comments"</span> <span class="hljs-string">--jq</span> <span class="hljs-string">'.[] | select(.user.login == "claude[bot]") | .node_id'</span> <span class="hljs-string">|</span> <span class="hljs-string">while</span> <span class="hljs-string">read</span> <span class="hljs-string">-r</span> <span class="hljs-string">comment_node_id;</span> <span class="hljs-string">do</span>
            <span class="hljs-string">if</span> [ <span class="hljs-string">-n</span> <span class="hljs-string">"$comment_node_id"</span> ]<span class="hljs-string">;</span> <span class="hljs-string">then</span>
              <span class="hljs-string">gh</span> <span class="hljs-string">api</span> <span class="hljs-string">graphql</span> <span class="hljs-string">-f</span> <span class="hljs-string">query='</span>
                <span class="hljs-string">mutation($id:</span> <span class="hljs-string">ID!)</span> {
                  <span class="hljs-string">minimizeComment(input:</span> {<span class="hljs-attr">subjectId:</span> <span class="hljs-string">$id</span>, <span class="hljs-attr">classifier:</span> <span class="hljs-string">OUTDATED</span>}<span class="hljs-string">)</span> {
                    <span class="hljs-string">minimizedComment</span> {
                      <span class="hljs-string">isMinimized</span>
                    }
                  }
                }<span class="hljs-string">' -f id="$comment_node_id"
            fi
          done

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: $<span class="hljs-template-variable">{{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}</span>
          allowed_bots: '</span><span class="hljs-string">*'</span>
          <span class="hljs-attr">prompt:</span> <span class="hljs-string">|
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}
</span>
            <span class="hljs-attr">Please review this pull request and provide feedback on:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Code</span> <span class="hljs-string">quality</span> <span class="hljs-string">and</span> <span class="hljs-string">best</span> <span class="hljs-string">practices</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Potential</span> <span class="hljs-string">bugs</span> <span class="hljs-string">or</span> <span class="hljs-string">issues</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Performance</span> <span class="hljs-string">considerations</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Security</span> <span class="hljs-string">concerns</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Test</span> <span class="hljs-string">coverage</span>

            <span class="hljs-string">Use</span> <span class="hljs-string">the</span> <span class="hljs-string">repository's</span> <span class="hljs-string">CLAUDE.md</span> <span class="hljs-string">for</span> <span class="hljs-string">guidance</span> <span class="hljs-string">on</span> <span class="hljs-string">style</span> <span class="hljs-string">and</span> <span class="hljs-string">conventions.</span> <span class="hljs-string">Be</span> <span class="hljs-string">constructive</span> <span class="hljs-string">and</span> <span class="hljs-string">helpful</span> <span class="hljs-string">in</span> <span class="hljs-string">your</span> <span class="hljs-string">feedback.</span>

            <span class="hljs-string">Use</span> <span class="hljs-string">`gh</span> <span class="hljs-string">pr</span> <span class="hljs-string">comment`</span> <span class="hljs-string">with</span> <span class="hljs-string">your</span> <span class="hljs-string">Bash</span> <span class="hljs-string">tool</span> <span class="hljs-string">to</span> <span class="hljs-string">leave</span> <span class="hljs-string">your</span> <span class="hljs-string">review</span> <span class="hljs-string">as</span> <span class="hljs-string">a</span> <span class="hljs-string">comment</span> <span class="hljs-string">on</span> <span class="hljs-string">the</span> <span class="hljs-string">PR.</span>

          <span class="hljs-attr">claude_args:</span> <span class="hljs-string">'--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'</span>
</code></pre>
<p>There’s one bug in the Claude Code GitHub review action: <strong>it leaves too many review comments</strong>.</p>
<p>This can easily result in PRs being flooded with AI-generated comments.</p>
<h2 id="heading-how-to-use-ai-reviews-effectively">How to Use AI Reviews Effectively</h2>
<h3 id="heading-core-assumptions">Core Assumptions</h3>
<p>Let’s be explicit about the premises:</p>
<ul>
<li><p>Human reviews are slow</p>
</li>
<li><p>Human reviews are expensive</p>
</li>
</ul>
<p>Therefore, the goal is to <strong>minimize human involvement</strong>.</p>
<p>The strategy I chose is:</p>
<ol>
<li><p>Run AI reviews and CI first</p>
</li>
<li><p>Humans do not intervene until AI gives an OK</p>
</li>
<li><p>Only when tests and automated reviews pass</p>
</li>
<li><p>A human performs the final review</p>
</li>
</ol>
<p>In short:</p>
<blockquote>
<p>Humans act only as the “final approver.”</p>
</blockquote>
<h3 id="heading-1-using-a-github-app">1. Using a GitHub App</h3>
<p>By integrating AI reviews as a GitHub App, reviews start automatically as soon as a PR is opened.</p>
<p>At this stage, AI filters out:</p>
<ul>
<li><p>Code style issues</p>
</li>
<li><p>Obvious bugs</p>
</li>
<li><p>Structural problems</p>
</li>
</ul>
<h3 id="heading-2-applying-changes-via-github-actions">2. Applying Changes via GitHub Actions</h3>
<p><img src="https://cdn.gamma.app/369hvd746fpmyb6/9151ee873c544e18a87b6143de64214c/original/image.png" alt="screenshot" /></p>
<p>Using tools like the Claude Code GitHub Action makes parallel processing much easier. Checking out code locally should be reserved for situations where human, local testing is truly required.</p>
<h3 id="heading-3-using-ci-as-a-gatekeeper">3. Using CI as a Gatekeeper</h3>
<p><img src="https://cdn.gamma.app/369hvd746fpmyb6/5afe35a1a3714b81976456d41f3bbdcb/original/seukeurinsyas-2026-01-30-ohu-5.33.30.png" alt="screenshot" /></p>
<p>The key is to treat CI not just as a testing tool, but as:</p>
<blockquote>
<p><strong>A barrier between AI and humans</strong></p>
</blockquote>
<p>If AI-generated changes can’t pass CI, they never reach human reviewers. That alone significantly reduces review costs.</p>
<hr />
<h2 id="heading-qampa">Q&amp;A</h2>
<h3 id="heading-why-mcp-is-unnecessary-for-this-use-case">Why MCP Is Unnecessary for This Use Case</h3>
<p>Imagine there is a CLI that provides the exact same capabilities as a specific MCP server. Anything you can do through MCP could also be done through that CLI. This is why Vercel chose to improve its CLI instead of building an MCP server.</p>
]]></content:encoded></item><item><title><![CDATA[Ai 코딩 팁 2 (한국어)]]></title><description><![CDATA[발표 자료: https://gamma.app/docs/AI--2a52e7tk3eb1ch1

AI 활용법 관련해서 간단하게 발표를 했다. 발표 자료 앞쪽은 전에 블로그에 올린 글이랑 같은 내용이다. 이 글에서는 기존 글에서 다루지 않은 내용들을 다루겠다.
에러 메시지 및 로깅
구체적 타입 및 스키마 활용
any 타입은 사람에게도 위험하지만, AI에게는 더 위험하다.
마찬가지로,

JSON.parse처럼 아무 제약 없는 파싱

느슨한 인터페이스

...]]></description><link>https://kdy1.dev/2026-1-31-ai-coding-tips-kr</link><guid isPermaLink="true">https://kdy1.dev/2026-1-31-ai-coding-tips-kr</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Fri, 30 Jan 2026 23:31:14 GMT</pubDate><content:encoded><![CDATA[<ul>
<li>발표 자료: <a target="_blank" href="https://gamma.app/docs/AI--2a52e7tk3eb1ch1">https://gamma.app/docs/AI--2a52e7tk3eb1ch1</a></li>
</ul>
<p>AI 활용법 관련해서 간단하게 발표를 했다. 발표 자료 앞쪽은 <a target="_blank" href="https://kdy1.dev/2026-1-5-ai-coding-agent-tips">전에 블로그에 올린 글</a>이랑 같은 내용이다. 이 글에서는 기존 글에서 다루지 않은 내용들을 다루겠다.</p>
<h2 id="heading-7jeq65siouploylnoyngcdrsi8g66gc6rmf">에러 메시지 및 로깅</h2>
<h2 id="heading-6rws7lk07kcbio2dgoyehsdrsi8g7iqk7ykk66eiio2znoyaqq">구체적 타입 및 스키마 활용</h2>
<p><code>any</code> 타입은 사람에게도 위험하지만, AI에게는 더 위험하다.</p>
<p>마찬가지로,</p>
<ul>
<li><p><code>JSON.parse</code>처럼 아무 제약 없는 파싱</p>
</li>
<li><p>느슨한 인터페이스</p>
</li>
<li><p>암묵적인 데이터 구조</p>
</li>
</ul>
<p>이런 것들은 AI가 <strong>너무 많은 가정을 하게 만든다</strong>.</p>
<p>문제는 그 가정이 틀리면, 이후의 모든 판단이 연쇄적으로 꼬인다는 점이다.</p>
<p>그래서 가능한 한 다음을 지향한다.</p>
<ul>
<li><p><code>any</code> 타입 대신 최대한 구체적인 타입 사용</p>
</li>
<li><p>단순 파싱 대신 스키마 기반 파서 사용<br />  (예: <code>JSON.parse</code> 대신 Zod, Yup 같은 라이브러리)</p>
</li>
</ul>
<p>이렇게 하면 AI가 가정을 하더라도,</p>
<ul>
<li><p>그 가정이 틀릴 확률이 줄어들고</p>
</li>
<li><p>틀렸을 경우 즉시 실패하도록 만들 수 있다</p>
</li>
</ul>
<p>즉, <strong>AI가 잘못된 추론을 끝까지 끌고 가는 상황을 예방</strong>할 수 있다.</p>
<h2 id="heading-github-actions">GitHub Actions 활용</h2>
<p>GitHub Actions를 잘 보면 꽤 괜찮은 특징을 갖고 있다.</p>
<ul>
<li><p>완전히 격리된 환경</p>
</li>
<li><p>구성하기 쉬움</p>
</li>
<li><p>이미 잘 구성된 예제가 많음</p>
</li>
</ul>
<p>이걸 단순히 CI 용도로만 쓰지 않고,<br /><strong>개발용 가상 머신</strong>처럼 사용하는 접근을 했다.</p>
<p>AI에게도 마찬가지다.</p>
<blockquote>
<p>“로컬에서 개발자가 할 수 있는 걸<br />AI도 똑같이 할 수 있게 만들어준다”</p>
</blockquote>
<p>라는 관점이다.</p>
<h3 id="heading-claude-code">Claude Code를 위한 개발 환경 구성</h3>
<ul>
<li>실제 코드: <a target="_blank" href="https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude.yml">https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude.yml</a></li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">issue_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">pull_request_review_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">issues:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>, <span class="hljs-string">assigned</span>]
  <span class="hljs-attr">pull_request_review:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">submitted</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">claude:</span>
    <span class="hljs-attr">if:</span> <span class="hljs-string">|
      (github.event_name == 'issue_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' &amp;&amp; contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' &amp;&amp; (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
</span>    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">pull-requests:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">issues:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">actions:</span> <span class="hljs-string">read</span> <span class="hljs-comment"># Required for Claude to read CI results on PRs</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">1</span>

      <span class="hljs-comment"># Setup pnpm </span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">pnpm</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">pnpm/action-setup@v4.2.0</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Tauri</span> <span class="hljs-string">dependencies</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
            sudo apt-get update
            sudo apt-get install -y \
              libwebkit2gtk-4.1-dev \
              libappindicator3-dev \
              librsvg2-dev \
              patchelf
</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Rust</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">dtolnay/rust-toolchain@stable</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">claude</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anthropics/claude-code-action@v1</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">claude_code_oauth_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.CLAUDE_CODE_OAUTH_TOKEN</span> <span class="hljs-string">}}</span>

          <span class="hljs-comment"># This is an optional setting that allows Claude to read CI results on PRs</span>
          <span class="hljs-attr">additional_permissions:</span> <span class="hljs-string">|
            actions: read
</span>
          <span class="hljs-attr">claude_args:</span> <span class="hljs-string">|
            --allowed-tools Bash,WebFetch,WebSearch,Skill
            --model opus</span>
</code></pre>
<p>GitHub Actions에서:</p>
<ul>
<li><p>패키지 매니저 설치</p>
</li>
<li><p>빌드 명령 실행 (<code>pnpm build</code>, <code>cargo build</code> 등)</p>
</li>
<li><p>테스트 실행</p>
</li>
</ul>
<p>까지 모두 가능하게 구성해두면,<br />Claude Code는 사실상 <strong>로컬 개발 환경과 거의 동일한 조건</strong>에서 동작한다.</p>
<p>이렇게 환경이 갖춰져 있으면 AI의 작업 품질이 눈에 띄게 좋아진다.</p>
<ul>
<li><p>추측으로 답하지 않고</p>
</li>
<li><p>실제 실행 결과를 기반으로 판단하고</p>
</li>
<li><p>“이론상 맞는 코드” 대신 “실제로 도는 코드”를 만든다</p>
</li>
</ul>
<h3 id="heading-ai">AI로 커밋 메시지 예쁘게 관리하기</h3>
<p><img src="https://cdn.gamma.app/369hvd746fpmyb6/9780314e609f49c496cb045817adfa33/original/seukeurinsyas-2026-01-30-ohu-5.29.37.png" alt /></p>
<h3 id="heading-pr">PR 본문 스팸 방지</h3>
<ul>
<li>실제 코드: <a target="_blank" href="https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude-code-review.yml#L34-L55">https://github.com/delinoio/delidev/blob/abed0d02fd30524bfb2f77f7227bf9560092e949/.github/workflows/claude-code-review.yml#L34-L55</a></li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span> <span class="hljs-string">Review</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">pull_request:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>, <span class="hljs-string">synchronize</span>]
    <span class="hljs-comment"># Optional: Only run on specific file changes</span>
    <span class="hljs-comment"># paths:</span>
    <span class="hljs-comment">#   - "src/**/*.ts"</span>
    <span class="hljs-comment">#   - "src/**/*.tsx"</span>
    <span class="hljs-comment">#   - "src/**/*.js"</span>
    <span class="hljs-comment">#   - "src/**/*.jsx"</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">claude-review:</span>
    <span class="hljs-comment"># Optional: Filter by PR author</span>
    <span class="hljs-comment"># if: |</span>
    <span class="hljs-comment">#   github.event.pull_request.user.login == 'external-contributor' ||</span>
    <span class="hljs-comment">#   github.event.pull_request.user.login == 'new-developer' ||</span>
    <span class="hljs-comment">#   github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'</span>

    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">pull-requests:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">issues:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">1</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Dismiss</span> <span class="hljs-string">old</span> <span class="hljs-string">Claude</span> <span class="hljs-string">bot</span> <span class="hljs-string">comments</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-attr">GH_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          # Get PR comments from claude[bot] and hide them as outdated
          REPO="${{ github.repository }}"
          PR_NUMBER="${{ github.event.pull_request.number }}"
</span>
          <span class="hljs-comment"># Get issue comments (gh pr comment creates issue comments, not review comments)</span>
          <span class="hljs-string">gh</span> <span class="hljs-string">api</span> <span class="hljs-string">"repos/$REPO/issues/$PR_NUMBER/comments"</span> <span class="hljs-string">--jq</span> <span class="hljs-string">'.[] | select(.user.login == "claude[bot]") | .node_id'</span> <span class="hljs-string">|</span> <span class="hljs-string">while</span> <span class="hljs-string">read</span> <span class="hljs-string">-r</span> <span class="hljs-string">comment_node_id;</span> <span class="hljs-string">do</span>
            <span class="hljs-string">if</span> [ <span class="hljs-string">-n</span> <span class="hljs-string">"$comment_node_id"</span> ]<span class="hljs-string">;</span> <span class="hljs-string">then</span>
              <span class="hljs-string">echo</span> <span class="hljs-string">"Hiding review comment: $comment_node_id"</span>
              <span class="hljs-string">gh</span> <span class="hljs-string">api</span> <span class="hljs-string">graphql</span> <span class="hljs-string">-f</span> <span class="hljs-string">query='</span>
                <span class="hljs-string">mutation($id:</span> <span class="hljs-string">ID!)</span> {
                  <span class="hljs-string">minimizeComment(input:</span> {<span class="hljs-attr">subjectId:</span> <span class="hljs-string">$id</span>, <span class="hljs-attr">classifier:</span> <span class="hljs-string">OUTDATED</span>}<span class="hljs-string">)</span> {
                    <span class="hljs-string">minimizedComment</span> {
                      <span class="hljs-string">isMinimized</span>
                    }
                  }
                }<span class="hljs-string">' -f id="$comment_node_id"
            fi
          done

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: $<span class="hljs-template-variable">{{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}</span>
          allowed_bots: '</span><span class="hljs-string">*'</span>
          <span class="hljs-attr">prompt:</span> <span class="hljs-string">|
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}
</span>
            <span class="hljs-attr">Please review this pull request and provide feedback on:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Code</span> <span class="hljs-string">quality</span> <span class="hljs-string">and</span> <span class="hljs-string">best</span> <span class="hljs-string">practices</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Potential</span> <span class="hljs-string">bugs</span> <span class="hljs-string">or</span> <span class="hljs-string">issues</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Performance</span> <span class="hljs-string">considerations</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Security</span> <span class="hljs-string">concerns</span>
            <span class="hljs-bullet">-</span> <span class="hljs-string">Test</span> <span class="hljs-string">coverage</span>

            <span class="hljs-string">Use</span> <span class="hljs-string">the</span> <span class="hljs-string">repository's</span> <span class="hljs-string">CLAUDE.md</span> <span class="hljs-string">for</span> <span class="hljs-string">guidance</span> <span class="hljs-string">on</span> <span class="hljs-string">style</span> <span class="hljs-string">and</span> <span class="hljs-string">conventions.</span> <span class="hljs-string">Be</span> <span class="hljs-string">constructive</span> <span class="hljs-string">and</span> <span class="hljs-string">helpful</span> <span class="hljs-string">in</span> <span class="hljs-string">your</span> <span class="hljs-string">feedback.</span>

            <span class="hljs-string">Use</span> <span class="hljs-string">`gh</span> <span class="hljs-string">pr</span> <span class="hljs-string">comment`</span> <span class="hljs-string">with</span> <span class="hljs-string">your</span> <span class="hljs-string">Bash</span> <span class="hljs-string">tool</span> <span class="hljs-string">to</span> <span class="hljs-string">leave</span> <span class="hljs-string">your</span> <span class="hljs-string">review</span> <span class="hljs-string">as</span> <span class="hljs-string">a</span> <span class="hljs-string">comment</span> <span class="hljs-string">on</span> <span class="hljs-string">the</span> <span class="hljs-string">PR.</span>

          <span class="hljs-comment"># See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md</span>
          <span class="hljs-comment"># or https://code.claude.com/docs/en/cli-reference for available options</span>
          <span class="hljs-attr">claude_args:</span> <span class="hljs-string">'--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'</span>
</code></pre>
<p>Claude Code GitHub 리뷰 액션에는 버그가 하나 있다. 리뷰 코멘트를 <strong>너무 많이 남긴다</strong>.</p>
<p>이 때문에 PR이 리뷰 댓글로 도배되는 문제가 생긴다.</p>
<h2 id="heading-ai-1">AI 리뷰 활용법</h2>
<h3 id="heading-6riw67o4ioygkeq3va">기본 접근</h3>
<p>전제부터 분명히 하자.</p>
<ul>
<li><p>인간 리뷰는 느리다</p>
</li>
<li><p>인간 리뷰는 비싸다</p>
</li>
</ul>
<p>그래서 <strong>인간 리뷰를 최소화해야 한다</strong>.</p>
<p>이를 위해 선택한 전략은 다음과 같다.</p>
<ol>
<li><p>AI 리뷰 + CI를 먼저 통과시킨다</p>
</li>
<li><p>AI가 OK를 내릴 때까지는 인간이 개입하지 않는다</p>
</li>
<li><p>테스트와 자동 리뷰가 모두 통과된 경우에만</p>
</li>
<li><p>사람이 최종 리뷰를 한다</p>
</li>
</ol>
<p>즉,</p>
<blockquote>
<p>인간은 “최종 승인자” 역할만 맡는다</p>
</blockquote>
<ol>
<li><h3 id="heading-github">GitHub 앱 활용</h3>
</li>
</ol>
<p>AI 리뷰를 GitHub 앱 형태로 붙이면, PR 생성과 동시에 자동 리뷰가 시작된다.</p>
<p>이 단계에서는:</p>
<ul>
<li><p>코드 스타일</p>
</li>
<li><p>명백한 버그</p>
</li>
<li><p>구조적인 문제</p>
</li>
</ul>
<p>같은 것들을 AI가 먼저 걸러낸다.</p>
<ol start="2">
<li><h3 id="heading-github-actions-1">GitHub Actions를 사용해서 반영</h3>
<p> <img src="https://cdn.gamma.app/369hvd746fpmyb6/9151ee873c544e18a87b6143de64214c/original/image.png" alt /></p>
<p> 스크린샷과 같이 Claude Code GitHub Action등을 사용해서 반영해야 병렬 처리가 쉽다. 로컬에 체크아웃하는 것은 사람의 테스팅처럼 로컬에서 해야만 하는 상황에만 하는 것을 추천한다.</p>
</li>
<li><h3 id="heading-ci">CI 활용</h3>
</li>
</ol>
<p><img src="https://cdn.gamma.app/369hvd746fpmyb6/5afe35a1a3714b81976456d41f3bbdcb/original/seukeurinsyas-2026-01-30-ohu-5.33.30.png" alt /></p>
<p>중요한 건 CI를 단순한 테스트 도구가 아니라,</p>
<blockquote>
<p><strong>AI와 인간 사이의 방파제</strong></p>
</blockquote>
<p>로 사용하는 것이다. AI가 통과시키지 못한 변경사항은, 인간에게 도달하지 않게 만드는 것만으로도 리뷰 비용은 크게 줄어든다.</p>
<hr />
<h2 id="heading-qampa">Q&amp;A</h2>
<h3 id="heading-mcp">MCP가 필요없는 스펙인 이유</h3>
<p>특정 MCP 서버랑 똑같은 기능을 가진 CLI가 있다고 생각해보자. MCP를 통해서 수행할 수 있는 모든 건 CLI를 통해서도 수행할 수 있을 것이다. Vercel이 MCP를 만들지 않고 CLI 명령어를 개선한 것은 그래서이다.</p>
]]></content:encoded></item><item><title><![CDATA[Tips for AI coding agents]]></title><description><![CDATA[I’ve been using AI coding agents for a while, and I’d like to share my findings. The findings are mainly about Claude Code, but may apply to all coding agents, like opencode, if there’s no note about it.  

Intuitive API is a must.
Everything should ...]]></description><link>https://kdy1.dev/2026-1-5-ai-coding-agent-tips</link><guid isPermaLink="true">https://kdy1.dev/2026-1-5-ai-coding-agent-tips</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Mon, 05 Jan 2026 06:28:02 GMT</pubDate><content:encoded><![CDATA[<p>I’ve been using AI coding agents for a while, and I’d like to share my findings. The findings are mainly about Claude Code, but may apply to all coding agents, like opencode, if there’s no note about it.  </p>
<hr />
<h3 id="heading-intuitive-api-is-a-must">Intuitive API is a must.</h3>
<p>Everything should work intuitively, based on the <strong>name</strong>. AI tends to avoid digging into the lower layer unless you explicitly instruct it to fix it. For example, if <code>enabled: false</code> does not work in the code below, AI will fail to fix it most of the time because it <em>assumes</em> that the option works as expected.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767580108213/41e090a1-8546-4311-abec-666c94f6c4e3.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-subagents-may-reduce-context-window-usage">Subagents may reduce context window usage.</h3>
<blockquote>
<p>Use subagents proactively.</p>
</blockquote>
<p>You can utilize subagents to reduce the usage of the <strong>main</strong> context window. The only thing you need to do is saying <code>Use subagents proactively</code> in the prompt. It’s useful when you need to do a very large task. It makes Claude Code less intelligent for tasks that require the organic analysis of multiple clues, though.</p>
<p>Note: I didn’t define any subagents in my repository. General subagents are enough for this trick.</p>
<h3 id="heading-the-api-reference-document-reduces-the-guess-and-grep-loop">The API reference document reduces the guess-and-grep loop.</h3>
<p>If you don’t specify the name of the method you want to fix, the AI agent will guess the method/variable/module name and grep for it <strong>repeatedly</strong> until it finds the relevant code.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767582431474/95ec0a3e-f479-486b-bbbf-605cf491f911.png" alt class="image--center mx-auto" /></p>
<p>This means that if you can provide an API reference document listing all method names, the coding agent will be much more efficient. As a side note, the best thing is an RPC API specification file that lists all method names and only the RPC message name.</p>
<pre><code class="lang-plaintext">syntax = "proto3";
package delino.appcore.v1;
option go_package = "github.com/delinoio/cloud/rpc/appcore";

import "appcore/auth.proto";

service AppCore {
  rpc UpdateUserProfile(UpdateUserProfileRequest) returns (UpdateUserProfileResponse);
}
</code></pre>
<p>Mentioning this file would give the AI agent</p>
<ul>
<li><p>the name of RPC methods to grep for</p>
</li>
<li><p>the names of RPC message types to grep for</p>
</li>
</ul>
<p>so the AI agent will never need to repeatedly guess the names.</p>
<h3 id="heading-provide-the-design-document-and-ask-the-ai-agent-to-update-it">Provide the design document, and ask the AI agent to update it.</h3>
<p>The source of truth <strong>was</strong> the code. And yeah, the primary source of truth is still code. But you can’t feed the whole code into AI agents, and updating code requires lots of tokens. I’m not talking about the token cost. It’s about the context window size. That’s why we need a specification document that is <strong>up-to-date with the codebase</strong> and <strong>committed to the repository</strong>.</p>
<p>Luckily, having one is easy. You don’t need to update it manually. Instead, instruct the AI agent to read the design document before any task, and update it as required.</p>
<h3 id="heading-you-may-start-building-in-a-separate-session-after-creating-a-plan">You may start building in a separate session after creating a plan.</h3>
<ul>
<li>Applies to: Claude Code.</li>
</ul>
<p>The plan mode is great. It’s a really wonderful feature that allows you to create a comprehensive task input prompt that mentions all the relevant files. But sometimes, Claude Code runs compaction nearly immediately after approving the plan because it does not clear the context before executing the plan. If you want, you can instruct it to write the comprehensive task prompt as a Markdown file, and <code>/clear</code> the context window, and paste it there.</p>
<p>In this way, Claude Code will run with a fresh context window, reading referenced files as required. It’s useful if you've done a lot of ping-pong with the planning agent.</p>
<h3 id="heading-provide-project-structure">Provide project structure.</h3>
<p>You can provide the project structure using the instruction file (<code>CLAUDE.md</code>/<code>AGENTS.md</code>) or a custom command. Giving the project structure also reduces the number of tokens wasted to guess the project structure.</p>
<p>Personally, I prefer a monorepo, so I have commands like <code>/work-on-devbird</code> that mentions the relevant frontend/backend directory, the RPC definition, and the design documents.</p>
<h3 id="heading-mention-the-filepath-or-the-names-of-utility-functions">Mention the filepath or the names of utility functions.</h3>
<p>This is a good fit for the instruction files, like <code>CLAUDE.md</code> and <code>AGENTS.md</code>. The AI agent has limited knowledge of the project, so it may repeat the same code over and over. It isn’t good. If you instruct it to read the utility file beforehand, it will reuse the existing function.</p>
<h3 id="heading-if-you-dont-understand-something-throw-the-whole-text-to-the-plan-mode">If you don’t understand something, throw the whole text to the Plan Mode.</h3>
<p>You don’t need to understand everything, seriously. You don’t need to give it a perfect prompt. Instead, you can use plan mode to expand your thoughts within the project context. Sometimes I didn’t understand some requirements because they are specific to the project, but Claude Code's plan mode expanded them into a concrete plan prompt. You can even ask Claude Code to ask you back. You can do clarification based on the questions the Claude Code asks.</p>
]]></content:encoded></item><item><title><![CDATA[2025년 회고]]></title><description><![CDATA[들어가며
2025년은 나한테 롤러코스터 같은 한 해였다. 많은 일들이 있었고 환경의 변화도 많았다. 미국과 한국을 오갔고, 소속된 곳이 바뀌었으며, 새로운 사람들을 만났다. 지난 1년을 타임라인을 따라 정리해 본다.
커리어 변화
4월 16일: Vercel 본사 근무를 위한 Relocation
Vercel 본사 근무를 위해 미국으로 이동했다. 짧지 않은 기간 동안 현지에서 일하며, 이전과는 다른 환경과 문화 속에서 일을 하게 됐다.
6월 16일:...]]></description><link>https://kdy1.dev/2025</link><guid isPermaLink="true">https://kdy1.dev/2025</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sat, 20 Dec 2025 02:15:36 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-65ok7ja06rca66mw">들어가며</h2>
<p>2025년은 나한테 롤러코스터 같은 한 해였다. 많은 일들이 있었고 환경의 변화도 많았다. 미국과 한국을 오갔고, 소속된 곳이 바뀌었으며, 새로운 사람들을 만났다. 지난 1년을 타임라인을 따라 정리해 본다.</p>
<h2 id="heading-7luk66as7ja0iouzgo2zla">커리어 변화</h2>
<h3 id="heading-4-16-vercel-relocation">4월 16일: Vercel 본사 근무를 위한 Relocation</h3>
<p>Vercel 본사 근무를 위해 미국으로 이동했다. 짧지 않은 기간 동안 현지에서 일하며, 이전과는 다른 환경과 문화 속에서 일을 하게 됐다.</p>
<h3 id="heading-6-16">6월 16일: 귀국</h3>
<p>두 달 정도의 미국 생활을 마치고 한국으로 돌아왔다. 이 시점까지도 이후의 방향이 명확하게 정해져 있던 것은 아니었다.</p>
<h3 id="heading-7-vercel">7월: Vercel 퇴사</h3>
<p>어쩌다 보니 Vercel을 퇴사하게 됐다. 당시에는 회사가 지나치게 무례하다고 느꼈고, 더 이상 같이 일하고 싶지 않다는 감정이 컸다. 분노와 피로가 동시에 있었다. 말해봤자 무슨 소용이 있을까 싶을 정도였다.</p>
<p>시간이 조금 지난 뒤, 미국 기업 문화에 대해 미국에 거주하는 분들의 이야기를 듣고, 또 인공지능을 통해 정리해보면서 그 상황을 다시 바라보게 됐다. 미국 정서 기준으로 보면 회사 쪽이 특별히 잘못했다고 보기는 어려웠다. 한국 기준으로는 쉽게 받아들이기 힘든 방식이었지만, 억울함을 말하고 싶은 건 아니다. 그 당시의 나는 그렇게 느꼈고, 그게 전부였다.</p>
<h3 id="heading-7-delino">7월: Delino 창업</h3>
<p>나는 원래 창업이 하고 싶었다. 아이템도 여러 개 생각해두고 있었다. 마침 퇴사를 하게 되었고, 결과적으로는 잘 된 선택이었다고 생각한다. 감정과는 별개로, 방향을 바꾸기에 적절한 시점이었다.</p>
<h3 id="heading-8-9-real-prompter">8월 9일: Real Prompter 런칭</h3>
<p>Claude Code를 활용해 여러 서비스를 만들면서 한 가지를 계속 느꼈다. LLM을 제대로 활용하는 것은 생각보다 어렵다는 점이었다. 많은 사람들이 “프롬프팅은 어떻게 하느냐”고 물어봤고, 나는 반복해서 비슷한 답을 해왔다.</p>
<p>Roo Cline 등을 사용해 내가 실제로 하던 작업 방식들을 블로그와 SNS를 통해 여러 번 공유했고, 이를 반복하다 보니 서비스화하는 편이 낫겠다는 생각이 들었다. 그렇게 Real Prompter를 만들게 됐다.</p>
<h3 id="heading-10-14-autodev">10월 14일: AutoDev 런칭</h3>
<p>LLM을 잘 사용하는 것이 요령이나 감각의 문제인 것은 맞지만, 시스템적인 방식으로 근본적으로 해결할 수 있는 문제라고 생각했다. AI 덕분에 그 요령이나 감각조차 자동화가 가능한 시대라는 것이다.</p>
<p>AutoDev는 내가 이전부터 계속 이야기해오던 작업 방식을 자동화한 도구였다. 내가 강조해온 핵심은 몇 개 더 있지만, 가장 핵심적인 것은 세 가지였다.</p>
<ol>
<li><p>복잡한 작업을 적절한 단위로 쪼개는 것</p>
</li>
<li><p>여러 세션에 걸쳐 반복적으로 검증하고 피드백을 받는 구조</p>
</li>
<li><p>CI와 자동 테스트를 활용한 회귀(regression) 방지</p>
</li>
</ol>
<p>이건 새로운 아이디어라기보다는, 내가 계속 해오던 방식이었다. AutoDev는 그 방식을 도구로 옮긴 결과였다.</p>
<h3 id="heading-10-15">10월 15일: 인프런 멘토링</h3>
<p>돈을 받고 진행한 내 인생 첫번째 멘토링이라서 적기로 했다. 인프런을 통해서 진행한 것이었고, AI 활용법 및 오픈소스 관련 전략에 대해서 많은 얘기를 나누었다. 가격이 한국 기준으론 상당한 가격이었기에 감사한 마음으로 사전 질문들 및 추후 추가 질문들도 답변해드렸다.</p>
<h3 id="heading-10-23-autodev-devbird">10월 23일: AutoDev → DevBird 리브랜딩</h3>
<p>Microsoft에서 만든 AutoDev와 이름이 겹치면서 SEO가 사실상 불가능했다. 결국 DevBird로 리브랜딩했다. 제품의 방향이나 철학이 바뀐 것은 아니었다.</p>
<h3 id="heading-10-27-zack">10월 27일: Zack과 미팅</h3>
<p>Zephyr Cloud의 CEO인 Zack과 미팅을 가졌다. 네트워킹으로 분류할 수도 있었지만, 이후의 커리어와 연결되는 지점이 있어서 이 글에서는 커리어 이벤트로 남긴다.</p>
<h3 id="heading-11-1-zephyr-cloud">11월 1일: Zephyr Cloud 업무 시작</h3>
<hr />
<h2 id="heading-66eo7j2aioyxro2wiq">많은 여행</h2>
<p>이번 해엔 나답지 않게 여행을 많이 다녔다.</p>
<h3 id="heading-4-16-6-16-vercel">4월 16일 ~ 6월 16일: 미국 Vercel 근무</h3>
<p>미국에서 Vercel과 함께 일한 이 두 달은 즐거움과 떨림이 공존했던 시간이었다.<br />낯선 환경에서 일한다는 점에서 긴장도 됐지만, 좋은 친구들을 만나 덕분에 생각보다 빠르게 적응할 수 있었다. 새로운 사람들과 함께 일하며 많이 배웠다.</p>
<h3 id="heading-10">10월 초: 속초 가족 여행</h3>
<p>힐링의 시간이었다. 맛있는 음식을 함께 먹는 시간이 특히 좋았지만, 집에 두고 온 고양이가 계속 마음에 걸려서 조금 일찍 돌아와야 했던 점은 아쉬움으로 남았다.</p>
<h3 id="heading-10-1">10월 중순: 부산 여행</h3>
<p>동생이랑 부산 여행을 갔다왔다. 열심히 걸었지만 맛있는 음식을 너무 많이 먹었는지 갔다와서 재보니까 체중이 조금 늘었다. 그리고 갈 때 ITX를 탔다. 깨끗하긴한데 너무 느렸다. 그래서 올 때는 KTX 탔다.</p>
<p>해동 용궁사 같은 곳도 보고 왔고, 이재모 피자 같은 맛집도 많이 찾아다녔다.</p>
<h3 id="heading-11-16-23-for-zephyr-cloud">11월 16일 ~ 23일: 미국 출장 (for Zephyr Cloud)</h3>
<p>너무 재밌었다. 일주일간 한 customer onsite였는데 업무 시간엔 일을 엄청나게 많이 했고, 어쩌다보니 앞에 나가서 데모 발표도 했다. 그리고 업무 외 시간에는 대표분이 렌트하신 차로 같이 놀러다녔는데 이게 정말 재밌었다. 재밌는 여행을 할 수 있게 해주신 대표분께 감사드린다.</p>
<h3 id="heading-11-12">11월 말 ~ 12월 초: 일본 도쿄 여행</h3>
<p>동생이랑 일본 도쿄로 짧은 여행을 갔다왔다. 도쿄 디즈니랜드 가서 재밌게 놀았고, 미녀와 야수라는 가장 인기 많은 놀이기구에 충격을 받았다. 그래도 디즈니랜드에서 다른 건 다 재밌었어서 만족스러웠다.</p>
<p>근데 숙소 위치를 조금 잘못 잡았던 것 같다. 신주쿠 가부키초 쪽이었는데 저녁엔 무서워서 안 나갔다.</p>
<h3 id="heading-12">12월 중순: 속초 가족 여행</h3>
<p>홈캠 등의 장비들을 설치하고 가서 고양이 걱정을 덜 한 재밌는 여행이었다. 좋은 숙소에 묵고 맛있는 음식을 많이 먹은 여행이었는데, 숙소에서 일도 꽤 많이 했다.</p>
<hr />
<h2 id="heading-66eo7j2aiouepo2kuoybjo2cueqzvcdrsjztkzw">많은 네트워킹과 발표</h2>
<p>여러 자리에서 사람들을 만나며 느낀 건, 생각보다 많은 사람들이 비슷한 고민을 하고 있다는 점이었다.<br />“AI를 어떻게 잘 써야 할까?”라는 질문이 반복해서 나왔고, 나는 여전히 AI가 버블이라고 생각하지 않는다. 다만 AI를 제대로 쓰기 위해서는, 마법 같은 도구를 기대하기보다 구조와 시스템이 먼저 필요하다고 느꼈다.</p>
<h3 id="heading-1-vercel">1월 말: Vercel 최지원과 페어코딩</h3>
<p>Vercel의 최지원님과 진행한 페어코딩은 협업 자체가 굉장히 재미있었던 경험이었다.<br />미국 회사에서 일하면서 한국인 동료와 함께 코드를 짜는 시간이어서 더 편안하고 즐겁게 느껴졌다.</p>
<h3 id="heading-3-1">3월 1일: 팀 스파르타(항해) 손윤주 씨와 커피챗</h3>
<p>손윤주 씨와의 커피챗에서는 그분이 정말 성실하게 일하는 분이라는 인상을 받았다.<br />대화 중에는 내가 AI 이야기를 많이 했고, 노트북까지 꺼내 직접 데모를 보여주며 이야기를 이어갔다.</p>
<h3 id="heading-3-11-ai">3월 11일: 항해 AI 웨비나</h3>
<p>이 웨비나는 개인적으로 정말 즐거운 경험이었다.<br />평소 주변 사람들에게 “AI는 이제 무조건 써야 한다”고 이야기하고 다녔는데, 그 메시지를 웨비나라는 공식적인 자리에서 정리해 전달할 수 있어서 좋았다. AI 도구들을 소개하며 내가 계속 강조해오던 이야기를 꺼낼 수 있었던 시간이 오래 기억에 남는다.</p>
<h3 id="heading-3-27">3월 27일: 성균관대학교 강연</h3>
<p>원래는 긴장을 안 할 거라고 생각했지만, 교수님들이 지켜보고 계셔서 생각보다 긴장이 됐다.<br />그럼에도 불구하고 교수님들이 흥미롭게 들어주시고 질문까지 해주셔서 강연을 마치고 나서는 꽤 뿌듯한 기분이 들었다.</p>
<h3 id="heading-8-6">8월 6일: 오픈소스 밋업</h3>
<p>오픈소스 밋업에서는 다양한 이야기를 들을 수 있었지만, 한편으로는 아쉬운 지점도 있었다.<br />오픈소스 기여를 마치 개인의 성과나 이력서 한 줄처럼 이야기하는 분위기가 있었는데, 오픈소스는 결국 문제를 함께 해결하기 위해 모이는 공동체라는 점을 다시 생각하게 됐다.</p>
<h3 id="heading-9-16">9월 16일: 크래프톤 정글 팟캐스트</h3>
<p>이 자리에서는 Vercel에서의 경험과 실리콘밸리에서의 일하는 방식, 그리고 AI 시대에 개발자가 어떤 자세를 가져야 하는지에 대해 많이 이야기했다.<br />전하고 싶은 메시지가 많다 보니 조금 정리가 덜 된 채로 이야기를 한 점은 아쉬움으로 남았다.</p>
<h3 id="heading-9-18-marco-ippolito">9월 18일: Marco Ippolito 님의 서울 방문</h3>
<ul>
<li><a target="_blank" href="https://x.com/satanacchio/status/1968670634885500997">https://x.com/satanacchio/status/1968670634885500997</a></li>
</ul>
<p>Marco Ippolito 님과의 만남은 서로의 경험을 나누며 굉장히 유익한 시간이었다.<br />Node 컨트리뷰터분이신데 인사이트가 매우 깊었고, 개인적으로도 많은 것을 배울 수 있었다.</p>
<h3 id="heading-9-30-hoco">9월 30일: HOCO 팟캐스트</h3>
<p>크래프톤 정글 팟캐스트와 비슷한 주제를 다뤘지만, 이번에는 미리 블로그 글로 생각을 정리해 둔 상태에서 이야기를 풀어갈 수 있었다.<br />덕분에 훨씬 정돈된 흐름으로 설명할 수 있었고, 스스로도 잘했다고 느낀 자리였다.</p>
<h3 id="heading-10-24">10월 24일: 토스 프다클</h3>
<p>토스 프다클에서는 사람들이 AI를 사용하는 수준이 생각보다 크게 다르다는 걸 실감했다.<br />그 경험을 통해 내가 앞으로 무엇을 해야 할지, 또 어떤 방식으로 사람들을 도울 수 있을지 감을 잡게 됐다. 동시에 개인적으로도 많은 인사이트를 얻은 의미 있는 시간이었다.</p>
<h3 id="heading-10-30-ai-2">10월 30일: 항해 AI 웨비나 2</h3>
<hr />
<h2 id="heading-6riw7yoaioydtouypo2kua">기타 이벤트</h2>
<h3 id="heading-2">2월 중순: 수면 문제 해결</h3>
<p>내가 원래 잠을 되게 못 자는 사람이었다. 어느 날 우연히 상추차를 접하게 되었는데, 상추차를 마시니까 잠이 잘 왔다. 며칠 실험해보고 이건 진짜라는 것을 깨달았다. 그리고 지금은 상추환으로 정착했다. 상추차를 농축해서 환으로 만들어놓은 것인데, 상추차는 차의 특성상 우리거나 마시는 데에 시간이 걸리고, 물을 많이 마시다보니 아침에 자꾸 깨서 상추환이 훨씬 나았다. 상추환을 꾸준히 먹다보니 수면에 관련된 호르몬 자체가 선순환으로 들어간건지 이제는 낮 시간에도 졸리면 낮잠을 잘 수 있게 됐다. 삶의 질이 아주 높아져서 행복하다.</p>
<h3 id="heading-11">11월 초: 사촌동생 결혼식</h3>
<p>사촌동생 결혼식에 참석했다. 놀랍게도 이게 내가 가 본 첫번째 결혼식이다. 나보다 어린 나이에, 오랜 시간 함께한 연인과 결혼하는 모습을 보니까 부러웠고, 나도 원래 한명하고 오래 연애하다가 27살 쯤에 결혼하고 싶었던 사람이라서 여러 가지 생각이 들었다. 이 이벤트가 나한테 꽤나 큰 변화를 남겨서 회고록에 적는다.</p>
<h2 id="heading-66ei7lmy66mw">마치며</h2>
<p>2025년을 지나온 지금, 예전보다 자유롭고 행복하다. 내 일을 충분히 잘 해내고 있는 것 같아서 뿌듯하기도 하다. 여전히 실험 중이고, 여전히 복잡한 문제를 풀고 있지만, 지금의 상태는 나쁘지 않다고 느낀다.</p>
]]></content:encoded></item><item><title><![CDATA[Ai 시대의 개발자]]></title><description><![CDATA[오늘 발표에서 얘기할 내용들입니다.

기본 태도

적극적으로 사용해야 함. 모든 도구를 사용해볼 필요는 없지만, 좋은 평을 받는 도구는 시도해볼 것.

AI를 적극적으로 활용하는 기업 기준, 현 시점에서 이미 프론트엔드/백엔드 같은 것은 안 중요함.

모든 것을 다 알아야한다는 태도는 반드시 버릴 것. 이것은 개발 씬에서 원래도 문제임. 솔직하게 말하면 개발 소질 이슈. 애매한 중상위권의 특징임.

원리 이해 같은 경우, 난이도가 훨씬 낮지만 ...]]></description><link>https://kdy1.dev/2025-9-30-developer-in-ai-era</link><guid isPermaLink="true">https://kdy1.dev/2025-9-30-developer-in-ai-era</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Mon, 29 Sep 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<hr />
<p>오늘 발표에서 얘기할 내용들입니다.</p>
<hr />
<h2 id="heading-6riw67o4io2dnoupha">기본 태도</h2>
<ul>
<li><p>적극적으로 사용해야 함. 모든 도구를 사용해볼 필요는 없지만, 좋은 평을 받는 도구는 시도해볼 것.</p>
</li>
<li><p>AI를 적극적으로 활용하는 기업 기준, 현 시점에서 이미 프론트엔드/백엔드 같은 것은 안 중요함.</p>
</li>
<li><p>모든 것을 다 알아야한다는 태도는 반드시 버릴 것. 이것은 개발 씬에서 원래도 문제임. 솔직하게 말하면 개발 소질 이슈. 애매한 중상위권의 특징임.</p>
<ul>
<li><p>원리 이해 같은 경우, 난이도가 훨씬 낮지만 효율적인 방법은 아님.</p>
<ul>
<li>자기가 국소적 이해 기반의 코딩을 할 수 없다면 전체 설계를 이해해서라도 코딩을 해야함.</li>
</ul>
</li>
<li><p>큰 프로젝트 여러 개를 동시에 해야하는 경우 국소적 이해로 코딩하는 능력이 필수임.</p>
<ul>
<li><p>이 능력을 습득하고 싶으면 규모가 꽤 있지만 본인은 잘 모르는 오픈소스에 기여하는 것이 최고라고 생각.</p>
</li>
<li><p>오픈소스에서 이것이 특히 중요한데, 규모가 큰 프로젝트 여러 개에 각각 패치를 보내야하는 일이 생각보다 자주 있는데 물어볼 사람도 없고, 문서도 내부 구현에 대한 것은 없는 경우가 대부분인데 각 프로젝트를 제대로 이해하고 작업하려고 하면 작업 시간이 지나치게 늘어남.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="heading-67cu7j2067im7l2u65sp7j2yiousuoygncdtlbtqsrdssyu">바이브코딩의 문제 해결책</h2>
<ul>
<li><p>바이브 코딩의 단점을 막을 가장 중요한 해결책은 <strong>테스트</strong></p>
</li>
<li><p>스펙 문서는 항상 넘겨주고 적절한 수정을 요청할 것.</p>
</li>
<li><p>바이브 코딩 이후 작업에 대한 설명이 명확하게 이해가 안 간다면 관련 개념을 공부하는 것을 추천. 그 뒤에도 이해가 안 가면 컴퓨팅적 사고력의 문제.</p>
</li>
</ul>
<h2 id="heading-ai">AI 시대의 능력</h2>
<ul>
<li><p>1인 창업이 맞는 시대라고 보지만 (당연히) 자기 능력 검증은 필수.</p>
</li>
<li><p>AI 없이 처음부터 끝까지 개발하기 위한 능력은 필요치 않음.</p>
</li>
<li><p>다시 말해, <strong>코딩하는 능력</strong> 자체는 이제 의미가 없음.</p>
</li>
<li><p>하지만 AI 를 활용해서 학습하고 코딩하는 능력은 매우 중요함.</p>
<ul>
<li>바이브 코딩 이후 AI의 설명이 이해가 안 간다면 복사해서 다른 인공지능 챗봇에 붙여넣은 뒤 어떤 개념을 공부해야 이 설명을 이해할 수 있는지 물어보고 공부할 것.</li>
</ul>
</li>
</ul>
<p>이 시대의 문제 해결 능력은 2가지</p>
<ul>
<li><p>새로운 문제를 만들지 않는 것</p>
<ul>
<li>핵심은 테스트의 활용</li>
</ul>
</li>
<li><p>주어진 문제를 고치는 것</p>
<ul>
<li><p>AI를 활용해보고, 문제가 생겼을 때 AI를 활용해서 해결한 경험이 많은 것이 중요함.</p>
</li>
<li><p>어떻게 하면 해결되는지는 본인이 전부 기억하고 있어야 함.</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-vs">지능 vs 지식</h2>
<ul>
<li><p>원래 시대가 빠르게 바뀔수록 순수 지능이 중요함. 근데 지능이란 건 함수 같은 것이고 쓰던 사람이 잘 씀. 공부할 때도 머리를 많이 쓰는 방식을 사용하는 것이 좋음.</p>
<ul>
<li><p>바이브 코딩하는 방법을 책이나 강의로 배울 생각을 한다면 바이브코딩 관련 재능 중 제일 중요한 것이 없는 것. 공부 방법을 근본적으로 바꿔야 함.</p>
</li>
<li><p>강의나 책은 자기의 사고력을 덜 쓰는 방법이라서 편하지만 이 시대에 최악인 습관임.</p>
</li>
</ul>
</li>
<li><p>CS 지식 자체는 중요하지 않음. 중요한 건 컴퓨팅적 사고. 이게 처음부터 자유자재로 되는 사람이 있는데 그런 사람은 AI 적극적으로 쓴다는 전제 하에 CS 지식 따로 안 배워도 됨. 근데 이 애기는 천재에 대한 얘기가 아니고 생각보다 이것이 처음부터 되는 사람이 많음. 코테는 컴퓨팅적 사고가 안 되는 사람을 거르는 역할을 함.</p>
</li>
<li><p>코딩하는 능력 자체도 마찬가지로 코딩하는 능력이 없어도 거의 모든 개발이 가능함. 그래서 프로덕트 엔지니어라는 직군으로 바뀌는 것.</p>
</li>
<li><p>메타인지가 오히려 더 중요. 자기가 메타인지가 있는지 확인하는 방법:</p>
<ul>
<li><p>안다고 생각했는데 시험 때 생각 안 났다라는 경험이 한번이라도 있으면 메타인지가 없다고 치고 공부 계획을 짜야함.</p>
</li>
<li><p>자기가 모르는데 안다고 착각하면 해결책 없는 교착 상태가 생김. 안다고 전제하지 말 것.</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-6riw7yoaioygleuzta">기타 정보</h2>
<ul>
<li><p>실리콘밸리의 새로운 변화는 보통 1~2달 정도의 시차를 두고 한국에 들어옴.</p>
<ul>
<li>프로덕트 엔지니어 직군 / AI 네이티브 인재 채용 (카카오) 등</li>
</ul>
</li>
<li><p>코테는 허수 (컴퓨팅적 사고 안 되는 사람들) 거르기 + 면접에 드는 품 줄이기.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[내가 거리를 두고 싶은 사람들]]></title><description><![CDATA[난 이런 사람들과는 거리를 두고싶다. 공격적으로 느껴질 수도 있는 글이라 쓸지 말지 고민 조금 했는데 쓰기로 했다.


사람 급 나누기에 미친 사람들

중범죄자

음주운전 등.


자기의 조그만 이익을 위해 남들한테 큰 피해를 주는 걸 아무렇지 않게 생각하는 사람들.

예를 들어 우회전 할 때 반드시 지나가야하는 위치에 차 세워놓는 사람들.


자기 잘못은 어떻게든 합리화하는 사람들.

남들한테 피해주면서까지 돈 벌려는 사람들.

각종 망상이 ...]]></description><link>https://kdy1.dev/2025-9-29-people</link><guid isPermaLink="true">https://kdy1.dev/2025-9-29-people</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Mon, 29 Sep 2025 00:02:27 GMT</pubDate><content:encoded><![CDATA[<p>난 이런 사람들과는 거리를 두고싶다. 공격적으로 느껴질 수도 있는 글이라 쓸지 말지 고민 조금 했는데 쓰기로 했다.</p>
<hr />
<ul>
<li><p>사람 급 나누기에 미친 사람들</p>
</li>
<li><p>중범죄자</p>
<ul>
<li>음주운전 등.</li>
</ul>
</li>
<li><p>자기의 조그만 이익을 위해 남들한테 큰 피해를 주는 걸 아무렇지 않게 생각하는 사람들.</p>
<ul>
<li>예를 들어 우회전 할 때 반드시 지나가야하는 위치에 차 세워놓는 사람들.</li>
</ul>
</li>
<li><p>자기 잘못은 어떻게든 합리화하는 사람들.</p>
</li>
<li><p>남들한테 피해주면서까지 돈 벌려는 사람들.</p>
</li>
<li><p>각종 망상이 심각한 사람들.</p>
</li>
<li><p>나 이용하려는 게 너무 티나는 사람들.</p>
</li>
<li><p>자기 잘못을 이해하는 능력이 글러먹은 사람들.</p>
</li>
<li><p>윤리의식이 나랑 너무 안 맞는 사람들.</p>
</li>
<li><p>쓰레기 짓 해놓고 지가 머리 잘 썼다고 생각하는 사람들.</p>
</li>
<li><p>자신의 이익을 위해 상황을 변조하는 사람들.</p>
<ul>
<li>일부 사실만 공개하는 것은 제외.</li>
</ul>
</li>
<li><p>남의 돈으로 생색내는 사람들.</p>
</li>
</ul>
<p>이렇게 늘어놓으면 인생 피곤하게 사는 것처럼 들릴 수도 있는데 이 사람들한테 공통점이 있어서 피하는 것이 그리 어렵지는 않은 것 같다.</p>
]]></content:encoded></item><item><title><![CDATA[How to use Claude Code via GitHub]]></title><description><![CDATA[Setup
I configured Claude Code GitHub Action correctly. You should add setup steps to emulate a real development environment before anthropics/claude-code-action@beta. The setup steps depend on the repository, but I’ll provide my Claude Code Action S...]]></description><link>https://kdy1.dev/2025-8-24-claude-code-github</link><guid isPermaLink="true">https://kdy1.dev/2025-8-24-claude-code-github</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sat, 23 Aug 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-setup">Setup</h2>
<p>I configured Claude Code GitHub Action <em>correctly</em>. You should add setup steps to emulate a real development environment before <code>anthropics/claude-code-action@beta</code>. The setup steps depend on the repository, but I’ll provide my Claude Code Action Setup as a reference.</p>
<p><code>.github/workflows/claude.yml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">issue_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">pull_request_review_comment:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">created</span>]
  <span class="hljs-attr">issues:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>, <span class="hljs-string">assigned</span>]
  <span class="hljs-attr">pull_request_review:</span>
    <span class="hljs-attr">types:</span> [<span class="hljs-string">submitted</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">claude:</span>
    <span class="hljs-attr">if:</span> <span class="hljs-string">|
      (github.event_name == 'issue_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' &amp;&amp; contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' &amp;&amp; contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' &amp;&amp; (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
</span>    <span class="hljs-attr">runs-on:</span> [<span class="hljs-string">'self-hosted'</span>, <span class="hljs-string">'linux'</span>]
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">pull-requests:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">issues:</span> <span class="hljs-string">read</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">actions:</span> <span class="hljs-string">read</span> <span class="hljs-comment"># Required for Claude to read CI results on PRs</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">fetch-depth:</span> <span class="hljs-number">1</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Protoc</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">arduino/setup-protoc@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">repo-token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Node.js</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">./.github/actions/setup-node</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Configure</span> <span class="hljs-string">environment</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">pnpm</span> <span class="hljs-string">install</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Run</span> <span class="hljs-string">Claude</span> <span class="hljs-string">Code</span>
        <span class="hljs-attr">id:</span> <span class="hljs-string">claude</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">anthropics/claude-code-action@beta</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">claude_code_oauth_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.CLAUDE_CODE_OAUTH_TOKEN</span> <span class="hljs-string">}}</span>

          <span class="hljs-comment"># This is an optional setting that allows Claude to read CI results on PRs</span>
          <span class="hljs-attr">additional_permissions:</span> <span class="hljs-string">|
            actions: read
</span>
          <span class="hljs-comment"># Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)</span>
          <span class="hljs-comment"># model: "claude-opus-4-20250514"</span>

          <span class="hljs-comment"># Optional: Customize the trigger phrase (default: @claude)</span>
          <span class="hljs-comment"># trigger_phrase: "/claude"</span>

          <span class="hljs-comment"># Optional: Trigger when specific user is assigned to an issue</span>
          <span class="hljs-attr">assignee_trigger:</span> <span class="hljs-string">"claude-bot"</span>

          <span class="hljs-comment"># Optional: Allow Claude to run specific commands</span>
          <span class="hljs-attr">allowed_tools:</span> <span class="hljs-string">"Bash,WebFetch,WebSearch"</span>

          <span class="hljs-comment"># Optional: Add custom instructions for Claude to customize its behavior for your project</span>
          <span class="hljs-comment"># custom_instructions: |</span>
          <span class="hljs-comment">#   Follow our coding standards</span>
          <span class="hljs-comment">#   Ensure all new code has tests</span>
          <span class="hljs-comment">#   Use TypeScript for new files</span>

          <span class="hljs-comment"># Optional: Custom environment variables for Claude</span>
          <span class="hljs-comment"># claude_env: |</span>
          <span class="hljs-comment">#   NODE_ENV: test</span>
</code></pre>
<p>Note <code>allowed_tools: "Bash,WebFetch,WebSearch"</code>. You need it to allow Claude Code to run bash commands.</p>
<h2 id="heading-usage">Usage</h2>
<p>Mention <code>@claude</code> from issues or PRs to instruct it to resolve issues.</p>
<p>Example:</p>
<blockquote>
<p><a class="user-mention" href="https://hashnode.com/@https://github.com/claude">@claude</a> <a target="_blank" href="https://github.com/claude">Implem</a>ent comprehensive unit tests</p>
</blockquote>
<h2 id="heading-pro-tip-you-can-use-local-claude-code-to-create-a-handful-of-issues-quickly">Pro Tip: You can use local Claude Code to create a handful of issues quickly</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1755992979320/fae16172-d327-4362-b695-db63dd5f54db.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Tip: TailScale]]></title><description><![CDATA[When developing, you often need to connect to your development computer from your phone. In such cases, you need to connect to the same router or use a program like ngrok to connect to your development computer.
However, there is another method, and ...]]></description><link>https://kdy1.dev/tip-tailscale</link><guid isPermaLink="true">https://kdy1.dev/tip-tailscale</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Tue, 19 Aug 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<p>When developing, you often need to connect to your development computer from your phone. In such cases, you need to connect to the same router or use a program like <code>ngrok</code> to connect to your development computer.</p>
<p>However, there is another method, and this one is the most convenient and free. It involves using a virtual private network (VPN) service called <strong>Tailscale</strong>. After logging in and registering your device, each device is assigned an IP address.</p>
<p>After running the server on your development laptop, you can check the IP address of the device in the Tailscale app and connect to it using that IP address, as shown in the screenshot, to access the development server.</p>
<p>This is also the best option when creating a service that only you can access, as you don't need to set up complex external access settings. Install Tailscale on the specific device, deploy the service, and connect. Installing Tailscale on the server can also be done with a single line of script, making it very convenient.</p>
]]></content:encoded></item><item><title><![CDATA[Tip for reducing AI cost]]></title><description><![CDATA[If you have a personal VPS, you can reduce your AI subscription fees by deploying OpenWebUI. By connecting OpenRouter, you can use various models without a fixed subscription fee, paying only for what you use via the API. Multiple users can share acc...]]></description><link>https://kdy1.dev/2025-8-14-tip-for-reducing-ai-cost</link><guid isPermaLink="true">https://kdy1.dev/2025-8-14-tip-for-reducing-ai-cost</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Wed, 13 Aug 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<p>If you have a personal VPS, you can reduce your AI subscription fees by deploying OpenWebUI. By connecting OpenRouter, you can use various models without a fixed subscription fee, paying only for what you use via the API. Multiple users can share accounts, and in my case, I created accounts for my family members as well. Combined, my family and I paid a total of <strong>$42.44 for seven months</strong> of usage. Usage details can be viewed in the OpenRouter API Key Console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1755994282891/2a681dfd-0eb8-49c2-a541-70a877b4477a.png" alt class="image--center mx-auto" /></p>
<p>As you can see on the left side of the screenshot, chats can be organized like folders, and there are features such as setting different system prompts for each folder. For example, you can set it to only use official documents for matters related to law or taxation.</p>
<p>With LLM models, connecting OpenRouter allows you to utilize a huge number of models freely. The models shown in the screenshot are ones that I have selected and activated. Since my family also uses it, I thought it might be unclear if there were too many.</p>
<p>When you turn on the web search function in the chat feature, it searches for information and organizes it for you. When the image feature is enabled, it generates images. When numbers appear during the inference process or there is a lot to manage, it uses LLM to code, executes it, and then uses the results to provide answers.</p>
<p>Since it supports PWA, you can add it to the home screen on mobile devices or use the app installation feature in desktop Chrome to use it like a native app.</p>
]]></content:encoded></item><item><title><![CDATA[Tip for GitHub Runners Concurrency]]></title><description><![CDATA[The number of concurrent GitHub Action runners is determined by the plan of the GitHub Org to which the repository belongs, regardless of whether the repository is public. Even though GitHub Actions are unlimited and free for public repositories, the...]]></description><link>https://kdy1.dev/2025-8-12-tip-for-github-runners</link><guid isPermaLink="true">https://kdy1.dev/2025-8-12-tip-for-github-runners</guid><category><![CDATA[GitHub]]></category><category><![CDATA[GitHub Actions]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Mon, 11 Aug 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1755994052423/9cb8ef76-8aa5-419b-85c2-2861ecf0ffa8.png" alt class="image--center mx-auto" /></p>
<p>The number of concurrent GitHub Action runners is determined by the plan of the GitHub Org to which the repository belongs, regardless of whether the repository is public. Even though GitHub Actions are unlimited and free for public repositories, they are still affected. Because of this, SWC uses the Enterprise plan.</p>
<p>If you're running a large open-source project and are having issues with GitHub Actions only running 20 jobs at a time, you can upgrade your plan to Team or Enterprise.</p>
<ul>
<li>Documentation link: <a target="_blank" href="https://docs.github.com/en/actions/reference/limits#job-concurrency-limits-for-github-hosted-runners">https://docs.github.com/en/actions/reference/limits#job-concurrency-limits-for-github-hosted-runners</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How I use Claude Code]]></title><description><![CDATA[Some people asked me on X about the way I use Claude Code, so I'm writing this post. I'm too tired to write a long post, so I keep it short. I use Roo Code with Architecture mode first, with a prompt like

Service XXX is for ...
If anything is ambigu...]]></description><link>https://kdy1.dev/2025-7-7-how-i-use-claude-code</link><guid isPermaLink="true">https://kdy1.dev/2025-7-7-how-i-use-claude-code</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sun, 06 Jul 2025 15:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Some people asked me on X about the way I use Claude Code, so I'm writing this post. I'm too tired to write a long post, so I keep it short. I use <strong>Roo Code with Architecture mode</strong> first, with a prompt like</p>
<blockquote>
<p>Service XXX is for ...</p>
<p>If anything is ambiguous or you are not sure about it, do not infer but ask me.</p>
</blockquote>
<p>After spending a handful of times for clarifying everything and describing entity relations, I ask it to store it as a markdown file. Typically, it generates a very, very long text. I then follow getting started step of the framework I want to use. The latest one I used is <code>tauri</code>. I do this step manually just because typically it's just a few CLI commands. After creating a directory, I ask Claude Code to</p>
<blockquote>
<p>Implement app in @apps/xxx.</p>
<p>[Paste the design markdown file content]</p>
</blockquote>
<p>You'll get a bare minimum prototype that works with dummy data. Even after getting the initial version, I ask Claude Code for all modifications.</p>
]]></content:encoded></item><item><title><![CDATA[par-core & par-iter: Switchable parallelization for Rust]]></title><description><![CDATA[tl;dr:
I forked rayon to allow switching parallelization library or disable parallelization. See par-iter and par-core.

I'm the creator of the SWC project. I've been using chili the SWC Minifier. chili is a parallelization library with a heartbeat s...]]></description><link>https://kdy1.dev/2025-3-26-par-core-and-par-iter</link><guid isPermaLink="true">https://kdy1.dev/2025-3-26-par-core-and-par-iter</guid><category><![CDATA[Rust]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Wed, 26 Mar 2025 07:46:59 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>tl;dr:</p>
<p>I forked <code>rayon</code> to allow switching parallelization library or disable parallelization. See <a target="_blank" href="https://docs.rs/par-iter">par-iter</a> and <a target="_blank" href="https://docs.rs/par-core">par-core</a>.</p>
</blockquote>
<p>I'm the creator of <a target="_blank" href="https://swc.rs">the SWC project</a>. I've been using <code>chili</code> the SWC Minifier. <code>chili</code> is a parallelization library with a heartbeat scheduling algorithm. I found that it performs far better than <code>rayon</code> for my usecase. But it lacks an API like parallel iterators of <code>rayon</code>. Additionally, I need to use different parallelization libraries for <code>next.js</code> or <code>rspack</code> and disable parallelism for Wasm targets. So I forked <code>rayon</code> and named it <a target="_blank" href="https://docs.rs/par-iter">par-iter</a>. <a target="_blank" href="https://docs.rs/par-iter"><code>par-iter</code></a> is based on <a target="_blank" href="https://docs.rs/par-core/"><code>par-core</code></a>, which allows selecting <code>rayon</code> or <code>chili</code> for parallelism or even disabling parallelism using cargo features.</p>
<p>I prefer to get it merged back to <code>rayon</code> , so I filed <a target="_blank" href="https://github.com/rayon-rs/rayon/issues/1235">an issue on the rayon issue tracker to ask if they are open to PR for it</a>, but I don't think it's likely, considering the package name.</p>
<p>Any ideas, thoughts, and feedback are welcome!</p>
]]></content:encoded></item><item><title><![CDATA[성균관대 Gdg에서 발표할 예정이다]]></title><description><![CDATA[발표 자료 만들다가 이 내용을 블로그에 적지 않았다는 것을 깨달아서 늦게나마 올린다.]]></description><link>https://kdy1.dev/2025-3-22-skku-gdg</link><guid isPermaLink="true">https://kdy1.dev/2025-3-22-skku-gdg</guid><category><![CDATA[GDG]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sat, 22 Mar 2025 05:35:12 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742621660656/40cb5e83-d64e-4a33-a5c6-2a34d91d433b.jpeg" alt class="image--center mx-auto" /></p>
<p>발표 자료 만들다가 이 내용을 블로그에 적지 않았다는 것을 깨달아서 늦게나마 올린다.</p>
]]></content:encoded></item><item><title><![CDATA[AutoPilot status update - 2]]></title><description><![CDATA[This week, I introduced a concept of a base image to to the AutoPilot service. A user can configure their own base image as they want, by installing all necessary tools or running builds so that the build cache exists for the worker from start.

This...]]></description><link>https://kdy1.dev/2025-3-22-autopilot-status-update</link><guid isPermaLink="true">https://kdy1.dev/2025-3-22-autopilot-status-update</guid><category><![CDATA[Dudy AutoPilot]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sat, 22 Mar 2025 03:54:48 GMT</pubDate><content:encoded><![CDATA[<p>This week, I introduced a concept of a <code>base image</code> to to the AutoPilot service. A user can configure their own base image as they want, by installing all necessary tools or running builds so that the build cache exists for the worker from start.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742615311914/ed65daa6-8de3-4f8b-8cfc-447619c6828f.png" alt class="image--center mx-auto" /></p>
<p>This is the screenshot of a base image setup process. I installed nodejs and did <code>pnpm install</code>. So there’s a folder named <code>node_modules</code>. After then, I clicked <code>Finish Setup</code> button, an pressing the button creates a base docker image for the worker. It utilizes the <code>docker commit</code> command.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742615383521/3c918e0e-82cc-4ee5-8f09-9bb4ff07b037.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Screenshot captured from a running instance of <code>pnpm dev</code> (using turborepo)</li>
</ul>
<p>And after waiting for a while, I could use the base image in a worker. The base image does not have the AutoPilot vscode extension nor Roo Code, but the worker image has one.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742615477783/09386302-e289-411b-b6b9-36e267fa89ef.png" alt class="image--center mx-auto" /></p>
<p>This is the screenshot of a new worker instance, from which you can find <code>node_modules</code>, Roo Code, and Dudy AutoPilot vscode extension.</p>
<hr />
<p>With this change, a worker can drive a task from the start to the end by itself without an interaction. But I still need to polish lots of things, and I would be busy this weekend because of a GDG event.</p>
]]></content:encoded></item><item><title><![CDATA[AutoPilot development status update - 1]]></title><description><![CDATA[The AutoPilot project aims to take an AI-powered code generation tool that works well like Roo Code and use it as a PR generator. It’s quite similar to Devin, but it will be much cheaper than Devin.

Side note: I’ll not sell this as SaaS, to avoid co...]]></description><link>https://kdy1.dev/2025-3-15-auto-pilot</link><guid isPermaLink="true">https://kdy1.dev/2025-3-15-auto-pilot</guid><category><![CDATA[status update]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Sat, 15 Mar 2025 14:50:44 GMT</pubDate><content:encoded><![CDATA[<p>The AutoPilot project aims to take an AI-powered code generation tool that works well like Roo Code and use it as a PR generator. It’s quite similar to Devin, but it will be much cheaper than Devin.</p>
<ul>
<li>Side note: I’ll not sell this as SaaS, to avoid competing with v0</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742049166241/a2f0632a-2066-41a4-a767-a320b43930e1.png" alt class="image--center mx-auto" /></p>
<p>Yesterday, I managed to <strong>automatically</strong> spawn a <code>code-server</code> instance with my <code>Dudy AutoPilot</code> extension and <code>Roo Code</code> extension installed. Once the user approves the plan for a task, a vscode worker is spawned to resolve the task.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742049659888/72449444-a7e1-482b-a5e5-36022ff000d5.png" alt class="image--center mx-auto" /></p>
<p>Today, I made it automatically clone the repository, configure <code>Roo Code</code> using secrets sent by the server, and start a new task with <code>Roo Code</code>.</p>
]]></content:encoded></item><item><title><![CDATA[Prompt Context 번역]]></title><description><![CDATA[Prompt Context는 AI를 거대한 레포지토리에서 사용할 수 있게 해주는 아이디어입니다. 사용하시는 IDE나 도구는 거의 상관 없습니다. 그리고 이 방식을 사용하면 거대하고 복잡한 모노레포에서도 AI가 잘 작동합니다.

tl;dr;

제 .cursorrules 파일은 다음과 같습니다.
 - First, look for glob `**/.AI.md`. Use terminal command `find . -name '.AI.md'` from...]]></description><link>https://kdy1.dev/2025-3-12-prompt-context-kr</link><guid isPermaLink="true">https://kdy1.dev/2025-3-12-prompt-context-kr</guid><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Wed, 12 Mar 2025 11:56:25 GMT</pubDate><content:encoded><![CDATA[<p>Prompt Context는 AI를 거대한 레포지토리에서 사용할 수 있게 해주는 아이디어입니다. 사용하시는 IDE나 도구는 거의 상관 없습니다. 그리고 이 방식을 사용하면 거대하고 복잡한 모노레포에서도 AI가 잘 작동합니다.</p>
<blockquote>
<p>tl;dr;</p>
</blockquote>
<p>제 <code>.cursorrules</code> 파일은 다음과 같습니다.</p>
<pre><code class="lang-markdown"><span class="hljs-bullet"> -</span> First, look for glob <span class="hljs-code">`**/.AI.md`</span>. Use terminal command <span class="hljs-code">`find . -name '.AI.md'`</span> from the project root, if required.
<span class="hljs-bullet"> -</span> Second, if you are going to read and/or write any file in a directory containing <span class="hljs-code">`.AI.md`</span> files from the first step, read all of them and respect the instructions in them.
<span class="hljs-bullet"> -</span> For example, if you are reading or writing a file at /a/b/c, you should check for <span class="hljs-code">`/a/.AI.md`</span>, <span class="hljs-code">`/a/b/.AI.md`</span> and <span class="hljs-code">`/a/b/c/.AI.md`</span> in the order.
</code></pre>
<p>감이 오시나요? 이런 방식으로 AI한테 어떤 폴더에서는 어떻게 작업해야하는지 폴더별로 가르쳐줄 수 있습니다. <code>context.md</code> 파일을 통해서요.</p>
<p>아이디어는 인공지능이 작업을 하기 위해 필요한 경우 임의의 파일을 읽어올 수 있다는 점에서 착안했습니다. 제 레포지토리는 전혀 느낌이 다른 여러개의 next.js 앱과 protobuf RPC를 위한 코드를 포함해 여러가지 복잡한 패키지들이 있는데요, 각 폴더에서 해야하는 작업이 너무 다릅니다. 하지만 저는 이 기술을 사용해서 AI가 코드를 잘 짜게 만들 수 있었습니다.</p>
<p><strong>장점:</strong></p>
<ul>
<li><p>전체 폴더를 위한 작업 지침을 넘기는 것이 아니기 때문에 컨텍스트 사이즈가 거의 문제되지 않습니다.</p>
</li>
<li><p>폴더별로 작성하기 때문에 관리하기 쉬워집니다.</p>
</li>
<li><p>AI가 코드 스타일을 더 잘 지킵니다. (지키지 않는다면 <code>context.md</code> 에 적으면 됩니다.)</p>
</li>
<li><p>AI가 더 높은 퀄리티의 코드를 짭니다.</p>
</li>
<li><p><code>.cursorrules</code> 방식의 암시적 프롬프트가 레포지토리의 복잡도와 상관없이 작동합니다.</p>
</li>
</ul>
<p>예시 <code>context.md</code> 파일입니다.</p>
<p><code>/context.md</code>:</p>
<p>(레포지토리의 최상단에 있습니다)</p>
<pre><code class="lang-markdown">
<span class="hljs-section"># RPC</span>

We use connect rpc to call RPC methods. The protobuf files are located at <span class="hljs-code">`${gitRoot}/rpc/*/v1.proto`</span>.

<span class="hljs-section">## When to use RPC vs client-side code</span>

<span class="hljs-bullet">-</span> Basically, prefer client-side code over RPC.
<span class="hljs-bullet">-</span> If you need to call a nodejs-only code, use RPC.
<span class="hljs-bullet">-</span> If you need to call code that uses any secret, use RPC.

<span class="hljs-section">## Implementing RPC methods</span>

<span class="hljs-bullet">-</span> First, add the RPC method definitions and message definitions to the protobuf files.
<span class="hljs-bullet">-</span> You should register the RPC method implementations in the <span class="hljs-code">`${gitRoot}/servers/*-api/connect.ts`</span> file.
<span class="hljs-bullet">-</span> You should not store all code in the <span class="hljs-code">`${gitRoot}/servers/*-api/connect.ts`</span> file. Instead, define a service and put the implementation in another file in the same directory.

<span class="hljs-section">## Calling RPC methods</span>

<span class="hljs-bullet">-</span> Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.

From a react component, you can define a hook using the <span class="hljs-code">`useMutation`</span> method.

<span class="hljs-code">```js
const detectFaces = webtoolsClient.detectFaces.useMutation();
```</span>

After then, you can call the method with <span class="hljs-code">`mutateAsync`</span> method.

<span class="hljs-code">```js
const result = await detectFaces.mutateAsync({
  imageData: new Uint8Array(buffer),
});
```</span>
</code></pre>
<p><code>/apps/context.md</code>:</p>
<pre><code class="lang-markdown"><span class="hljs-bullet">1.</span> This directory contains next.js apps. Follow the next.js app directory structure.
<span class="hljs-bullet">2.</span> List all files before you start coding. Follow the file structure.
<span class="hljs-bullet">3.</span> Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.
<span class="hljs-bullet">4.</span> Prefer explicit path parameters in components over 'useParams'.
<span class="hljs-bullet">5.</span> Do not generate shadcn ui components.
<span class="hljs-bullet">6.</span> If you are trying to run the test script in package.json (e.g. <span class="hljs-code">`pnpm test:unit`</span>), ensure you set environment variable <span class="hljs-code">`CI=1`</span> to indicate it's running automatically.
<span class="hljs-bullet">7.</span> Follow Toss Design guidelines.
<span class="hljs-bullet">8.</span> Ignore route-related TypeScript type errors.
<span class="hljs-bullet">9.</span> If you need to call mutating RPC methods, use the <span class="hljs-code">`useMutation`</span> hook.

<span class="hljs-code">```ts
const createProject = coreClient.createProject.useMutation();
```</span>

<span class="hljs-bullet">10.</span> If you need to call query RPC methods, use the <span class="hljs-code">`useQuery`</span> hook.

<span class="hljs-code">```ts
const projects = coreClient.listProjects.useQuery();
```</span>

<span class="hljs-bullet">11.</span> Include <span class="hljs-code">`locale: Locale`</span> where <span class="hljs-code">`Locale`</span> is <span class="hljs-code">`import { Locale } from "@/i18n";`</span> in the params of the page components.
<span class="hljs-bullet">12.</span> Define the params as <span class="hljs-code">`Promise&lt;T&gt;`</span> in the page components.
<span class="hljs-bullet">13.</span> Use <span class="hljs-code">`use(params)`</span> to unwrap the params as <span class="hljs-code">`T`</span> from <span class="hljs-code">`Promise&lt;T&gt;`</span> in the page components.
<span class="hljs-bullet">14.</span> Import RPC clients from <span class="hljs-code">`@dudykr/rpc-clients/src/XXX`</span>. where <span class="hljs-code">`XXX`</span> is the name of the RPC client.

e.g.

<span class="hljs-code">```ts
import { coreClient } from "@dudykr/rpc-clients/src/core";
```</span>

<span class="hljs-bullet">15.</span> Use <span class="hljs-code">`&lt;Link&gt;`</span> from <span class="hljs-code">`next/link`</span> instead of the <span class="hljs-code">`&lt;a&gt;`</span> tag.

<span class="hljs-section"># Translation</span>

For the next.js apps, modify only <span class="hljs-code">`./messages/en.json`</span> and run <span class="hljs-code">`pnpm translate`</span>.
This will translate the messages to all languages.
</code></pre>
<p>이것들은 실제로 제가 사용하는 <code>context.md</code> 파일들입니다. 흥미롭다면 한 번 시도해보시는 걸 추천드립니다.</p>
]]></content:encoded></item><item><title><![CDATA[Prompt Context: The technique of the era]]></title><description><![CDATA[I want to introduce an idea for utilizing AI for huge repositories. It’s a tool-agnostic technique.

The IDE you use does not matter.

The size of your code base can be huge; AI will still work with this technique.



tl;dr;

My .cursorrules:
 - Firs...]]></description><link>https://kdy1.dev/2025-3-12-prompt-context</link><guid isPermaLink="true">https://kdy1.dev/2025-3-12-prompt-context</guid><category><![CDATA[AI]]></category><category><![CDATA[Programming Tips]]></category><category><![CDATA[AI coding]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Wed, 12 Mar 2025 11:39:25 GMT</pubDate><content:encoded><![CDATA[<p>I want to introduce an idea for utilizing AI for huge repositories. It’s a tool-agnostic technique.</p>
<ul>
<li><p>The IDE you use does not matter.</p>
</li>
<li><p>The size of your code base can be huge; AI will still work with this technique.</p>
</li>
</ul>
<blockquote>
<p>tl;dr;</p>
</blockquote>
<p>My <code>.cursorrules</code>:</p>
<pre><code class="lang-markdown"><span class="hljs-bullet"> -</span> First, look for glob <span class="hljs-code">`**/.AI.md`</span>. Use terminal command <span class="hljs-code">`find . -name '.AI.md'`</span> from the project root, if required.
<span class="hljs-bullet"> -</span> Second, if you are going to read and/or write any file in a directory containing <span class="hljs-code">`.AI.md`</span> files from the first step, read all of them and respect the instructions in them.
<span class="hljs-bullet"> -</span> For example, if you are reading or writing a file at /a/b/c, you should check for <span class="hljs-code">`/a/.AI.md`</span>, <span class="hljs-code">`/a/b/.AI.md`</span> and <span class="hljs-code">`/a/b/c/.AI.md`</span> in the order.
</code></pre>
<p>Did you get it? You can write this down and write down how you need to work on a folder-by-folder basis in a folder-specific <code>context.md</code>. This technique tells the AI what to do in which folders and how to do it on a folder-by-folder basis.</p>
<p>The idea is that the AI can call tools to read the files it needs, depending on what it needs to do. In my repository, I had a mix of next.js apps with different feelings, code for protobuf-based RPCs packaged in monorepo, and a lot of other things to do in other folders, and I was able to apply this technique to solve the problem.</p>
<p><strong>Pros:</strong></p>
<ul>
<li><p>Context size is rarely an issue no matter how large your repository grows, because you're not flipping through action rules for every folder.</p>
</li>
<li><p>It's easier to manage because you can set action rules per folder.</p>
</li>
<li><p>The AI will adhere to your code style (and if it doesn't, you can write it down in <code>context.md</code>).</p>
</li>
<li><p>AI’s code will be of higher quality.</p>
</li>
<li><p><code>.cursorrules</code>-style file works for any kind of complex repository, even though requirements are very different.</p>
</li>
</ul>
<p>An example <code>context.md</code> files would be</p>
<p><code>/context.md</code>:</p>
<p>(This is at the root of the repository)</p>
<pre><code class="lang-markdown">
<span class="hljs-section"># RPC</span>

We use connect rpc to call RPC methods. The protobuf files are located at <span class="hljs-code">`${gitRoot}/rpc/*/v1.proto`</span>.

<span class="hljs-section">## When to use RPC vs client-side code</span>

<span class="hljs-bullet">-</span> Basically, prefer client-side code over RPC.
<span class="hljs-bullet">-</span> If you need to call a nodejs-only code, use RPC.
<span class="hljs-bullet">-</span> If you need to call code that uses any secret, use RPC.

<span class="hljs-section">## Implementing RPC methods</span>

<span class="hljs-bullet">-</span> First, add the RPC method definitions and message definitions to the protobuf files.
<span class="hljs-bullet">-</span> You should register the RPC method implementations in the <span class="hljs-code">`${gitRoot}/servers/*-api/connect.ts`</span> file.
<span class="hljs-bullet">-</span> You should not store all code in the <span class="hljs-code">`${gitRoot}/servers/*-api/connect.ts`</span> file. Instead, define a service and put the implementation in another file in the same directory.

<span class="hljs-section">## Calling RPC methods</span>

<span class="hljs-bullet">-</span> Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.

From a react component, you can define a hook using the <span class="hljs-code">`useMutation`</span> method.

<span class="hljs-code">```js
const detectFaces = webtoolsClient.detectFaces.useMutation();
```</span>

After then, you can call the method with <span class="hljs-code">`mutateAsync`</span> method.

<span class="hljs-code">```js
const result = await detectFaces.mutateAsync({
  imageData: new Uint8Array(buffer),
});
```</span>
</code></pre>
<p><code>/apps/context.md</code>:</p>
<pre><code class="lang-markdown"><span class="hljs-bullet">1.</span> This directory contains next.js apps. Follow the next.js app directory structure.
<span class="hljs-bullet">2.</span> List all files before you start coding. Follow the file structure.
<span class="hljs-bullet">3.</span> Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.
<span class="hljs-bullet">4.</span> Prefer explicit path parameters in components over 'useParams'.
<span class="hljs-bullet">5.</span> Do not generate shadcn ui components.
<span class="hljs-bullet">6.</span> If you are trying to run the test script in package.json (e.g. <span class="hljs-code">`pnpm test:unit`</span>), ensure you set environment variable <span class="hljs-code">`CI=1`</span> to indicate it's running automatically.
<span class="hljs-bullet">7.</span> Follow Toss Design guidelines.
<span class="hljs-bullet">8.</span> Ignore route-related TypeScript type errors.
<span class="hljs-bullet">9.</span> If you need to call mutating RPC methods, use the <span class="hljs-code">`useMutation`</span> hook.

<span class="hljs-code">```ts
const createProject = coreClient.createProject.useMutation();
```</span>

<span class="hljs-bullet">10.</span> If you need to call query RPC methods, use the <span class="hljs-code">`useQuery`</span> hook.

<span class="hljs-code">```ts
const projects = coreClient.listProjects.useQuery();
```</span>

<span class="hljs-bullet">11.</span> Include <span class="hljs-code">`locale: Locale`</span> where <span class="hljs-code">`Locale`</span> is <span class="hljs-code">`import { Locale } from "@/i18n";`</span> in the params of the page components.
<span class="hljs-bullet">12.</span> Define the params as <span class="hljs-code">`Promise&lt;T&gt;`</span> in the page components.
<span class="hljs-bullet">13.</span> Use <span class="hljs-code">`use(params)`</span> to unwrap the params as <span class="hljs-code">`T`</span> from <span class="hljs-code">`Promise&lt;T&gt;`</span> in the page components.
<span class="hljs-bullet">14.</span> Import RPC clients from <span class="hljs-code">`@dudykr/rpc-clients/src/XXX`</span>. where <span class="hljs-code">`XXX`</span> is the name of the RPC client.

e.g.

<span class="hljs-code">```ts
import { coreClient } from "@dudykr/rpc-clients/src/core";
```</span>

<span class="hljs-bullet">15.</span> Use <span class="hljs-code">`&lt;Link&gt;`</span> from <span class="hljs-code">`next/link`</span> instead of the <span class="hljs-code">`&lt;a&gt;`</span> tag.

<span class="hljs-section"># Translation</span>

For the next.js apps, modify only <span class="hljs-code">`./messages/en.json`</span> and run <span class="hljs-code">`pnpm translate`</span>.
This will translate the messages to all languages.
</code></pre>
<p>These are real <code>context.md</code> files I use. Give it a try if it sounds interesting.</p>
]]></content:encoded></item><item><title><![CDATA[항해 Ai 생산성 토크쇼 Q&a]]></title><description><![CDATA[인사이트 공유가 제일 큰 목적인만큼, 최대한 많이 답변하기 위해 노력했지만 오늘 얘기한 내용들, 사업적인 아이디어, 혹은 비개발적인 AI 활용에 대한 질문은 제외했습니다. 저는 AI를 사용해서 생산성을 올리는 방법을 연구한 개발자일 뿐, AI 엔지니어가 아니기 때문에 비개발적인 AI 질문들은 대답하기 힘듭니다. 잘못된 답변을 드릴 수도 있기 때문에 답변을 하지 않았습니다.
저도 할루시네이션 해결법 같은 건 모릅니다. 대신 AI로 코딩할 때 AI...]]></description><link>https://kdy1.dev/2024-3-11-ai-qna</link><guid isPermaLink="true">https://kdy1.dev/2024-3-11-ai-qna</guid><category><![CDATA[Q&A]]></category><category><![CDATA[항해]]></category><category><![CDATA[항해플러스]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[DongYoon Kang]]></dc:creator><pubDate>Tue, 11 Mar 2025 11:45:46 GMT</pubDate><content:encoded><![CDATA[<p>인사이트 공유가 제일 큰 목적인만큼, 최대한 많이 답변하기 위해 노력했지만 오늘 얘기한 내용들, 사업적인 아이디어, 혹은 비개발적인 AI 활용에 대한 질문은 제외했습니다. 저는 AI를 사용해서 생산성을 올리는 방법을 연구한 개발자일 뿐, AI 엔지니어가 아니기 때문에 비개발적인 AI 질문들은 대답하기 힘듭니다. 잘못된 답변을 드릴 수도 있기 때문에 답변을 하지 않았습니다.</p>
<p>저도 할루시네이션 해결법 같은 건 모릅니다. 대신 AI로 코딩할 때 AI가 틀린 코드를 작성한 경우 스스로 정정한 뒤에 다음 단계로 넘어가게 하는 방법은 알고 있습니다.</p>
<p>참고로 내용이 거의 비슷한 질문은 첫번째 질문을 인용으로 달았습니다.</p>
<hr />
<blockquote>
<p>문서화도 대체하고 싶은데 어떻게 자동화할까요</p>
</blockquote>
<p>코드 @ 로 넣고 문서화 해달라고 하면 해줍니다.</p>
<blockquote>
<p>코딩 에이전트 vs 어시스턴트. 앞으로의 방향성을 어떻게 보시는지 궁금합니다</p>
</blockquote>
<p>에이전트가 간단한 작업은 다 대신 해주리라 보고있고요, 저도 하나 만들고 있습니다.</p>
<blockquote>
<p>에이전트 등으로 FE라는 직무는 향후 5년 내 없어지지 않을까 예상하고 있습니다. 개발자들이 변화하는 ai 시대에 대응하기 위해 준비해야 할 역량은 무엇일까요?</p>
</blockquote>
<p>AI 활용 능력입니다. 프론트엔드/백엔드 구분은 없어질 가능성이 높고요, 그냥 소수의 인원이 프론트엔드/백엔드 같은 구분 없이 전체를 구현하는 시대가 올 것이라고 봅니다. 이미 그러고있는 회사들도 있고요</p>
<blockquote>
<p>AI와 페어 프로그래밍 방법</p>
</blockquote>
<p>시연에서 보여드렸듯이 AI한테 일 시켜놓고 가끔 간섭하면 됩니다.</p>
<blockquote>
<p>주니어다 보니 AI를 활용하면서도 너무 기본기를 못 쌓고 AI에만 의존하는게 아닌가 하는 걱정이 드는데 의견이 궁금합니다.</p>
</blockquote>
<p>모르는 개념에 대해서 AI가 작성한 코드는 읽어보세요. 개념에 대해서 알고있는 경우는 그냥 넘어가도 되는데 개념도 모르는 상태에서 AI를 이용해서 구현만 하고 넘어가는 건 좋은 생각이 아닙니다.</p>
<blockquote>
<p>AI가 전체 프로젝트 구조를 계속 인지한 싱태로 개발시킬 수 있는 방법</p>
</blockquote>
<p><code>.cursorrules</code> 같은 파일과 커서 같은 IDE의 인덱싱 기능을 활용하세요. 자동으로 RAG로 관련 코드를 AI한테 던져줍니다.</p>
<blockquote>
<p>AI를 어디까지 활용하는게 맞을까요? 요즘에는 너무 AI에만 의존하는 것 같다는 생각이 들어서 고민입니다.</p>
</blockquote>
<p>저는 은행권이나 군사쪽처럼 폐쇄망 개발을 해야하는 쪽을 가려는 것이 아닌 이상 거의 모든 일에 활용해도 된다고 봅니다. 근데 AI한테 일 시킬 정도는 이해하고 있어야하는데, 개념 정도만 제대로 이해하고 있으면 충분합니다. 혼자서 구현할 수 있을 정도까지는 필요없지만 AI가 짜놓은 코드를 보고 이건 개념의 어느 부분인지 알 수 있을 정도는 돼야합니다.</p>
<blockquote>
<p>좋은 코드를 뱉는 ai 프롬프트 잘 짜는 방법</p>
</blockquote>
<p>LLM을 직접 다루시는 것이라면 유출된 커서/윈드서프 같은 유명한 도구들 프롬프트 읽어보시는 걸 추천하고요, 커서를 쓰고 싶으신거면 그냥 쓰시면 됩니다. 근데 AI는 말을 진짜 있는 그대로 이해합니다. 비꼬는 건 다 알아듣는데, 보여드렸듯이 "최적화해줘" 를 안 넣고 "분리해줘" 만 하면 진짜 분리만 해줍니다.</p>
<blockquote>
<p>Ai답변이 사실인지 확인하는법</p>
</blockquote>
<p>코드 생성할 땐 테스트 짜는 게 최선입니다. 그리고 AI 없이도 개념 설명은 할 수 있어야 검증이 쉬워요.</p>
<blockquote>
<p>AI로 인해 개발자도 생각보다 빠르게 줄어들고 있는 상황입니다. 이런 상황에서 나만의 무기를 만들 방법은 AI를 잘 활용하는 방법밖에는 없는걸까요?</p>
</blockquote>
<p>AI를 활용한 개발 자동화 서비스를 만드는 것도 방법인데요, 저도 하고있습니다.</p>
<blockquote>
<p>음... LLM을 사용하는 방식에 제일 많을 것 같은데 혹시 cursorrules 같은 instructions file같은 것을 많이 설정해놓고 하는 편이신가요?</p>
</blockquote>
<p>전 여러가지 AI 툴을 사용하기도 하고 개인적으로 작업하는 레포지토리가 모노레포인 동시에 꽤나 복잡하기 때문에 <code>.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a>라는 파일을 폴더마다 넣어두고 <code>.cursorrules</code> 로 해당 파일을 적절한 상황에서 읽으라고 지시합니다. "<code>/a/b/c</code>의 파일을 수정할 것이면 <code>/a/.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a>, <code>/a/b/.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a>, <code>/a/b/c/.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a>를 전부 읽어야한다." 같은 식입니다. 그리고 그 <code>.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a> 파일엔 "어떤 동작을 할 것이라면 어떤 파일을 읽어봐라" 혹은 "어떤 동작은 이런식으로 처리해라" 식의 문장을 넣어둡니다. 이렇게 하면 자기가 작업 전에 예시 파일 읽고 상황에 맞는 동작 취해요.</p>
<blockquote>
<p>AI 정보 얻는 곳이 궁금합니다!</p>
</blockquote>
<p>전 주로 Geek News나 쓰레드에서 정보를 얻습니다.</p>
<blockquote>
<p>AI는 개발자와 대립하는 존재인가 동반자가 될 존재인가</p>
</blockquote>
<p>적어도 살아남은 개발자한텐 엄청나게 중요한 동반자일겁니다.</p>
<blockquote>
<p>보안이 엄격한 회사에서는 Ai를 어떻게 활용할 방법이 없을지 궁금합니다</p>
</blockquote>
<p>오픈소스 LLM을 자체적으로 띄우면 됩니다. 물론 코딩 실력은 좀 떨어지지만 그래도 쓸만하다고 들었습니다.</p>
<blockquote>
<p>생성형 ai가 범람하는 이때 주니어 개발자를 채용하지 않겠다는 소식을 가끔 듣습니다. ai에 대체 당하지 않을 개발자가 되는 법은 무엇일까요?</p>
</blockquote>
<p>AI를 잘 다루는 게 최선입니다. 이미 시니어 한 명이 AI를 적극적으로 활용해서 시니어 몇명분의 업무를 처리하는 시대이거든요. "1인분"의 개념 자체가 AI 때문에 바뀔 겁니다.</p>
<blockquote>
<p>Ai가 제공한 코드에 대한 검증을 어떻게 하는지</p>
</blockquote>
<p>테스트 케이스 많이 짜달라고하고 테스트 케이스를 검증하는 게 제일 쉬운 방법입니다. 물론 개념은 다 이해하시고 넘어가시고요.</p>
<blockquote>
<p>AI의 교육적 활용법</p>
</blockquote>
<p>시연에서 보여드렸듯이 AI한테 진행하지 말고 가능한 모든 방법을 나열해달라고 하는 게 최고입니다.</p>
<blockquote>
<p>조직이 매우 소규모라 프로토타이핑을 넘어서 운영 레벨로 넘어갈때에 대한 고민이 있고(조직내 대부분의 인원이 리서처 출신으로 모델 학습을 주로 했던지라 큰 서비스 운영 경험이 없음), 채용 관점에서 매일 세상이 바뀌는 느낌이라 어떤 분을 뽑아야하는지 고민이 있습니다.</p>
</blockquote>
<p>AI를 잘 다루는 시니어가 현 시점에선 최고입니다. 근데 이런 분을 실질적으로 어떻게 알아볼 것인가에 대한 얘기는 저도 아직 잘 모르겠습니다. 하지만 세상이 빨리 바뀔수록, 그리고 인공지능이 뜨면 뜰수록 순수 지능 높은 개발자가 최고입니다. 그쪽으로 찾아보시는 걸 추천드립니다.</p>
<blockquote>
<p>비인기 언어 사용시 나타나는 환각을 어떻게 피하는지 궁금해요!</p>
</blockquote>
<p>자체적인 언어라면 언어 스펙 문서 같은 걸 컨텍스트로 넣으시면 잘 작동할겁니다.</p>
<blockquote>
<p>안정적인 서비스적용을위한 평가방법론이 궁금합니다</p>
</blockquote>
<p>저도 개발 자동화 서비스를 개발중인 입장이라서 고민중인 내용인데요, 아직은 PR까지 만든 뒤 CI와 사람의 코드리뷰를 활용하는 게 제일 안전하지 않나 생각합니다. 참고로 저는 상위 모델을 사용하는 Supervisor 에이전트를 만드는 것도 고려중인데, 작동할지는 잘 모릅니다. 시도는 한 번 해 볼 생각입니다.</p>
<blockquote>
<p>AI의 발전으로 인해 1인 개발자가 많아진다면 사실 협업이나 커뮤니케이션 역량은 그닥 도움이 되지 않는게 아닐까 하는 걱정이 있는데 어떻게 생각하시나요</p>
</blockquote>
<p>1인 창업을 하실 게 아니라면 여전히 중요한 능력일 겁니다. 1인 개발이라는 게 개발을 혼자한다는 얘기지 회사의 모든 업무를 혼자 한다는 얘기가 아니기 때문에 여전히 마케팅이나 디자인처럼 개발이랑 전혀 상관없는 업무를 맡으신 분과는 협업을 해야하실 겁니다.</p>
<blockquote>
<p>여러 aI 도구간의 파이프라이닝을 어떻게 하면 좋을까요?</p>
</blockquote>
<p>저도 한참 고민해본 문제인데요, 이건 결국 코딩을 하지 않고 해결이 안 되는 문제 같습니다. 저도 그래서 결국 개발 반자동화 서비스가 필요하다는 결론을 내리고 개발중입니다.</p>
<blockquote>
<p>기초적인 코드 작성할때 자꾸 AI에 기대는 것 같은데 이렇게 의존해서 실력이 하락할까 걱정입니다.</p>
</blockquote>
<p>저도 실력이 어느정도 떨어졌겠지만 저는 폐쇄망 개발쪽으로 갈 의향이 없기 때문에 별로 신경쓰지 않습니다. 저는 폐쇄망 개발이 필요한 상황이 오지 않는다면 AI 도움 없이 코드를 만들어내는 능력은 가면 갈수록 별 의미가 없어질 것이라고 생각합니다.</p>
<blockquote>
<p>Shadcn 외 다른 컴포넌트로도 V0 사용 가능한가</p>
</blockquote>
<p>v0에 프롬프트 넣는 기능이 있는데요, 최근에 프롬프트 유출됐으니 한번 보시고 컴포넌트 부분을 사용하시는 컴포넌트 라이브러리에 맞게 수정하신 뒤 프롬프트로 넣으시면 작동할겁니다.</p>
<blockquote>
<p>개발자라는 직업에서 AI한테 대체가능한 영역이 어느정도라고 보시는지 궁금합니다</p>
</blockquote>
<p>코드를 짠다라고 하는 부분은 사실상 거의 다 대체가 가능할 것이라고 봅니다.</p>
<blockquote>
<p>manus같은 에이전트를 한국에서 개발하려는데 자금이 부족합니다. 어떻게 해야할까요.</p>
</blockquote>
<p>에이전트 개발 자체는 비용이 크게 들지 않습니다. 대규모 언어 모델을 만드는 게 아니잖아요. 에이전트도 언어 모델을 활용한다 뿐이지 일반적인 프로그램입니다. 운영 비용은 수익 모델을 만들어서 충당하시면 됩니다.</p>
<blockquote>
<p>요즘은 개발에도 ai 를 연동시키거나 접목시키는 경우가 많은 것 같습니다. 그래서 백엔드 개발자로서 어떤 포지션으로 어떤 지식을 가지고 있어야 하는지 알고싶습니다.</p>
</blockquote>
<p>오늘 얘기한 지식 정도면 거의 충분할겁니다. 참고로 Roo Cline이나 커서 같은 경우 MCP를 이용하면 인프라까지 관리할 수 있습니다. 이런 식으로 어떤 AI 도구가 어떤 역할까지 할 수 있는지 알고 있으면 됩니다.</p>
<blockquote>
<p>주니어의 AI 페어프로그래밍 시 효과적인 사용법</p>
</blockquote>
<p>기본적으로는 위에서 답변했듯이 코드를 생성하되 개념은 진짜로 이해하고 넘어가는 게 제일 좋은 활용법이라고 봅니다. 그리고 제가 생각하는 개념 이해의 기준선은 AI가 작성한 코드의 어떤 부분이 개념의 어떤 부분을 구현한 것인지 바로바로 알 수 있을 정도입니다. 이 정도면 추후에 다른 작업을 지시할 때나 관련 문서를 작성할 때 충분합니다. 그리고 오늘 보여드렸듯이, “가능한 모든 최적화를 나열해줘” 같은 것도 좋은 사용법입니다.</p>
<blockquote>
<p>AI 생성에 유리한 언어나 프레임워크의 특성이 궁금합니다.</p>
</blockquote>
<p>러스트, 타입스크립트가 대표적으로 불리한 언어인데요, 러스트는 언어 자체가 추론할 게 많고, 타입스크립트는 Mapped 타입 같은 것들 한정입니다. 이런 식으로 추론이 많이 필요하면 불리해져요. 반대로 사람 입장에서도 추론할 게 없다면 코드 잘 짜줍니다.</p>
<blockquote>
<p>사내 LLM백엔드를 쉽고빠르고저렴하게 구성하는방법</p>
</blockquote>
<p>인프라 엔지니어가 아니라서 잘 모릅니다.</p>
<blockquote>
<p>데이터분석에 어떤식으로 활용하면 효율성을 극대화 시킬 스 있을지 궁금합니다.</p>
</blockquote>
<p>v0한테 데이터 던지고 시각화 해달라고 하면 이미지나 그래프로 보여줍니다. 경험상 그게 제일 빨라요. 데이터 분석 과정에 사용하고 싶으신 것이라면 분석 스크립트를 짜달라고 하시면 돼요. 어떤 점을 분석하고 싶은 것인지만 얘기해도 자기가 알아서 코드 만들어줍니다.</p>
<blockquote>
<ol>
<li>Cursor 나 Windsurf 구독하지 않고 비슷한 기능을 사용하는 방법을 알고 싶어요. 2. 개발하는 프로젝트 구조와 파일 수가 많이 커져도 전체를 다 파악하면서 일관성있게 개발을 계속하고 리펙토링도 가능한 방법이 있나요?</li>
</ol>
</blockquote>
<p>관련된 도구를 직접 만드시는 방법이나 개인 API 키를 사용하시는 방법 외엔 사실상 없다고 보시면 됩니다. 두번째 질문은 <code>.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a> 답변 참고하세요.</p>
<blockquote>
<p>프로덕션 상에서는 기능 추가에 AI를 사용할 경우 워낙 코드베이스가 방대하다보니 그 정확도가 많이 떨어집니다. 이를 어떻게 극복하고 계신지가 궁금합니다.</p>
</blockquote>
<p><code>.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a> 답변 참조하시면 됩니다.</p>
<blockquote>
<p>아주 긴 코드에서 맥락 유지하면서 개발하는 방법</p>
</blockquote>
<p>파일이 많은 것이라면 <code>.</code><a target="_blank" href="http://AI.md"><code>AI.md</code></a> 답변 참고하시면 되는데, 긴 파일 얘기하시는 것이라면 커서 같은 도구 사용하세요. 커서에 Long Context Mode 라는 것이 있는데 체크박스만 누르면 긴 파일도 컨텍스트로 넣어줍니다.</p>
<blockquote>
<p>개발팀이 AI를 더 잘 활용할 수 있도록 회사 차원에서 어떤 걸 해주면 좋을지 고민입니다</p>
</blockquote>
<p>커서/윈드서프 등 툴 지원 및 Roo Cline 같은 도구들 사용할 때 드는 비용 정도 지원해주시면 될 것 같습니다.</p>
<blockquote>
<p>Ai를 어디까지 접목해야하는지, 모두다 ai가 한다면 내 코드가 맞는지</p>
</blockquote>
<p>앞 질문은 위에 답변 참조하시고, ai 별 이용약관이 있는데 그것을 읽어보시면 됩니다. 현실적으로는 당연히 제 코드고요.</p>
<blockquote>
<p>ai를 전문적으로 공부할 생각은(지금단계에서는) 없지만 활용 역량을 끌어올리고 싶다는 가정하에 ai에 대해 이론 공부를 어디까지 하면 좋을지 궁금합니다</p>
</blockquote>
<p>AI를 코딩용으로 활용하는 게 목적이면 이론 공부는 필요 없습니다.</p>
<blockquote>
<p>현재 온페이지, 테크니컬SEO를 주 담당하고있는데 AI를 사용함으로써 더 생산성이 높아질지</p>
</blockquote>
<p>당연히 높아집니다. SEO 해달라고 하면 진정한 SEO 초고수가 뭔지 보여주더라고요. 저도 해봤는데 사람보다 한참 위라고 느꼈습니다. og는 물론이고 구조화된 메타데이터까지 짜줍니다.</p>
<blockquote>
<p>AI로 생성된 코드의 보안 취약점을 효과적으로 분석하고 방지하는 방법.</p>
</blockquote>
<p>시도해보진 않았지만 보안 취약점이 없는 코드를 짜달라고 하면 CSRF 토큰 같은 것도 적용해서 코드를 작성해줄 것입니다. 근데 기본적인 접근은 주니어가 짠 코드로 취급하는 것이 최선인 것 같습니다. 저도 개발 반자동화 서비스를 만들고 있는데, 코드 리뷰로 취약점을 잡을 생각이에요. 참고로 프롬프트나 <code>.cursorrules</code> 같은 것으로 보안 규칙을 명시해주면 잘 따릅니다.</p>
<blockquote>
<p>개발할 때 LLM을 적극 활용하시나요? 신규 기능을 도입할 때 적극 활용중인데, 너무 LLM 의존적인 것 같아 가끔 스스로 회의감이 들 때가 있습니다. 모르는 기능을 도입할 때 어떤 식으로 활용하시나요?</p>
</blockquote>
<p>매우 적극적으로 활용합니다. 근데 저는 관련된 개념은 다 이해하고 있습니다. 저는 개념 이해 정도면 충분하다고 봅니다. 저는 어차피 AI 도움 없이 혼자서 코드를 짜는 능력은 가면 갈수록 큰 의미가 없어질 것이라고 봐요. 단지 컴퓨팅적 사고에 소질이 있다는 것을 증명하는 용도가 되지 않을까 생각합니다. 그리고 저는 제가 예전에 구현했던 것들 AI한테 절대 참조하지 말고 처음부터 구현해보라고 시킨 뒤 AI는 어떤 식으로 접근했나도 살펴봅니다. 이러면 도움이 많이 되는 것 같아요.</p>
<blockquote>
<p>레거시와 함께할때 어떻게 최대치로 활용할까</p>
</blockquote>
<p>커서 같은 도구를 사용하시면 레거시 코드도 컨텍스트로 알아서 넣어줍니다. @로 직접 넣으셔도 되고요. <code>.AI.md</code> 관련 답변도 읽어보시는 걸 추천드립니다.</p>
<blockquote>
<p>AI를 사용함으로써 생산성을 올릴 수 있지만 보안에 대한 이슈는 없을지 궁금합니다</p>
</blockquote>
<p>민감한 정보는 외부 AI에 넣지 않는 것이 기본입니다. 코드가 민감한 정보라면 리텐션 기능이 있는 (유료) AI 도구만 활용하세요. 그리고 <code>.rooignore</code> 같은 파일을 적극적으로 활용하시는 것을 추천드립니다.</p>
<blockquote>
<p>1. AI를 어느정도 범위로 사용하시는지?<br />2. 협업에 혼란이 가지 않게끔 AI가 코드를 작성하게할 수 있는지? (기존 컨벤션이나 파일을 과 맞지 않는 코드 작성)<br />3. 생소한 라이브러리와 AI를 함께 사용하는 경우 활용도가 떨어지는 문제를 겪고있는데 혹시 이런 경험이 있으신지, 있다면 특별한 해결방법이 있을지?</p>
</blockquote>
<p>1번은 토크쇼에서 얘기했습니다.</p>
<p>2번 같은 경우, git hook 같은 방법을 찾아보세요. 컨벤션은 기본적으로 도구를 이용해서 관리하는 것입니다. git hook으로 안 되는 종류의 컨벤션은 관련 명령어를 구성해둔 뒤 AI한테 해당 명령어가 통과해야한다고 지시해주면 됩니다. 지시해주는 방법은 <code>.AI.md</code> 답변 참조하시면 됩니다.</p>
<p>3번 같은 경우, 저는 <code>.AI.md</code> 에 “어떤 라이브러리는 어떤 식으로 써야한다.” 이렇게 가르쳐줍니다.</p>
<pre><code class="lang-plaintext">
10. If you need to call mutating RPC methods, use the `useMutation` hook.

```ts
const createProject = xxxClient.createProject.useMutation();
```

11. If you need to call query RPC methods, use the `useQuery` hook.

```ts
const projects = xxxClient.listProjects.useQuery();
```

12. Include `locale: Locale` where `Locale` is `import { Locale } from "@/i18n";` in the params of the page components.
13. Define the params as `Promise&lt;T&gt;` in the page components.
14. Use `use(params)` to unwrap the params as `T` from `Promise&lt;T&gt;` in the page components.
</code></pre>
<p>제가 실제로 사용중인 <code>.AIㅅ.md</code>에서 발췌한 내용입니다. 이런 식으로 가르쳐주면 잘 사용합니다.</p>
<blockquote>
<p>커서, 윈드서프, 클로드 cline등 ai 서비스가 많은데, 어떤 서비스 사용 빈도가 가장 높고, 상황별로 특별히 선호하는 서비스가 있는지?</p>
</blockquote>
<p>토크쇼에서 얘기했습니다.</p>
<blockquote>
<p>AI을 활용해서 개발을 진행할때 같은 문제가 반복된다면 어떤 조치를 취하시는지 알고싶습니다</p>
</blockquote>
<p>중간에 개입하거나 프롬프트를 바꿔서 재시도합니다. 그리고 잘못된 코드를 짜는 경우엔 매 과정마다 테스트를 돌리라고 시킵니다.</p>
<blockquote>
<p>어떤 기능 구현에 대한 로직 초안, 에러 원인 추정 등 여러가지 상황이 있는데 각각에 적합한 질문법과 특화된 AI 툴이 있는지 궁금합니다!</p>
</blockquote>
<p>따로 구분할 필요 없이 커서나 Roo Cline 모델을 <code>claude-3.7-sonnet-thinking</code>로 설정하시고 해달라고 하면됩니다. 이 모델이 생각보다 똑똑해서 상황 구분할 필요 없이 디버깅 요청이든 뭐든 프롬프트로 요청만 하면 됩니다. 테스트 고쳐달라고 하면 자기가 테스트에 dump용 로그 메시지 추가해서 돌린 뒤 디버깅하고 에러 잡은 뒤에 해당 코드 다시 지우는 수준의 작업까지 합니다. 근데 프롬프트에 테스트를 수정하지 말라고 해야합니다. 안 그러면 디버깅하다가 잘 안되면 테스트의 expected 값을 바꿔서 테스트가 통과하게 합니다.</p>
<blockquote>
<p>"3년 전 - 현재 - 3년 후" 개발 조직 구성과 조직 협업 방식이 어떻게 변해왔고, 어떻게 변해갈까요? 어떤 것을 주로 떠올리실지 궁금합니다. AI 어시스턴트 수준이 계속 높아지는데, 업무 협업 방식도 많이 변해갈 것 같아서 질문 남깁니다! 실력도 실력이지만 여전히 사람이 잘해야만 하는 면을 잘 길러둬야, 협업하기 좋은 인재로 성장할/시킬 수 있을 거라 생각해서요!</p>
</blockquote>
<p>백엔드/프론트엔드 같은 구분은 없어지고 혼자서 다 하게 될 가능성이 높다고 생각합니다. 그래도 혼자서 회사를 운영하는 것이 아니라면 기본적인 협업능력은 필수일 것입니다. 근데 협업이 이제 백엔드-프론트엔드 같은 방식은 아닐 것입니다. 업무를 나누는 방식이 달라질텐데, 혼자서 업무범위 전체를 AI를 이용해서 짧은 시간에 구현할 줄 알아야 할 것 같습니다. 즉, AI 활용 능력을 키우는 게 가장 바람직해 보입니다.</p>
<blockquote>
<p>질문이 쌓이다보면 계속 같은 말은 반복하거나, 원하는 흐름에서 벗어나는 경우가 많아요<br />어떻게 질문을 쌓아가는게 좋은지</p>
</blockquote>
<p>그런 경우 질문들을 모아서 새 챗을 만들고 첫 프롬프트로 전부 넘기시면 됩니다. 내용만 모아주는 게 가장 낫지만 귀찮으시다면 질문 형태로 그대로 복붙하셔도 작동은 합니다. 보여드린 SWC의 점프 테이블 작업이 그런 예시입니다. AI가 자꾸 이상한 행동을 하길래 저도 점프 테이블에 관련된 요구사항을 상세히 던져준 것입니다.</p>
<p>참고로 그 작업 같은 경우 AI가 제가 원하는 방식대로 구현 안 한 이유가 있었습니다. 벤치마크 결과 잘못된 최적화였습니다.</p>
<blockquote>
<p>AI 연계 에디터(예: 커서) 사용여부와 AI의 코드 접근에 대한 기준을 어떻게 잡고 있는지 궁금합니다.</p>
</blockquote>
<p>앞의 질문은 토크쇼에서 얘기했습니다. 접근 기준 같은 경우 SWC나 next.js는 오픈소스라서 거의 신경을 쓸 일이 없고요, 비공개 프로젝트 같은 경우엔 리텐션 기능을 활용하고, <code>.rooignore</code> 같은 파일이나 vscode의 ignore 기능도 사용합니다.</p>
<blockquote>
<p>AI를 사용해서 멍청해지는 듯한 느낌을 받은 적이 있나요?</p>
</blockquote>
<p>멍청해진다는 느낌은 받은 적 없고 게을러졌다는 느낌은 받은 적 많습니다. 장난으로 멍청해졌다 이런 얘기는 가끔 하는데, 저는 어지간한 것들 여전히 다 구현할 수 있습니다. 그래도 빡센 구현은 옛날보다 시간이 더 걸리긴 할 것 같습니다.</p>
]]></content:encoded></item></channel></rss>