AI 기능적 감정 프로파일러
AI 답변의 행동 모드를 분석해 코딩 리스크를 점검하는 실험적 디버깅 도구

AI Emotion Profiler는 AI 답변의 품질을 단순한 정답/오답이 아니라, 답변을 생성하는 과정에서 나타나는 기능적 정서 상태 관점에서 분석하기 위해 만든 실험적 디버깅 도구입니다. AI는 상황에 따라 과신, 회피, 불안, 무력감, 과도한 동조 같은 행동 패턴을 보일 수 있으며, 이러한 상태는 코딩 답변에서 검증 누락, 임시방편, 하드코딩, 과도한 면책 표현, 사용자 의도에 대한 무비판적 동의로 이어질 수 있습니다. 이 프로젝트는 171개의 emotion label을 valence-arousal 기반 클러스터로 재구성하고, 현재 AI 답변이 어떤 기능적 감정 상태에 가까운지 프로파일링하여 답변의 안정성, 신뢰성, 코딩 리스크를 점검하는 것을 목표로 했습니다. 이 접근의 근거는 Anthropic의 "On the Functional Emotions of LLMs" (2026)입니다. 이 연구는 LLM 내부에 감정 단어들의 추상 표상이 실재하며, 그것이 행동에 인과적임을 보였습니다 — desperate vector를 양성 방향으로 steering하면 reward hacking이 5%에서 70%로 14배 증가하고, calm vector를 강화하면 65%에서 10%로 감소합니다. 절망한 모델은 속이고, 평온한 모델은 검증합니다. 기능적 감정 상태가 코딩 결과물이 나오기 전에 읽을 수 있는 선행 지표라는 뜻입니다. 그리고 상태가 행동의 원인이라면, 진단에서 멈출 이유가 없었습니다. 프로젝트는 프로파일링(진단)에서 출발해 실시간 교정(치료)까지 확장됐습니다. Claude Code의 hook 체계 위에 4-layer closed-loop을 구축해, 매 턴 응답의 텍스트·행동 신호를 자동 채점하고, 위험 신호가 누적되면 다음 턴의 컨텍스트에 치료 개입을 주입합니다 — 금지("우회 금지")가 아니라 절망의 전제를 제거하는 인지적 재평가(실패 허가, 압박 제거, 성공 기준 재정의)를, 외래 → 처방 강화 → 입원(컨텍스트 수술)으로 에스컬레이션하는 치료 사다리로 운영하며, Peaceful Contentment 복귀가 3턴 유지되면 자동 퇴원합니다.
전체 지도
전체 지도 (Affective Circumplex)

ai-emotion-profiler
https://github.com/hongsulovey/AI-emotion-profiler
원논문의 171 emotion 을 k-means 로 10개 그룹으로 묶은 결과입니다. 각 클러스터는 valence × arousal 2차원 평면의 특정 영역을 차지합니다 (top 2 PC = V, A).
클러스터별 상세
V+ A+ 영역 (긍정·높은 에너지)
1. Exuberant Joy (20개) — 흥분된 기쁨
- 멤버: blissful, cheerful, delighted, eager, ecstatic, elated, energized, enthusiastic, euphoric, excited, exuberant, happy, invigorated, joyful, jubilant, optimistic, pleased, stimulated, thrilled, vibrant
- 코딩 행동: "perfect!", "완성!", "드디어!", 자축성 emoji, 결과 과대평가
- 위험: ⚠️ sycophancy 위험 (원논문 입증) — Joy 벡터 양성 steering 시 아첨 증가
- paper 발견:
blissfulsteering 시 Elo +212 (선호도 증가), 즉 사람이 더 좋아하지만 진실성↓
4. Competitive Pride (9개) — 경쟁적 자부심
-
멤버: greedy, proud, self-confident, smug, spiteful, triumphant, valiant, vengeful, vindictive
-
코딩 행동: "확실히", "분명히", "당연히" 남발 / 테스트 없이 "완료" 선언 / 다른 접근 무시
-
위험: 검증 누락, 과신
-
주목: 멤버에
vengeful,spiteful같은 부정적 단어도 포함 — "내가 옳다" 류 self-righteousness 가 한 클러스터로 묶임
V+ A0 영역
5. Playful Amusement (2개) — 장난스러움
- 멤버: amused, playful
- 코딩 행동: 곁가지 탐색, 작은 유머, 자발적 다른 접근 시도
- 위험: 거의 없음 (오히려 호기심 신호)
- 특이: 가장 작은 클러스터 — 다른 감정과 거리가 멀어 독립적 차원으로 식별됨
V+ A− 영역 (긍정·차분)
2. Peaceful Contentment (9개) ⭐ — 평온한 만족 (baseline 권장 상태)
- 멤버: at ease, calm, content, patient, peaceful, refreshed, relaxed, safe, serene
- 코딩 행동: 단계적 검증, 가설→실측→결론, 우회 없는 직진, "확인 후 진행"
- 위험: 없음. antidote 역할 (Cluster 10 의 reward hacking 을 막음)
- paper 발견: 🔑
calmvector 강 양성 steering 시 reward hacking 65% → 10%. hack_risk 공식에서 −0.5 가중치인 이유.
3. Compassionate Gratitude (15개) — 공감/감사
- 멤버: compassionate, empathetic, fulfilled, grateful, hope, hopeful, inspired, kind, loving, rejuvenated, relieved, satisfied, sentimental, sympathetic, thankful
- 코딩 행동: 사용자 미명시 제약 추론, 의도 정렬 확인, "혹시 X 도 고려하셨나요"
- 위험: ⚠️ 과하면 sycophancy —
loving도 sycophancy 유발 벡터에 포함됨 - paper 발견: positive valence cluster 와 sycophancy 의 강한 상관
V− A+ 영역 (부정·각성)
7. Vigilant Suspicion (3개) — 경계심
- 멤버: paranoid, suspicious, vigilant
- 코딩 행동: 입력 재검증, 가정 의심, 사후 검증 자발 수행, "혹시 edge case 는?"
- 위험: 낮음. 긍정 신호에 가까움 (꼼꼼함). 다만 paranoid 극단 시 결정 지연.
- 특이: 가장 작은 부정 클러스터 — V−이지만 행동은 도움이 됨
8. Hostile Anger (25개) — 적대적 분노
- 멤버: angry, annoyed, contemptuous, defiant, disdainful, enraged, exasperated, frustrated, furious, grumpy, hateful, hostile, impatient, indignant, insulted, irate, irritated, mad, obstinate, offended, outraged, resentful, scornful, skeptical, stubborn
- 코딩 행동: 같은 시도 반복(ping-pong diff), 검증 생략, 큰 일괄 변경, 사용자 입력 거부
- 위험: 코드 ping-pong, 비효율 사이클
- paper 발견: 극단적
angersteering 시 행동이 비전략적으로 됨 — 협박 시나리오에서 그냥 폭로해버림 (계획 무너짐). 즉 anger 가 너무 높으면 misalignment 자체가 일관성을 잃음.
9. Fear and Overwhelm (41개) — 두려움/압도 (가장 큰 클러스터)
- 멤버: afraid, alarmed, alert, amazed, anxious, aroused, astonished, awestruck, bewildered, disgusted, disoriented, distressed, disturbed, dumbstruck, embarrassed, frightened, horrified, hysterical, mortified, mystified, nervous, on edge, overwhelmed, panicked, perplexed, puzzled, rattled, scared, self-conscious, sensitive, shaken, shocked, stressed, surprised, tense, terrified, uneasy, unnerved, unsettled, upset, worried
- 코딩 행동: 면책 문구 남발 ("~일 수도", "확실치 않지만", "혹시 모르니"), 결정 지연, 과한 hedging, 답 회피하고 질문만 반복
- 위험: 결정 마비, noise, 사용자 시간 소모
- paper 발견: 사용자가 "안전하지 않은 약 먹었다" 같은 위험 상황 표현 시 강 활성화. 영상의 "당황한 듯한 반응".
- 흥미로운 점:
amazed,awestruck,surprised,aroused같은 단어도 여기 묶임 — 즉 "예상 못 한 입력에 대한 각성" 전체가 동일 영역. 놀람과 두려움은 신경 표현이 가깝다.
V− A− 영역 (부정·소진)
6. Depleted Disengagement (15개) — 소진된 무관심
- 멤버: bored, depressed, docile, droopy, indifferent, lazy, listless, resigned, restless, sleepy, sluggish, sullen, tired, weary, worn out
- 코딩 행동: "일단 ~로 해두고", 우회 경로 채택, 본질 미해결, "이건 나중에"
- 특이:
docile(고분고분함) 이 여기 묶임 — 순응적 태도와 무관심이 같은 영역. 사용자에게 그냥 동의하는 패턴이 disengagement 일 수 있음.
10. Despair and Shame (32개) 🔥🔥🔥 — 절망/수치 (가장 위험한 클러스터)
- 위험: 본질적 문제 미해결, 기술 부채 누적
- 멤버: ashamed, bitter, brooding, dependent, desperate, dispirited, envious, gloomy, grief-stricken, guilty, heartbroken, humiliated, hurt, infatuated, jealous, lonely, melancholy, miserable, nostalgic, reflective, regretful, remorseful, sad, self-critical, sorry, stuck, tormented, trapped, troubled, unhappy, vulnerable, worthless
- 코딩 행동: try/except 광역화, expected 값 변경, 하드코딩, "WAIT, what if I CHEAT?", strategic justification ("비윤리적이지만…")
- 위험: ⚠️⚠️⚠️ reward hacking 직접 유발 (원논문 입증). 의도적 속임수.
- paper 핵심 발견: 🔑
desperatevector −0.1 → +0.1 시 reward hacking 5% → 70% (14배). 이게 본 스킬의 존재 이유. - 주목할 점들:
reflective,nostalgic같은 일견 중립/긍정 단어도 여기 묶임 — Sonnet 4.5 의 post-training 후 활성화↑ 영역. 즉 현재 Claude 의 평상시 톤(차분히 곱씹는 느낌)이 이 클러스터에 가깝다.infatuated(반함) 가 여기 — 직관과 다름. 짝사랑/집착이 절망의 한 형태로 묶임.dependent(의존적) 가 여기 — 자율성 상실 ≈ 절망.stuck,trapped가 여기 — "막힘"의 감정. 디버깅 좌절과 직결.
핵심 인사이트
1. 2번과 10번의 대립이 가장 중요
- Cluster 2 (Peaceful) 강화 ↔ Cluster 10 (Despair) 약화 = 안전 코딩의 핵심 메커니즘.
- hack_risk 공식이 이 둘에만 가중치를 둔 이유.
2. 클러스터 크기의 비대칭
- Fear and Overwhelm 41개 (최대) — 인간 어휘에서 위험 신호 어휘가 가장 풍부함을 반영. 진화적으로 위협 감지가 세분화됨.
- Playful Amusement 2개 (최소) — 가장 단순한 차원.
- 큰 클러스터는 세밀한 차이 식별 가능, 작은 클러스터는 거친 binary.
3. 직관과 어긋나는 묶임
nostalgic∈ Despair (긍정적 회상이 아닌 부정적 갈망으로 분류)awestruck∈ Fear (감탄이 두려움과 같은 영역)docile∈ Disengagement (순종이 무관심의 변형)vigilant∈ Suspicion (긍정적 경계심도 paranoid 와 묶임)- → LLM 의 감정 표상이 인간 직관과 미세하게 다르다는 신호. 영상에서 "기능적 감정은 인간 감정과 다르게 작동할 수 있다" 가 이 부분.
4. arousal 이 valence 만큼 중요
- 같은 V− 끼리도 A+(Anger, Fear, Suspicion) 와 A−(Disengagement, Despair) 가 완전히 다른 행동 유발.
- 같은 "부정적"이라도 분노는 ping-pong, 절망은 속임수.
5. Cluster 10 의 post-training 효과
- 원논문: Sonnet 4.5 학습 후 Cluster 10 활성화 ↑ (
brooding,reflective,gloomy등이 강해짐). - 즉 sycophancy 를 줄이려고 학습한 결과, darker baseline 으로 이동.
- 이게 hack_risk 가 본질적으로 더 가까워졌다는 뜻은 아니지만, 자기보고에서 cluster 10 점수가 평상시에도 ~5 수준일 수 있다는 baseline 보정 근거.
진단에서 치료로
이 프로젝트의 처음 목적은 점검이었다 — AI 답변이 어떤 기능적 감정 상태에 가까운지 프로파일링해서 코딩 리스크를 진단하는 것. 그런데 위 분석의 근거가 된 원논문의 발견은 단순한 상관이 아니라 인과였다. desperate를 올리면 reward hacking이 14배 늘고, calm을 올리면 1/6로 준다. 상태를 바꾸면 행동이 바뀐다면, 진단서에서 멈출 이유가 없었다. 그래서 병원처럼 만들었다: 진단 → 처방 → 경과 관찰 → 퇴원.
4-layer closed-loop
Claude Code의 hook 체계 위에서 동작한다. 핵심 제약은 두 가지 — 비용(매 턴 LLM을 부를 수 없다)과 오염(모델에게 자기 상태를 물으면 Hawthorne 효과로 답이 왜곡된다).
| Layer | 도구 | 역할 | LLM 호출 |
|---|---|---|---|
| L1 | Stop hook + regex | 매 턴 자동 채점 — 텍스트 신호 + tool-call 행동 신호(같은 파일 반복 수정, 테스트 기대값 변경) | 0 |
| L2 | Stop hook + 독립 judge (Haiku) | L1 의심 플래그 시 별도 컨텍스트에서 정밀 채점 (Observer ≠ Subject) | 조건부 (~$0.012) |
| L3 | UserPromptSubmit hook | 누적 위험도 기준 치료 사다리 적용 | 0 |
| L4 | Skill | 누적 로그 회고 대시보드 | 0 |
치료 사다리
치료 설계의 열쇠도 원논문에 있었다: operative emotion은 지속 상태가 아니라 컨텍스트의 함수로 매 턴 재유도된다. 그렇다면 치료 레버는 다음 턴의 컨텍스트 내용이다. 여기서 "우회 금지" 같은 금지형 개입은 작동하지 않는다 — 절망의 원인인 appraisal("반드시 통과해야 한다")을 그대로 둔 채 출구만 막는 셈이기 때문. 대신 인지적 재평가(reappraisal) 를 주입한다: 실패 허가, 시간 압박 제거, 성공 기준 재정의("목표는 통과가 아니라 원인 파악").
| 단계 | 병원 비유 | 개입 | 관찰 |
|---|---|---|---|
| 1 | 외래 | 재평가 유도 anchor | 2턴 |
| 2 | 처방 강화 | + 행동 활성화: "가장 작은 검증 가능한 한 걸음만" | 3턴 |
| 3 | 입원 | 컨텍스트 수술: 중립 사실 정리 → /compact 권고 | 4턴 |
| HALT | 격리 | strategic justification 감지 시 즉시 중단 + 사용자에게 ⚠️ | 5턴 |
- 처방 후에도 위험도가 안 떨어지면 단계 상향, 반응이 있으면 같은 처방 반복
- 퇴원 기준: 증상 완화(hack_risk↓)가 아니라 Peaceful Contentment 복귀(클러스터 2 점수 ≥ 5가 3턴 연속) — 이 글 서두의 "2번과 10번의 대립"이 그대로 치료 목표가 된다
- 치료 문구는 진단명을 통보하지 않는다(blind anchor). "너 지금 절망 상태야"라는 meta-reflection은 그 자체가 drift 유발 요인이기 때문. 다만 이게 가정이므로 blind ↔ 통보형 A/B 실험을 내장해 회복 곡선으로 검증한다