<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Simple is Best.</title>
    <link>https://super-son.tistory.com/</link>
    <description>어제보다 나은 오늘</description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 22:20:16 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Super-Son</managingEditor>
    <image>
      <title>Simple is Best.</title>
      <url>https://tistory1.daumcdn.net/tistory/7067328/attach/eb5625cbc22743548c54a6310cb60b46</url>
      <link>https://super-son.tistory.com</link>
    </image>
    <item>
      <title>[AI Agent] Fable 5와 유사한 에이전트 지침 만들어보기</title>
      <link>https://super-son.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 &lt;b&gt;Fable 5를 사용해 다른 모델로도 Fable 5처럼 사용할 수 있는 AI 에이전트 지침을 만드는 시도&lt;/b&gt;를 정리해 보려고 합니다. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Fable 5가 성능이 워낙 좋다는 소식에 Fable 5가 너무 비싸니까 비슷한 걸 지침으로 만들 수 있을까? 라고 생각하고 시작했었습니다. 결론적으로 동일하게 동작하는 지침을 만드는 건 실패했지만, &lt;/span&gt;&lt;b&gt;기존에 사용하던 지침보다는 더 일을 잘하는 지침을 만드는 건 성공했습니다. (글 마지막 github link 첨부)&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Fable 5와 유사하게 만들기 위해 사용한 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Fable 5에게 '다른 모델을 사용해도 Fable 5처럼 동작하는 지침을 만들어줘.'라고 요청했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;1834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgva3c/dJMcaaeXbRW/o0XnuTLLESjBVznfVInWV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgva3c/dJMcaaeXbRW/o0XnuTLLESjBVznfVInWV1/img.png&quot; data-alt=&quot;Claude chat history&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgva3c/dJMcaaeXbRW/o0XnuTLLESjBVznfVInWV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgva3c%2FdJMcaaeXbRW%2Fo0XnuTLLESjBVznfVInWV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;920&quot; height=&quot;1834&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;1834&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Claude chat history&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/nDtno/dJMcage78Zk/buMnR8ARQ6YNWJmBaaiFq1/%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8_%EC%82%AC%EA%B3%A0%ED%96%89%EB%8F%99_%EC%A7%80%EC%B9%A8.md?attach=1&amp;amp;knm=tfile.md&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;에이전트_사고행동_지침.md&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fable 5가 세세한 절차 지시를 기입하지 않아도 잘 한다고 했으니 그대로 사용해봤습니다. 원하는 목표만 주고 나온 결과물을 'Fable 5처럼 동작하게 잘 구성됐는지' 피드백 및 평가를 요청해 개선했습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;Fable 5로 초안 작성
&amp;rarr; 부족한 부분 피드백
&amp;rarr; 지침 수정
&amp;rarr; 실제 작업 상황을 대입해 검토
&amp;rarr; 다시 피드백
&amp;rarr; 구조와 표현 개선
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;에이전트 지침의 핵심 구성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전하진&amp;nbsp;않지만&amp;nbsp;위와&amp;nbsp;같은&amp;nbsp;과정을&amp;nbsp;통해&amp;nbsp;완성한&amp;nbsp;지침은 목적과 예시를 제공하면 에이전트가 계획을 세우고 작업 및 검증까지 하도록 구현하는 것에 성공했습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지침의 주요 구성&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;핵심 원칙&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;목적 파악, 모호함 처리, 불확실성 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;작업 규율&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;범위 통제, 진행 상황 보고, 임의 수정 방지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;분석 프로토콜&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;샘플 검증, 행 수 추적, 집계 결과 역산&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;설계 프로토콜&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;요구사항, 제약 조건, 대안과 트레이드오프 기록&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Orchestrator&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;작업 분해, 위험도 판단, 실행 순서 계획&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Reviewer&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;작성자와 별도 관점에서 결과물 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Memory&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;프로젝트에서 반복되는 교훈 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;State&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;긴 작업의 단계와 검토 상태 기록&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모호함을 처리하는 기준&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트가 모든 애매한 내용을 사용자에게 질문하면 작업 속도가 너무 느려집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 전부 임의로 판단하게 하면 결과물이 잘못된 방향으로 진행될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 다음과 같이 지침이 만들어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가정이 틀렸을 때 결과물을 다시 만들어야 한다면 질문하고, 결과에 큰 영향이 없다면 합리적으로 가정한 뒤 가정 내용을 명시합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 날짜 컬럼이 생성일인지 수정일인지에 따라 분석 결과가 달라진다면 반드시 확인해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 출력 파일 이름처럼 결과의 본질에 영향을 주지 않는 내용은 기본값을 사용해도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기준을 넣은 뒤에는 에이전트가 불필요한 질문을 반복하거나, 중요한 내용을 마음대로 판단하는 문제가 줄어들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;확인된 사실과 추정 구분하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI의 가장 위험한 문제 중 하나는 확실하지 않은 내용을 자연스럽게 사실처럼 작성한다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 방지하기 위해 근거의 수준을 다음과 같이 구분했습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;확인됨&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;원본 파일이나 실행 결과로 직접 검증됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;추정&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;간접적인 근거를 바탕으로 판단함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;가정&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;작업 진행을 위해 기본값으로 선택함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;검증 필요&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;현재 자료만으로 확정할 수 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 파일을 수정했다고 보고하려면 실제로 파일이 저장되었는지 확인해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트가 통과했다고 말하려면 테스트 명령어를 실행한 결과가 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도구로 확인하지 않은 작업은 완료했다고 보고하지 않도록 지침에 명시했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작성자와 검토자 분리하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 기존에 사용하던 지침은 하나의 에이전트가 결과물을 만들고 스스로 다시 읽는 방식이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 에이전트가 자신이 만든 논리와 가정에 이미 영향을 받은 상태이기 때문에, 단순히 다시 읽는 것만으로는 문제를 찾기 어려워 다음과 같이 역할이 분리됐습니다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;Orchestrator
    &amp;darr;
Worker
    &amp;darr;
Reviewer
    &amp;darr;
수정 필요 여부 판단
    &amp;darr;
Worker 재작업
    &amp;darr;
Reviewer 재검증
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 실제 작업의 전체 흐름은 메인 에이전트가 관리합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Orchestrator:&lt;/b&gt; 작업 분해와 실행 계획을 제안&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Worker:&lt;/b&gt; 실제 분석, 코드 작성, 문서 작성 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reviewer:&lt;/b&gt; 결과물만 보고 오류와 누락 검토&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메인 에이전트:&lt;/b&gt; 검토 결과에 따라 수정과 재검증 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reviewer는 단순히 문장을 자연스럽게 고치는 역할이 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 관점으로 결과물을 공격적으로 검토하도록 구성했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청사항을 모두 충족했는가?&lt;/li&gt;
&lt;li&gt;결론이 근거에서 실제로 도출되는가?&lt;/li&gt;
&lt;li&gt;수치와 행 수가 서로 모순되지 않는가?&lt;/li&gt;
&lt;li&gt;추정이나 가정을 사실처럼 표현하지 않았는가?&lt;/li&gt;
&lt;li&gt;요청하지 않은 범위까지 수정하지 않았는가?&lt;/li&gt;
&lt;li&gt;이 결론을 반박할 수 있는 사례는 없는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;대규모 분석을 위한 검증 절차&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 주로 데이터 분석에 에이전트를 사용하는데, 기존에는 에이전트가 작업한 결과물에 대해서 실제로 결과에 문제가 없는지 검수하는 데 시간을 오래 사용했었습니다. 특히 많은 데이터를 한 번에 처리하면 중간 과정에서 발생한 오류를 찾기 어려웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들어진 지침에서는 다음과 같은 절차를 기본 원칙으로 넣어 기본적인 검수를 에이전트가 하도록 구현됐습니다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;전체 데이터 구조 확인
&amp;rarr; 소규모 샘플로 로직 검증
&amp;rarr; 처리 단계별 행 수 기록
&amp;rarr; 전체 데이터에 적용
&amp;rarr; 집계 결과를 원본 데이터로 역추적
&amp;rarr; 이상 여부 확인
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 데이터가 다음과 같이 변했다면 각 단계의 원인을 확인합니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;원본 데이터: 100,000행
필터 적용 후: 82,000행
조인 후: 125,000행
중복 제거 후: 81,500행
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조인 후 행 수가 예상보다 늘어났다면 바로 다음 작업으로 넘어가는 것이 아니라, 조인 키의 중복이나 다대다 관계를 먼저 확인합니다. 이런 검증 절차로 속도는 조금 줄었지만, 잘못된 분석 결과를 에이전트가 1차로 먼저 잡아냈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Cursor와 Claude Code에 적용한 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만든 지침은 하나의 문서로만 관리하지 않고, Cursor와 Claude Code에서 각각 사용할 수 있도록 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 주로 Cursor로만 작업을 하는데 주변에는 Claude Code를 쓰는 사람들도 많아서 둘다 만들었습니다.&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;agent-thinking-guidelines/
├── docs/
│   ├── agent-thinking-guidelines.md
│   ├── agent-system-overview.md
│   └── multi-agent-orchestration.md
├── cursor/
│   ├── .cursor/rules/
│   ├── .cursor/skills/
│   ├── .cursor/agents/
│   ├── .cursor/memory/
│   └── .cursor/state/
└── claude/
    ├── CLAUDE.md
    ├── skills/
    ├── agents/
    ├── .claude/memory/
    └── .claude/state/
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docs/를 원본 지침으로 사용하고, 해당 내용을 Cursor와 Claude Code의 규칙 체계에 맞게 각각 변환했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 역할CursorClaude Code&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;핵심 원칙&lt;/td&gt;
&lt;td&gt;.cursor/rules/*.mdc&lt;/td&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;상황별 프로토콜&lt;/td&gt;
&lt;td&gt;.cursor/skills/&lt;/td&gt;
&lt;td&gt;.claude/skills/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서브에이전트&lt;/td&gt;
&lt;td&gt;.cursor/agents/&lt;/td&gt;
&lt;td&gt;.claude/agents/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;프로젝트 기억&lt;/td&gt;
&lt;td&gt;.cursor/memory/&lt;/td&gt;
&lt;td&gt;.claude/memory/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;작업 상태&lt;/td&gt;
&lt;td&gt;.cursor/state/&lt;/td&gt;
&lt;td&gt;.claude/state/&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 구성한 이유는 도구별 파일 구조는 달라도, 에이전트가 따라야 하는 핵심 원칙은 하나의 원본에서 관리하기 위해서입니다. 한쪽 지침만 수정하고 다른 쪽을 놓치지 않도록 docs/를 SSOT(Single Source of Truth)로 사용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;세션 간 기억을 추가한 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI와 작업하다 보면 이전 세션에서 이미 해결한 문제를 다음 세션에서 다시 설명해야 하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 줄이기 위해 프로젝트에서 반복되는 교훈을 파일로 저장하도록 구성했습니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;.cursor/memory/
└── timestamp-column.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 내용은 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;요약: created_at은 데이터 생성일이 아니라 동기화 시점이므로 기간 분석 기준으로 사용하지 않습니다.

프로젝트의 기간 분석에서는 service_date를 기준으로 사용합니다.
created_at은 적재 및 동기화 상태를 확인하는 용도로만 사용합니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리는 한 파일에 모든 내용을 누적하지 않고, &lt;b&gt;한 가지 교훈을 하나의 파일로 관리&lt;/b&gt;하도록 했습니다. 세션 시작 시 모든 파일의 본문을 읽는 대신 첫 번째 요약 문장만 확인하고, 현재 작업과 관련된 메모만 자세히 읽게 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;직접 사용해 본 후기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재까지 사용해 본 결과는 만족스럽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 크게 달라진 부분은 결과물 뿐만 아니라 &lt;b&gt;작업 설계 편의성과 작업 과정의 안정성, 그리고 가성비&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;설계 편의성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;세세하게 지시하지 않고 작업 목표만 줘도 설계를 하고 애매한 건 물어봄&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안정성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애매한 내용을 임의로 채우는 경우가 줄어듦&lt;/li&gt;
&lt;li&gt;작업 범위를 벗어난 수정이 줄어듦&lt;/li&gt;
&lt;li&gt;긴 작업에서도 현재 단계와 남은 작업을 확인하기 쉬워짐&lt;/li&gt;
&lt;li&gt;데이터 분석 결과를 한 번 더 검증하는 흐름이 생김&lt;/li&gt;
&lt;li&gt;완료했다고 보고한 내용과 실제 작업 결과가 비교적 잘 일치함&lt;/li&gt;
&lt;li&gt;수정 요청 시 처음부터 다시 만드는 일이 줄어듦&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;가성비&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Composer 2.5로도 충분히 만족스러운 결과가 나옴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Fable 5와 같게 만들 수 있었는가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 &lt;b&gt;Fable 5와 완전히 같게 만드는 것은 불가능했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지침을 잘 작성한다고 해서 모델 자체의 추론 능력이나 판단 능력이 올라가는 것은 아니기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지침으로 개선할 수 있는 것은 주로 다음과 같은 행동 패턴입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업 전 요구사항 확인&lt;/li&gt;
&lt;li&gt;모호함을 처리하는 방식&lt;/li&gt;
&lt;li&gt;검증 절차 수행&lt;/li&gt;
&lt;li&gt;불확실성 표시&lt;/li&gt;
&lt;li&gt;작업 범위 통제&lt;/li&gt;
&lt;li&gt;결과물 자체 검토&lt;/li&gt;
&lt;li&gt;진행 상황과 오류 보고&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 다음과 같은 부분은 사용하는 모델의 성능에 영향을 많이 받습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 문제를 분해하는 능력&lt;/li&gt;
&lt;li&gt;긴 문맥을 유지하는 능력&lt;/li&gt;
&lt;li&gt;미묘한 오류를 발견하는 능력&lt;/li&gt;
&lt;li&gt;새로운 상황에 규칙을 적절히 적용하는 능력&lt;/li&gt;
&lt;li&gt;여러 도구와 에이전트를 안정적으로 조율하는 능력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이번 지침은 Fable 5를 복제한 결과물이라기보다는, &lt;b&gt;Fable 5에서 만족스러웠던 작업 방식을 일반적인 에이전트 환경에 적용해 본 결과물&lt;/b&gt;에 가깝습니다. 완전히 동일하지는 않지만, 제가 원했던 방향에는 어느 정도 유사하게 만들어진 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-end=&quot;5218&quot; data-start=&quot;5110&quot; data-ke-size=&quot;size16&quot;&gt;Fable 5와 완전히 같게 만들 수는 없었지만, &lt;b&gt;Fable 5로 초안을 만들고 피드백과 개선을 반복하면서 그나마 유사한 방향으로 다듬어 본 결과&lt;/b&gt; 현재는 꽤 만족스럽게 사용하고 있습니다. 앞으로 사용해보면서 지속적으로 개선해볼 생각입니다.&lt;/p&gt;
&lt;p data-end=&quot;5287&quot; data-start=&quot;5220&quot; data-ke-size=&quot;size16&quot;&gt;에이전트 지침으로 뭘 써야하나 이것저것 테스트해보시거나, 직접 만들어보려고 시도 중이신 분들에게 도움이 되면 좋을 것 같습니다. 감사합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5418&quot; data-start=&quot;5311&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5418&quot; data-start=&quot;5311&quot; data-section-id=&quot;1a4y926&quot;&gt;GitHub: &lt;a href=&quot;https://github.com/geunsu-son/agent-thinking-guidelines&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/geunsu-son/agent-thinking-guidelines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Study/AI</category>
      <category>Agent</category>
      <category>fable5</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/115</guid>
      <comments>https://super-son.tistory.com/115#entry115comment</comments>
      <pubDate>Mon, 13 Jul 2026 00:35:15 +0900</pubDate>
    </item>
    <item>
      <title>[Cursor] 실사용 내역 기준 모델 비용 분석 (feat. Composer 2.5 Fast 끄기)</title>
      <link>https://super-son.tistory.com/114</link>
      <description>&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;Cursor를 업무에 쓰면서 모델을 선택하고 사용하는데 크게 생각하지 않았었는데 최근 Opus 4.8가 발표된 뒤 사용해보다가, 이번에 비용이 크게 나왔으니 원인 보고를 하도록 지시를 받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 5월 초부터 6월 말까지 2개월 치의 토큰 사용량을 확인했는데 이벤트는 900건이 조금 넘었으며 토큰은 대략 6억 3천만 정도였습니다. 이번 사용 내역을 분석해보면서 생각한 것과 그래서 앞으로 저는 어떻게 쓸지를 정리해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;처음엔 그냥 골라 썼습니다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 Auto, Composer, Opus가 각각 뭔지 잘 모른 채로, 필요할 때마다 그냥 골라가며 썼습니다. 새로 나왔다고 하면 써보고, 대규모 작업에 좋다고 하면 좋겠거니 하고 고르는 식이었습니다. 그래서 비용이 나중에야 눈에 들어왔습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;숫자가 말해 준 것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 내역을 모델별로 나눠 보니, 토큰 대비 비용이 아래처럼 나왔습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;모델&lt;/td&gt;
&lt;td&gt;이벤트&lt;/td&gt;
&lt;td&gt;토큰 비중&lt;/td&gt;
&lt;td&gt;On-Demand&lt;/td&gt;
&lt;td&gt;1M 토큰당 비용&lt;/td&gt;
&lt;td&gt;이벤트당 평균 토큰&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Opus 4.8&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;201&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;47%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;$298.60 (79%)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$1.24&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;1.53M&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;auto&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;508&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;35%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$36.67 (10%)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;b&gt;$0.36&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;0.67M&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;composer-2.5-fast&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;191&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;17%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$44.45 (12%)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$1.05&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;0.78M&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 수는 Auto가 더 많았는데, 토큰의 절반 가까이와 On-Demand 비용의 약 80%는 Opus에서 나왔습니다.&lt;br /&gt;Auto는 건수도 많고 1M 토큰당 비용도 &lt;b&gt;$0.36&lt;/b&gt;으로 가장 낮았습니다. 반면 composer-2.5-fast는 1M 토큰당 &lt;b&gt;$1.05&lt;/b&gt;로, Auto보다 토큰 대비 비용이 꽤 높았습니다. Composer 2.5가 저렴하다고 생각해서 사용했는데 왜 이렇게 비용이 크게 나왔는지를 확인해보니 Fast Mode를 쓰면 Standard Mode 보다 6배정보 비싸더라구요..?   (&lt;a href=&quot;https://cursor.com/ko/changelog/composer-2-5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 모델의 문제는 아니었겠으나 기본적으로 모델 비용이 비싼걸 사용하면 비용이 눈에 띄게 차이가 난다는걸 깨달았습니다. 애초에 비용이 10배 차이였으니 말해뭐해...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx1RMT/dJMcabrlhiB/BOpkPkhAxHpQNm7V4rtKk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx1RMT/dJMcabrlhiB/BOpkPkhAxHpQNm7V4rtKk0/img.png&quot; data-alt=&quot;Cursor Docs: https://cursor.com/ko/docs/models-and-pricing&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx1RMT/dJMcabrlhiB/BOpkPkhAxHpQNm7V4rtKk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx1RMT%2FdJMcabrlhiB%2FBOpkPkhAxHpQNm7V4rtKk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;583&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cursor Docs: https://cursor.com/ko/docs/models-and-pricing&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;지금은 이렇게 씁니다.&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대부분의 작업은 Auto&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일상적인 SQL 작성&amp;middot;검수, ETL 점검, Git&amp;middot;PR, 짧은 수정은 거의 Auto만 둡니다. 생각보다 Agent 구현도 Auto에 맡겨 두면 Composer 쪽으로 라우팅되는 경우가 많았습니다. &amp;ldquo;구현이니까 무조건 Composer&amp;rdquo;로 시작하지 않아도 되는 날이 더 많았습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;에이전트를 복잡하게 사용할건데 싸게 쓰고 싶으면 Composer 2.5&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent로 파일을 오래 만지거나, Auto 라우팅에만 맡기기 애매할 때입니다. &lt;b&gt;(Standard 기준입니다.) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본값이 Fast으로 되어있어서 별도로 변경해줘야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMH94f/dJMcacjqovB/RaoNPVxVkSekhkem1viwh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMH94f/dJMcacjqovB/RaoNPVxVkSekhkem1viwh0/img.png&quot; data-alt=&quot;Composer 2.5 Fast 끄는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMH94f/dJMcacjqovB/RaoNPVxVkSekhkem1viwh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMH94f%2FdJMcacjqovB%2FRaoNPVxVkSekhkem1viwh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;311&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Composer 2.5 Fast 끄는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Composer 2.5의 성능이 제 기준에서는 매우 만족스러워서 굳이 다른 모델을 고르지는 않고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 분석한 결과와 사용하는 방법이 완벽하다고 할 수는 없습니다. 업무 종류와 요금제, Cursor 버전마다 체감이 다를 수 있습니다. 그래도 혹시 모델을 뭘 써야 하는지 고민하는 분들에게 도움이 되면 좋겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>Study/IDE</category>
      <category>ai</category>
      <category>composer2.5</category>
      <category>cursor</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/114</guid>
      <comments>https://super-son.tistory.com/114#entry114comment</comments>
      <pubDate>Fri, 10 Jul 2026 00:44:47 +0900</pubDate>
    </item>
    <item>
      <title>[tmux] 내가 나중에 보려고 정리한 주요 단축키 및 사용법</title>
      <link>https://super-son.tistory.com/112</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 오늘은 &lt;b&gt;tmux(Terminal Multiplexer)&lt;/b&gt; 사용법과 주요 단축키에 대한 정리 글입니다. 서버에서 장시간 스크립트를 실행하거나, SSH 접속이 끊겨도 작업을 유지하고 싶을 때 tmux를 쓰면 편하다는 추천을 받았습니다만, 단축키가 익숙해지기 전까지는 계속 사용해버릇해야 될 것 같아 언제든 찾아볼 수 있게 주로 사용하는 단축키만&amp;nbsp;골라 정리해 보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;tmux란 무엇이며 왜 쓰는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmux는 하나의 터미널 안에서 여러 작업 공간을 만들고, 그 작업을 &lt;b&gt;백그라운드에 계속 유지&lt;/b&gt;할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;용도:&lt;/b&gt; 서버에서 장시간 실행되는 스크립트, 크롤러, 자동매매 봇, 백테스트 등을 돌리거나, 터미널 화면을 분할해서 쓰고 싶을 때 유용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Prefix(접두어):&lt;/b&gt; tmux 명령의 시작은 &lt;b&gt;[Ctrl + b]&lt;/b&gt;입니다. 이 키를 먼저 누르고 손을 뗀 다음, 다른 키를 입력하는 방식인데, 익숙해지려면 자주 사용해 봐야겠습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주의:&lt;/b&gt; window OS는 WSL 로만 사용 가능하다고 합니다. (제가 잘 모르는 걸 수도 있지만...)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;세션(Session) 관리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션은 tmux 작업 공간의 전체 단위입니다. 세션 이름을 지정해 관리하는 것이 나중에 찾기 훨씬 수월합니다.&lt;/p&gt;
&lt;table style=&quot;height: 121px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;th style=&quot;height: 21px;&quot; align=&quot;left&quot;&gt;작업&lt;/th&gt;
&lt;th style=&quot;height: 21px;&quot; align=&quot;left&quot;&gt;명령어 / 단축키&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;새 세션 생성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;code&gt;tmux new -s [세션명]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;세션 목록 확인&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;code&gt;tmux ls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;세션 밖으로 나가기 (Detach)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[d]&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;기존 세션 재접속 (Attach)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;code&gt;tmux a -t [세션명]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;b&gt;특정 세션 종료&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot; align=&quot;left&quot;&gt;&lt;code&gt;tmux kill-session -t [세션명]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Detach&lt;/b&gt; 기능을 사용하면 터미널을 닫아도 서버 작업은 계속 살아있게 됩니다. 개인적으로는 이것이 tmux를 쓰는 가장 중요한 이유라고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;윈도우(Window)와 패널(Pane) 단축키&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 세션 안에서 탭(Window)을 나누거나, 화면(Pane)을 분할할 때 사용하는 단축키입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;윈도우(Window) - 브라우저 탭 개념&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;새 윈도우 생성:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[c]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다음/이전 윈도우 이동:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[n]&lt;/b&gt; / &lt;b&gt;[p]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;윈도우 이름 변경:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[,]&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;패널(Pane) - 화면 분할 개념&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;좌우 분할:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[%]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;위아래 분할:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[&quot;]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;패널 간 이동:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[방향키]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;패널 전체 화면/복귀:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[z]&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;스크롤 모드 및 실전 팁&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmux 안에서는 마우스 스크롤이 바로 되지 않을 수 있습니다. 이때는 아래 모드를 활용하면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스크롤 모드 진입:&lt;/b&gt; &lt;b&gt;[Ctrl + b]&lt;/b&gt; &amp;rarr; &lt;b&gt;[[]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스크롤 모드 종료:&lt;/b&gt; &lt;b&gt;[q]&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로는 아래 흐름만 익혀도 충분히 자주 사용할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;haxe&quot;&gt;&lt;code&gt;tmux new -s work&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어로 세션을 열고 작업을 시작합니다.&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;python main.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을 돌려둔 뒤에는 아래 단축키로 세션 밖으로 빠져나옵니다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;Ctrl + b &amp;rarr; d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 다시 확인하고 싶을 때는 아래 명령어로 접속합니다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;tmux a -t work&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 단축키가 낯설지만, 위의 &lt;b&gt;최소 암기 세트&lt;/b&gt;만 익혀도 웬만한 서버 작업은 충분히 가능합니다. 저처럼 단축키를 자주 잊어버리는 분들께 이 정리 글이 도움이 되었으면 좋겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 기능을 사용하는 분들께 도움이 되면 좋겠습니다. 감사합니다.&lt;/p&gt;</description>
      <category>Study</category>
      <category>tmux</category>
      <category>단축키</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/112</guid>
      <comments>https://super-son.tistory.com/112#entry112comment</comments>
      <pubDate>Sun, 28 Jun 2026 15:34:25 +0900</pubDate>
    </item>
    <item>
      <title>[python] 디버깅 방법 정리 (try~except, raise, from e)</title>
      <link>https://super-son.tistory.com/111</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬으로 작업하다 보면 &lt;code&gt;try~except&lt;/code&gt;를 자주 사용하게 된다. 에러가 발생하더라도 전체 작업이 중단되지 않게 하기 위해서인데, 문제는 이걸 여기저기 덕지덕지 사용하다 보니 나중에 디버깅을 할 때 &lt;b&gt;도대체 어디서 문제가 생겼는지 한 번에 파악하기가 어려워졌다는 점&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 내가 실제로 겪었던 방식들을 기준으로, 디버깅 과정에 조금이나마 도움이 되었던 예외 처리 방법을 정리해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;try~except + print(e)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러가 발생해도 코드는 계속 동작하게 두고, 어떤 에러가 발생했는지만 로그로 남기는 방법이다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;def convert_to_int(value):
    try:
        return int(value)
    except ValueError as e:
        print(e)
        return None&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768742675968&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 출력 예시
invalid literal for int() with base 10: 'abc'
# 함수 정상 종료&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 흐름이 끊기지 않는다.&lt;/li&gt;
&lt;li&gt;콘솔 로그를 통해 에러 원인을 바로 확인할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수 실패 여부를 놓치지 쉽다. (함수 정상 리턴)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;try~except + raise, from e&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 흐름에 치명적인 문제가 발생할 여지가 있는 경우 예외를 발생시켜 실패시키는 방법이다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;def convert_to_int(value):
    try:
        return int(value)
    except ValueError as e:
        raise RuntimeError(&quot;숫자 변환 실패&quot;) from e&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768742639634&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 출력 예시 - from e 미사용
Traceback (most recent call last):
  File &quot;example.py&quot;, line 12, in &amp;lt;module&amp;gt;
    convert_to_int(&quot;abc&quot;)
  File &quot;example.py&quot;, line 8, in convert_to_int
    raise RuntimeError(&quot;숫자 변환 실패&quot;)
RuntimeError: 숫자 변환 실패


# 출력 예시 - from e 사용
Traceback (most recent call last):
  File &quot;example.py&quot;, line 6, in convert_to_int
    int(&quot;abc&quot;)
ValueError: invalid literal for int() with base 10: 'abc'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File &quot;example.py&quot;, line 12, in &amp;lt;module&amp;gt;
    convert_to_int(&quot;abc&quot;)
  File &quot;example.py&quot;, line 8, in convert_to_int
    raise RuntimeError(&quot;숫자 변환 실패&quot;) from e
RuntimeError: 숫자 변환 실패&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 지점에서 코드 흐름이 명확하게 중단되고&lt;/li&gt;
&lt;li&gt;호출한 쪽에서도 &amp;ldquo;이건 실패한 작업이다&amp;rdquo;라는 걸 바로 알 수 있다.&lt;/li&gt;
&lt;li&gt;from e 덕분에 실제 원인이 된 에러(ValueError)도 함께 남는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 코드가 완전히 끝나야 하는 경우에는 적합하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Python</category>
      <category>from e</category>
      <category>python</category>
      <category>Raise</category>
      <category>try~except</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/111</guid>
      <comments>https://super-son.tistory.com/111#entry111comment</comments>
      <pubDate>Sun, 18 Jan 2026 22:27:12 +0900</pubDate>
    </item>
    <item>
      <title>[Python] raise를 활용해 의도적으로 예외 처리하기</title>
      <link>https://super-son.tistory.com/110</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬으로 작업하던 중 &amp;ldquo;이 상황에서는 그냥 진행하면 안 되는데&amp;hellip;&amp;rdquo; 싶은 순간에 의도적으로 에러를 발생시키는 게 필요해져서 알아보니 &lt;code&gt;raise&lt;/code&gt;라는 문법을 발견했다. 이번 글에서는 &lt;code&gt;raise&lt;/code&gt;의 사용 예시와 상황에 맞는 예외들을 정리해봤다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;raise는 언제 쓰는 게 좋을까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;raise&lt;/code&gt;는 &lt;b&gt;&amp;ldquo;이 상태는 정상 흐름이 아니다&amp;rdquo;&lt;/b&gt; 라는 것을 코드로 명확히 표현할 수 있는 방법이다.&lt;br /&gt;입력값이 잘못됐거나, 필수 데이터가 없거나, 더 이상 처리를 진행하면 안 되는 경우에 특히 유용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;raise 사용 예시&lt;/h4&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;def validate_age(age):
    if age &amp;lt; 0:
        raise ValueError(&quot;나이는 0 이상이어야 합니다.&quot;)
    if age &amp;gt; 150:
        raise ValueError(&quot;나이는 150 이하여야 합니다.&quot;)
    return age&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 만족하지 않으면 즉시 &lt;code&gt;ValueError&lt;/code&gt;를 발생시켜 함수 실행을 중단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;try:
    validate_age(-5)
except ValueError as e:
    print(e)
    raise&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;except&lt;/code&gt;에서 로그만 남기고 다시 &lt;code&gt;raise&lt;/code&gt; 하면, 에러 메시지를 유지한 채 프로그램을 종료할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;상황에 맞는 예외 타입 선택하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;raise&lt;/code&gt;를 쓰면서 느낀 점은 &lt;b&gt;예외 타입 자체가 설명서 역할&lt;/b&gt;을 한다는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;값이 잘못된 경우 &amp;rarr; &lt;code&gt;ValueError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;타입이 다른 경우 &amp;rarr; &lt;code&gt;TypeError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;딕셔너리 키 누락 &amp;rarr; &lt;code&gt;KeyError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;리스트 범위 초과 &amp;rarr; &lt;code&gt;IndexError&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;파일 문제 &amp;rarr; &lt;code&gt;FileNotFoundError&lt;/code&gt;, &lt;code&gt;PermissionError&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외 타입과 메시지만 봐도 어떤 문제가 발생했는지 바로 파악할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실전 활용 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ETL 과정에 아래와 같은 검증용 매서드를 정의하여 이후 문제가 되는 상황을 잘 잡아냈었다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;def validate_dataframe(df, required_columns=None):
    if df is None:
        raise ValueError(&quot;입력 데이터가 None입니다.&quot;)

    if not isinstance(df, pd.DataFrame):
        raise TypeError(&quot;DataFrame이 필요합니다.&quot;)

    if df.empty:
        raise ValueError(&quot;데이터프레임이 비어있습니다.&quot;)

    if required_columns:
        missing = [c for c in required_columns if c not in df.columns]
        if missing:
            raise KeyError(f&quot;필수 컬럼 누락: {missing}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 평소 if, print를 사용해서 문제가 되는 부분들을 다 찍어보면서 처리했었는데 &lt;code&gt;raise&lt;/code&gt;를 사용하면서 횟수가 상대적으로 줄어들었었습니다. 처음 &lt;code&gt;raise&lt;/code&gt;를 알게 된 분들에게 도움이 되었길 바랍니다.&lt;/p&gt;</description>
      <category>Study/Python</category>
      <category>python</category>
      <category>Raise</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/110</guid>
      <comments>https://super-son.tistory.com/110#entry110comment</comments>
      <pubDate>Sun, 18 Jan 2026 21:56:38 +0900</pubDate>
    </item>
    <item>
      <title>[Cursor] Possible Fixes to Try When Jupyter Kernel Errors Occur After the Agent Update</title>
      <link>https://super-son.tistory.com/109</link>
      <description>&lt;p data-end=&quot;182&quot; data-start=&quot;157&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;* Translated by ChatGPT&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;184&quot; data-ke-size=&quot;size16&quot;&gt;It&amp;rsquo;s been over half a year since I switched from VSCode to Cursor. Although Cursor is still slightly less stable compared to VSCode at times, I&amp;rsquo;ve generally been quite satisfied with it. However, after the agent feature update in early November, &lt;b&gt;I ran into an issue where the Jupyter Notebook kernel stopped being recognized.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;184&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;833&quot; data-start=&quot;515&quot; data-ke-size=&quot;size16&quot;&gt;It turned out I wasn&amp;rsquo;t the only one experiencing this &amp;mdash; &lt;b&gt;there was a bug report on the Cursor Forum&lt;/b&gt;, and the suggested workaround was to reinstall an older version. I followed that for a while, but recently I stumbled upon a simple attempt that surprisingly resolved the issue. It was almost nothing&amp;hellip; yet it worked.&lt;/p&gt;
&lt;figure id=&quot;og_1763710436615&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kernel Selection doesn't work&quot; data-og-description=&quot;Where does the bug appear (feature/product)? Cursor IDE Describe the Bug I cannot select any of my Kernels for my Jupyter notebook. In vs studio code it is working. It may be a problem with the extension Python Environments, which cannot be installed in th&quot; data-og-host=&quot;forum.cursor.com&quot; data-og-source-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; data-og-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLrulB/hyZOf3K6q2/4lRvlhSNAQ71emIfkfVlx1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/bE0LgB/hyZOghhAFR/oYjBLxHfZYb7BNVmh0zI00/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500&quot;&gt;&lt;a href=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLrulB/hyZOf3K6q2/4lRvlhSNAQ71emIfkfVlx1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/bE0LgB/hyZOghhAFR/oYjBLxHfZYb7BNVmh0zI00/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kernel Selection doesn't work&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Where does the bug appear (feature/product)? Cursor IDE Describe the Bug I cannot select any of my Kernels for my Jupyter notebook. In vs studio code it is working. It may be a problem with the extension Python Environments, which cannot be installed in th&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;forum.cursor.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-end=&quot;833&quot; data-start=&quot;515&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;897&quot; data-start=&quot;840&quot; data-ke-size=&quot;size23&quot;&gt;Reinstalling the Jupyter extension fixed it (somehow)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oOIp6/dJMcaajoE4o/pkVhDkhgiXNSK50L30yeH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oOIp6/dJMcaajoE4o/pkVhDkhgiXNSK50L30yeH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oOIp6/dJMcaajoE4o/pkVhDkhgiXNSK50L30yeH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoOIp6%2FdJMcaajoE4o%2FpkVhDkhgiXNSK50L30yeH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1365&quot; height=&quot;425&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1127&quot; data-start=&quot;913&quot; data-ke-size=&quot;size16&quot;&gt;For a moment, I genuinely considered switching back to VSCode, so I&amp;rsquo;m relieved that this resolved the issue. Since I haven&amp;rsquo;t tested this on other machines, &lt;b&gt;I can&amp;rsquo;t say for sure that this will work for everyone.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1127&quot; data-start=&quot;913&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1248&quot; data-start=&quot;1129&quot; data-ke-size=&quot;size16&quot;&gt;Still, I&amp;rsquo;m sharing this in hopes that it helps someone else who&amp;rsquo;s been struggling with Jupyter kernel issues on Cursor.&lt;/p&gt;
&lt;p data-end=&quot;1248&quot; data-start=&quot;1129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/IDE</category>
      <category>Bug</category>
      <category>cursor</category>
      <category>jupyternotebook</category>
      <category>Kernel</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/109</guid>
      <comments>https://super-son.tistory.com/109#entry109comment</comments>
      <pubDate>Fri, 21 Nov 2025 16:34:36 +0900</pubDate>
    </item>
    <item>
      <title>[Cursor] 에이전트 업데이트 후 주피터 커널 오류 발생 시 시도해볼만한 해결법</title>
      <link>https://super-son.tistory.com/108</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;VSCode에서&amp;nbsp;Cursor로&amp;nbsp;넘어온&amp;nbsp;지도&amp;nbsp;벌써&amp;nbsp;반년이&amp;nbsp;지났습니다.&amp;nbsp;아직은&amp;nbsp;VSCode에&amp;nbsp;비해&amp;nbsp;가끔&amp;nbsp;불안정한&amp;nbsp;모습을&amp;nbsp;보이지만,&amp;nbsp;개인적으로는&amp;nbsp;꽤&amp;nbsp;만족하며&amp;nbsp;잘&amp;nbsp;사용&amp;nbsp;중인데요.&amp;nbsp;그런데&amp;nbsp;11월&amp;nbsp;초&amp;nbsp;에이전트&amp;nbsp;기능이&amp;nbsp;업데이트된&amp;nbsp;이후로&amp;nbsp;주피터&amp;nbsp;노트북&amp;nbsp;커널이&amp;nbsp;인식되지&amp;nbsp;않는&amp;nbsp;문제가&amp;nbsp;발생했습니다. &lt;br /&gt;&lt;br /&gt;저만의&amp;nbsp;문제는&amp;nbsp;아니었는지&amp;nbsp;Cursor&amp;nbsp;포럼에도&amp;nbsp;동일한&amp;nbsp;버그&amp;nbsp;제보가&amp;nbsp;올라와&amp;nbsp;있었고,&amp;nbsp;임시&amp;nbsp;해결책으로는&amp;nbsp;&amp;ldquo;이전&amp;nbsp;버전을&amp;nbsp;다시&amp;nbsp;설치하라&amp;rdquo;는&amp;nbsp;조언이&amp;nbsp;있었습니다.&amp;nbsp;그래서&amp;nbsp;그동안은&amp;nbsp;그렇게&amp;nbsp;사용하고&amp;nbsp;있었는데,&amp;nbsp;최근&amp;nbsp;이것저것&amp;nbsp;만지다가&amp;nbsp;우연히&amp;nbsp;해결이&amp;nbsp;되어&amp;nbsp;기록을&amp;nbsp;남겨봅니다.&amp;nbsp;정말&amp;nbsp;별거&amp;nbsp;아닌&amp;nbsp;시도였는데&amp;hellip;&amp;nbsp;의외로&amp;nbsp;됐습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1763710029566&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Kernel Selection doesn't work&quot; data-og-description=&quot;Where does the bug appear (feature/product)? Cursor IDE Describe the Bug I cannot select any of my Kernels for my Jupyter notebook. In vs studio code it is working. It may be a problem with the extension Python Environments, which cannot be installed in th&quot; data-og-host=&quot;forum.cursor.com&quot; data-og-source-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; data-og-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLrulB/hyZOf3K6q2/4lRvlhSNAQ71emIfkfVlx1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/bE0LgB/hyZOghhAFR/oYjBLxHfZYb7BNVmh0zI00/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500&quot;&gt;&lt;a href=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://forum.cursor.com/t/kernel-selection-doesnt-work/140796&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLrulB/hyZOf3K6q2/4lRvlhSNAQ71emIfkfVlx1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/bE0LgB/hyZOghhAFR/oYjBLxHfZYb7BNVmh0zI00/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kernel Selection doesn't work&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Where does the bug appear (feature/product)? Cursor IDE Describe the Bug I cannot select any of my Kernels for my Jupyter notebook. In vs studio code it is working. It may be a problem with the extension Python Environments, which cannot be installed in th&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;forum.cursor.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;익스텐션에서 주피터를 다시 설치했더니 됐습니다. (?)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXJgO6/dJMcagqnALn/g0ahVwwteknlPuEm9dUwZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXJgO6/dJMcagqnALn/g0ahVwwteknlPuEm9dUwZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXJgO6/dJMcagqnALn/g0ahVwwteknlPuEm9dUwZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXJgO6%2FdJMcagqnALn%2Fg0ahVwwteknlPuEm9dUwZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1365&quot; height=&quot;425&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한때는&amp;nbsp;&amp;ldquo;다시&amp;nbsp;VSCode로&amp;nbsp;돌아가야&amp;nbsp;하나?&amp;rdquo;&amp;nbsp;싶을&amp;nbsp;정도로&amp;nbsp;불편했는데,&amp;nbsp;다행히&amp;nbsp;이렇게&amp;nbsp;간단히&amp;nbsp;해결돼서&amp;nbsp;마음이&amp;nbsp;놓였어요.&amp;nbsp;다만&amp;nbsp;다른&amp;nbsp;PC&amp;nbsp;환경에서는&amp;nbsp;테스트해보지&amp;nbsp;않아&amp;nbsp;이&amp;nbsp;방법이&amp;nbsp;보편적인&amp;nbsp;해결책이라고는&amp;nbsp;장담하기&amp;nbsp;어렵습니다. &lt;br /&gt;&lt;br /&gt;그래도&amp;nbsp;저처럼&amp;nbsp;Cursor에서&amp;nbsp;주피터&amp;nbsp;커널&amp;nbsp;인식&amp;nbsp;문제로&amp;nbsp;고생하는&amp;nbsp;분들이&amp;nbsp;계시다면,&amp;nbsp;조금이나마&amp;nbsp;도움이&amp;nbsp;되기를&amp;nbsp;바라며&amp;nbsp;글을&amp;nbsp;남깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/IDE</category>
      <category>오류</category>
      <category>주피터노트북</category>
      <category>커널</category>
      <category>커서</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/108</guid>
      <comments>https://super-son.tistory.com/108#entry108comment</comments>
      <pubDate>Fri, 21 Nov 2025 16:32:28 +0900</pubDate>
    </item>
    <item>
      <title>[Pandas] Series.get(key, default)</title>
      <link>https://super-son.tistory.com/107</link>
      <description>&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;DataFrame의 특정 열에 접근할 때 보통 row['col_name']을 사용하지만, 전처리 과정이나 외부 데이터 병합 이후 컬럼이 조건부로 생성될 수 있는 경우에는 get()이 훨씬 안전할 수 있습니다. 이번 글에서는 .get()을 사용하는 방법과 장단점을 정리해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;함수 설명&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Series.get(key, default)메서드는 존재하지 않는 키(열 이름)에 접근할 경우 오류를 발생시키지 않고, 대신 기본값(default)을 반환하는 안전한 접근 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;예시 코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd

# 예제 데이터
df = pd.DataFrame({
    'name': ['홍길동', '이몽룡', '성춘향'],
    'age': [25, 27, 22]
})

# 존재하지 않는 컬럼을 조회할 때
for _, row in df.iterrows():
    try:
        print(row['address'])   # KeyError 발생
    except KeyError:
        print('KeyError 발생!')

# 안전하게 접근
for _, row in df.iterrows():
    print(row.get('address', '주소 없음'))&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;erlang-repl&quot;&gt;&lt;code&gt;KeyError 발생!
KeyError 발생!
KeyError 발생!
주소 없음
주소 없음
주소 없음&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;row['address'] &amp;rarr; 존재하지 않는 컬럼이면 &lt;b&gt;KeyError&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;row.get('address', '주소 없음') &amp;rarr; 기본값 '주소 없음'을 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, get()을 쓰면 예상치 못한 컬럼 누락에도 코드가 멈추지 않고 기본값으로 처리할 수 있습니다.&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;장단점 비교&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;true&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;예외 처리 불필요: &lt;/b&gt;존재하지 않는 컬럼에 접근하더라도 오류 발생 X&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기본값 설정 가능: &lt;/b&gt;결측 컬럼에 대한 기본값을 쉽게 지정 가능해 전처리 유용&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚠️ &lt;b&gt;단점&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;true&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;성능 저하 가능성: &lt;/b&gt;내부적으로 추가적인 확인 과정을 거치므로, 대규모 데이터 반복 시 성능 차이 가능성 有&lt;/li&gt;
&lt;li&gt;&lt;b&gt;명시적 에러 감지 불가: &lt;/b&gt;잘못된 컬럼명을 실수로 입력해도 오류가 발생하지 않아 디버깅 시 문제 발견 어려움&lt;/li&gt;
&lt;li&gt;&lt;b&gt;일부 Pandas 객체에서 미지원: &lt;/b&gt;특정 상황(예: itertuples())에서는 .get() 메서드 사용 불가&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정상적인 컬럼 존재를 보장할 때는 &lt;/b&gt;&lt;b&gt;row[key]&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컬럼 존재가 불확실할 때는 &lt;/b&gt;&lt;b&gt;row.get(key, default)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;을 사용하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Python</category>
      <category>Get</category>
      <category>pandas</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/107</guid>
      <comments>https://super-son.tistory.com/107#entry107comment</comments>
      <pubDate>Tue, 14 Oct 2025 19:03:32 +0900</pubDate>
    </item>
    <item>
      <title>[Pandas] 다른 컬럼의 값으로 결측값 채우기 (feat. combine_first)</title>
      <link>https://super-son.tistory.com/106</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 정제 작업 중, 두 컬럼을 비교해서 한쪽이 비어 있으면 다른 값으로 채워야 할 때가 있습니다. 이때 fillna()를 주로 사용하지만, 인덱스가 다른 상황에서는 combine_first()가 더 안전한 선택입니다. &lt;span&gt;이번 글에서는 두 메서드의 차이를 예제로 비교하면서, 어떤 상황에 어떤 함수를 쓰면 좋은지 정리해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-pm-slice=&quot;1 2 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;combine_first() 기본 개념&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;combine_first()&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;두 Series(DataFrame 포함)를 결합하여, 앞쪽 값이 결측치(NaN)일 경우 뒤쪽 값으로 채워주는 메서드&lt;/b&gt;&lt;/span&gt;&lt;span&gt;입니다. &lt;/span&gt;&lt;span&gt;즉, &quot;왼쪽 값을 우선 사용하고, 비어 있으면 오른쪽 값으로 보충&quot;하는 방식으로 작동합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;예제 코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import pandas as pd

df = pd.DataFrame({
    '고객명': ['홍길동', None, '이몽룡'],
    '이름':   ['길동이', '성춘향', None]
})

df['고객명'].combine_first(df['이름'])&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;0    홍길동
1    성춘향
2    이몽룡
Name: 고객명, dtype: object&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;0번: &lt;/span&gt;&lt;span&gt;'고객명'&lt;/span&gt;&lt;span&gt; 값이 있으므로 그대로 유지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;1번: &lt;/span&gt;&lt;span&gt;'고객명'&lt;/span&gt;&lt;span&gt;이 비었으므로 &lt;/span&gt;&lt;span&gt;'이름'&lt;/span&gt;&lt;span&gt;의 값으로 채움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;2번: &lt;/span&gt;&lt;span&gt;'고객명'&lt;/span&gt;&lt;span&gt; 유지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;fillna와의 차이점&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교 항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;fillna&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;combine_first&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;기본 동작&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;NaN만 채움&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;NaN 채움 + 인덱스 합집합 고려&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;인덱스 다를 때&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;무시&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;자동 정렬 후 병합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;반환 결과&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;원본 인덱스 기준&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;두 Series의 union 인덱스 기준&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;예제 코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;s1 = pd.Series(['홍길동', None, '이몽룡'], index=[0, 1, 2])
s2 = pd.Series(['길동이', '성춘향'], index=[1, 3])

print(&quot;fillna 결과:\n&quot;, s1.fillna(s2))
print(&quot;\ncombine_first 결과:\n&quot;, s1.combine_first(s2))&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;fillna 결과:
0    홍길동
1     NaN
2    이몽룡
dtype: object

combine_first 결과:
0    홍길동
1    길동이
2    이몽룡
3    성춘향
dtype: object&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;fillna&lt;/span&gt;&lt;span&gt;: 같은 인덱스만 채우므로 1번은 비어 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;combine_first&lt;/span&gt;&lt;span&gt;: 인덱스 합집합으로 병합해 3번 인덱스까지 반영&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;정리&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인덱스가 &lt;/span&gt;&lt;span&gt;&lt;b&gt;완전히 동일&lt;/b&gt;&lt;/span&gt;&lt;span&gt;한 Series끼리는 &lt;/span&gt;&lt;span&gt;fillna()&lt;/span&gt;&lt;span&gt;와 &lt;/span&gt;&lt;span&gt;combine_first()&lt;/span&gt;&lt;span&gt; 결과가 동일&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;하지만 &lt;/span&gt;&lt;span&gt;&lt;b&gt;인덱스가 다를 수 있는 경우&lt;/b&gt;&lt;/span&gt;&lt;span&gt;에는 &lt;/span&gt;&lt;span&gt;combine_first()&lt;/span&gt;&lt;span&gt;가 더 안전&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;일반적인 DataFrame 내부 컬럼 결합이라면 인덱스가 일치하므로 &lt;/span&gt;&lt;span&gt;fillna()&lt;/span&gt;&lt;span&gt;로 충분하며 속도도 더 빠릅니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Study/Python</category>
      <category>combine_first</category>
      <category>fillna</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/106</guid>
      <comments>https://super-son.tistory.com/106#entry106comment</comments>
      <pubDate>Wed, 8 Oct 2025 10:06:18 +0900</pubDate>
    </item>
    <item>
      <title>[Pandas] int, int64, Int64의 차이와 변환 시 주의점</title>
      <link>https://super-son.tistory.com/105</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas에서 데이터를 다룰 때 결측치가 섞여있는 데이터를 정수형으로 변경해 사용하고자 할 때 어떤 방법을 사용하는게 좋을까요? 저는 평소 &lt;code&gt;.astype(int)&lt;/code&gt;를 쓰다가 숫자가 크면 제대로 변환이 되지 않아 &lt;code&gt;.astype('int64')&lt;/code&gt;를 사용했었는데요. 결측치가 있을 때는 오류가 나서 알아보고 &lt;code&gt;.astype('Int64')&lt;/code&gt;를 사용해서 해결했습니다. 이 글에서는 세 가지 타입의 차이와 함께 사용하면서 제가 만났던 오류를 피하는 팁을 간단한 예제를 통해 정리해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;int, int64, Int64 비교 &amp;mdash; 결측치 수용&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd

# 예제1
values = [None, 2, 7]
df = pd.DataFrame(values, columns=['values']) 

# 1-1. int로 변환 - 에러: 결측치
print(df['values'].astype('int'))

# 1-2. int64로 변환 - 에러: 결측치
print(df['values'].astype('int64'))

# 1-3. Int64로 변환 - 성공
print(df['values'].astype('Int64'))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int와 'int64'는 결측치를 허용하지 않기 때문에 None이나 NaN 값이 있으면 변환 오류가 발생합니다. 반면 'Int64'는 &lt;b&gt;Pandas의 nullable integer 타입&lt;/b&gt;으로 결측치(pd.NA)를 허용합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.0077%;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 16.5891%;&quot;&gt;결측치 허용&lt;/td&gt;
&lt;td style=&quot;width: 67.4031%;&quot;&gt;특징&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.0077%;&quot;&gt;int&lt;/td&gt;
&lt;td style=&quot;width: 16.5891%;&quot;&gt;❌&lt;/td&gt;
&lt;td style=&quot;width: 67.4031%;&quot;&gt;Python 기본 타입, 크기 제한 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.0077%;&quot;&gt;'int64'&lt;/td&gt;
&lt;td style=&quot;width: 16.5891%;&quot;&gt;❌&lt;/td&gt;
&lt;td style=&quot;width: 67.4031%;&quot;&gt;NumPy dtype, NaN 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.0077%;&quot;&gt;'Int64'&lt;/td&gt;
&lt;td style=&quot;width: 16.5891%;&quot;&gt;✅&lt;/td&gt;
&lt;td style=&quot;width: 67.4031%;&quot;&gt;Pandas&amp;nbsp;전용&amp;nbsp;nullable&amp;nbsp;integer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;int형의 한계 &amp;mdash; 큰 숫자 변환 문제&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 예제2
values = [2, 7, '2160378724']
df = pd.DataFrame(values, columns=['values'])

# 2-1. int로 변환 - 에러: int로 변환하기에는 너무 큼.
df['values'].astype(int)

# 2-2. int64로 변환 - 성공
df['values'].astype('int64')

# 2-3. Int64로 변환 - 성공
df['values'].astype('Int64')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python의 int는 내부적으로 크기 제한이 없지만, Pandas에서 사용하는 astype(int) 변환 과정에서는 C 기반 정수형(int32)이 기본으로 사용될 수 있어 32비트 한계를 넘어가면 오류가 발생할 수 있습니다. int32의 범위 아래와 같이 약 &amp;plusmn;21억이며, 이를 초과하면 OverflowError 또는 음수 변환이 일어날 수 있습니다. 따라서 큰 숫자를 다루려면 int64나 Int64를 사용하는 것이 안전합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;표현 가능 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;int32&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;&amp;plusmn;21억 (-2,147,483,648 ~ 2,147,483,647)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;int64 / Int64&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;약&amp;nbsp;&amp;plusmn;9경&amp;nbsp;(-9,223,372,036,854,775,808&amp;nbsp;~&amp;nbsp;9,223,372,036,854,775,807)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Int64 형 사용 시 주의할 점 &amp;mdash; float 변환 불가&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 예제3
values = [2, 7, 10.3]
df = pd.DataFrame(values, columns=['values'])

# 3-1. int로 변환 - 성공
df['values'].astype(int)

# 3-2. int64로 변환 - 성공
df['values'].astype('int64')

# 3-3. Int64로 변환 - 에러: float 데이터 변환 불가
df['values'].astype('Int64')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Int64는 결측치를 허용하는 대신 &lt;b&gt;부동소수(float) 값은 허용하지 않습니다.&lt;/b&gt; 실수 값이 포함된 데이터는 'int64'로 변환하거나, 필요에 따라 pd.to_numeric(..., errors='coerce')를 사용해 NaN으로 처리한 뒤 변환해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결측치가 포함된 정수열 &amp;rarr; &lt;b&gt;Int64&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;큰 숫자(&amp;plusmn;21억 이상)를 포함한 데이터 &amp;rarr; &lt;b&gt;int64&lt;/b&gt; &lt;b&gt;또는&lt;/b&gt; &lt;b&gt;Int64&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;실수(float) 포함 시 &amp;rarr; &lt;b&gt;int64&lt;/b&gt; &lt;b&gt;또는 float 유지&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 가지 타입의 차이를 이해하면 결측치나 큰 값이 섞인 데이터를 변환할 때 발생하는 오류를 쉽게 해결할 수 있습니다.&lt;/p&gt;</description>
      <category>Study/Python</category>
      <category>DataFrame</category>
      <category>iNT</category>
      <category>int64</category>
      <category>pandas</category>
      <author>Super-Son</author>
      <guid isPermaLink="true">https://super-son.tistory.com/105</guid>
      <comments>https://super-son.tistory.com/105#entry105comment</comments>
      <pubDate>Mon, 6 Oct 2025 17:27:04 +0900</pubDate>
    </item>
  </channel>
</rss>