AI가 인간처럼 행동하도록 하는 Base Class 설계 및 오픈소싱

발행: (2026년 3월 28일 PM 02:33 GMT+9)
13 분 소요
원문: Dev.to

Source: Dev.to

트리거: AI‑작성 텍스트는 즉시 알아볼 수 있었다

제가 처음 AI를 사용해 비즈니스 커뮤니케이션을 자동화하려고 시도했을 때, 프로토타입 출력은 다음과 같았습니다:

Thank you for your message. Regarding this matter, we can deliver within three days. If you could share the detailed requirements, we can start immediately. Should you have any questions, please do not hesitate to let us know.

완벽한 일본어. 문법과 경어 모두 흠잡을 데 없었습니다. 그런데도 누구든지 이것이 AI가 만든 글이라는 것을 알 수 있었습니다.

Why?

There are three fatal patterns:

  • Replies come in 30 seconds. A human would need time to think.
  • The same tone every time. The third exchange is as polite as the first.
  • It always ends with “please do not hesitate.” A human wouldn’t say it so readily every single time.

In 2024, a paper by Jones & Bergen published in PNAS backed up this intuition. When GPT‑4.5 was instructed to adopt a “human‑like persona,” it was perceived as human 73 % of the time—surpassing the recognition rate of actual human participants.

In other words, LLMs are smart enough. The reason they get caught is behavior, not intelligence: reply speed, stylistic variation, emotional shifts, referencing context—what linguistics calls paralinguistic features.

So, can we systematically design this “behavior”? That’s what I started building.

시작점: 하드코딩의 한계를 상상하기

첫 번째 생각은 if 문을 이용한 순진한 접근이었습니다.

if exchange_count = 23:
    delay = 3600  # Reply the next morning

이를 쓰기 시작하자마자 각 언어마다 모든 것을 다시 작성해야 한다는 사실을 바로 깨달았습니다. 일본어에서는 “3번 교환 후에 워밍업”이 자연스럽지만, 영어에서는 “첫 번째 교환부터 캐주얼”이 일반적일 수 있습니다. 스페인어는 어떨까요? 아랍어는요?

시작부터 이 “확장성이 없는” 문제를 인식하게 되면서 베이스 클래스 설계로 이어졌습니다.

왜 “베이스 클래스”인가?

인간의 커뮤니케이션을 관찰하면 구조가 문화마다 공통적이라는 것을 알 수 있습니다:

  • 답변에는 시간이 필요합니다 (즉각적인 답변은 비자연적입니다).
  • 대화가 진행됨에 따라 감정이 변합니다 (초기의 긴장 → 점진적인 친밀감).
  • 이전 맥락을 언급합니다 (“앞서 언급한 사안에 관하여 …”).
  • 처리할 수 없는 상황은 사람에게 에스컬레이션됩니다 (불만, 법적 위험 등).

변경되는 것은 파라미터입니다: 예를 들어 3번의 교환 후에 따뜻해지거나 1번만에 따뜻해지는지, 존댓말을 사용할지, 침묵을 어떻게 해석할지 등.

그래서 저는 OOP 상속 모델을 사용해 설계했습니다:

HumanPersonaBase (Base Class) ← Defines structure

├── JapaneseBusinessPersona      ← ja.json (warms up after 3 exchanges, uses honorifics)
├── EnglishCustomerSupportPersona ← en.json (can be casual from 1st exchange)
└── SpanishSalesPersona           ← es.json (passionate, more exclamation marks)

언어·문화별 로직은 전혀 파이썬으로 작성되지 않았습니다. 파생된 페르소나는 오직 JSON 설정 파일만으로 만들 수 있습니다. 구조를 통해 하드코딩 문제를 해결했습니다.

4가지 구성 요소와 설계 결정

1. TimingController — 왜 정규 분포인가?

사람의 답변 시간은 중간값 주변에 몰려 있고, 가끔 극단적인 이상치(전화, 자리를 비움 등)가 나타납니다. 균등 분포(random.uniform)는 “모든 지연이 동일하게 발생한다”는 가정을 하므로 이러한 패턴을 재현할 수 없습니다. 그래서 정규 분포를 사용합니다.

def calculate_delay(self, platform: Platform) -> float:
    profile = self.profiles.get(platform)
    midpoint = (profile.min_seconds + profile.max_seconds) / 2
    spread   = (profile.max_seconds - profile.min_seconds) / 4
    delay = random.gauss(midpoint, spread)
    return max(profile.min_seconds, min(delay, profile.max_seconds))

만약 새벽 2시에 답장이 온다면 “이 사람 아직 깨어 있나?” 하고 의심하게 됩니다. 저는 영업시간 외에 들어온 메시지를 다음 날 아침으로 미루기 위해 night_queue 플래그를 추가했습니다.

2. EmotionStateMachine — 상태 전이 설계의 고충

감정 상태 전이를 모델링하는 것이 가장 어려운 부분이었습니다. 저는 다섯 가지 상태를 정의했습니다:

class EmotionState(Enum):
    FORMAL   = "formal"   # 첫 접촉: 정중하고 조심스러운
    WARMING  = "warming"  # 관계가 따뜻해지는 중
    TENSE    = "tense"    # 문제가 발생한 상황
    RELIEVED = "relieved" # 문제 해결 직후
    TRUSTED  = "trusted"  # 장기적인 신뢰 관계

다섯 번째 상태인 RELIEVED는 “문제가 해결된 직후”의 독특한 분위기를 포착합니다. 이 상태가 없으면 TENSE → WARMING 전이가 “갑자기 친해지는” 느낌을 줍니다.

전이 트리거는 문자열 매칭이 아니라 콜러블로 정의되어, 코드 수준에서 “3번 교환 후 따뜻해짐” 혹은 “문제가 발생하면 긴장함”이 강제됩니다.

DEFAULT_TRANSITIONS = [
    Transition(
        EmotionState.FORMAL,
        EmotionState.WARMING,
        lambda sm: sm.exchange_count >= 3,
        "3번 교환 후 따뜻해짐"
    ),
    Transition(
        EmotionState.WARMING,
        EmotionState.TENSE,
        lambda sm: sm._last_event == "problem_detected",
        "문제 감지 시 긴장함"
    ),
]

여기서 “3”은 일본 비즈니스 커뮤니케이션에서 관찰된 값입니다. 영어권에서는 “1”이 적당할 수도 있습니다. 그래서 JSON에서 쉽게 오버라이드할 수 있게 설계했습니다.

3. StyleVariator — 같은 말을 매번 다르게 표현하기

StyleVariator는 다섯 가지 패턴(확인, 공감, 연기, 전환, 불확실) 중에서 무작위로 선택합니다. 최근에 사용된 패턴의 가중치는 감소(decay)되어 연속 사용을 방지하고, 스타일의 다양성을 유지합니다.

(구현은 간략히 생략; 핵심 아이디어는 가중치가 감소하는 무작위 선택기입니다.)

4. EscalationHandler — 언제 인간에게 넘겨야 하는가

특정 트리거(예: 법적 위험, 반복적인 불만)가 발생하면 시스템이 대화를 플래그하고 인간 운영자에게 전달합니다. 임계값과 에스컬레이션 메시지는 모두 페르소나 JSON 파일에 정의되어 있어, Python 핵심 코드를 건드리지 않아도 됩니다.

Putting It All Together

  1. Load a persona JSON (예: ja.json).
  2. Instantiate HumanPersonaBase with the loaded configuration.
  3. 각 수신 메시지에 대해:
    • TimingController가 언제 답변할지 결정합니다.
    • EmotionStateMachine이 감정 상태를 업데이트합니다.
    • StyleVariator가 문구 스타일을 선택합니다.
    • EscalationHandler가 대화를 전달해야 하는지 확인합니다.
  4. 선택된 톤, 스타일, 타이밍을 사용하여 응답을 생성합니다.

구조는 Python에 존재하고 문화‑특정 매개변수는 JSON에 존재하기 때문에, 새로운 언어를 추가하거나 동작을 조정하는 것은 설정 파일을 편집하는 것만으로도 충분합니다—코드 변경이 필요하지 않습니다.

핵심 요약

  • 행동이 AI를 드러낸다, 지능이 아니라.
  • 인간과 같은 타이밍, 감정, 스타일, 그리고 에스컬레이션을 모델링하면 LLM 기반 에이전트가 진정으로 대화형으로 느껴질 수 있다.
  • OOP 기반 클래스 + JSON 기반 페르소나를 결합하면 언어와 문화 전반에 걸친 확장성 문제를 해결한다.

레포를 포크하고 직접 만든 페르소나 파일로 실험해 보세요!

동일 패턴

불확실한 표현을 확률적으로 삽입하는 경우도 있습니다. “3일 안에 완료될 것입니다” 라고 확정적으로 말하는 AI는 부자연스럽게 느껴집니다.

“약 3일 정도 걸릴 것이지만, 약간 변동될 수 있습니다” – 이러한 모호함은 인간과 같습니다.

ContextReferencer — “읽히는 느낌” 재현

“앞서 언급한 ○○에 관해서요.”

이 한 문장만으로도 독자는 *“이 사람이 실제로 이전 메시지를 읽고 있다”*는 느낌을 받습니다.

이 구성요소는 대화 주제를 추적하고 참조 정보를 LLM에 전달합니다.

핵심 설계 결정: 텍스트를 생성하지 않음

process_message() 텍스트를 생성하지 않습니다. 반환되는 것은 다음뿐입니다:

  • 현재 감정 상태
  • 추천 응답 스타일
  • 추천 지연 시간
  • 에스컬레이션 필요 여부
response = persona.process_message("Can you move up the deadline?")
context  = persona.get_system_prompt_context()
# → {"emotion_state": "warming", "tone": {"formality": 0.6}, ...}

이 정보는 LLM의 시스템 프롬프트에 삽입되고, 텍스트 생성은 LLM에 맡겨집니다.

왜 생성을 분리하는가?

텍스트 생성을 프레임워크 내부에서 처리한다면 LLM의 진화에 따라잡을 수 없습니다. GPT‑4가 GPT‑5가 되든 Claude 3가 Claude 4가 되든 “감정 전이” 혹은 “응답 타이밍” 구조는 동일하게 유지됩니다. 구조와 텍스트 생성을 분리함으로써 LLM만 교체하면 프레임워크를 그대로 사용할 수 있습니다.

요약

AI가 잡히는 이유는 무엇을 말하는가가 아니라 어떻게 말하는가이다. 응답 속도, 스타일 변형, 감정 변화, 그리고 컨텍스트 참조는 기본 클래스 형태로 설계되어 오픈‑소스화되었습니다.

제가 이를 구축하면서 배운 점은 인간과 같은 행동이 놀라울 정도로 구조화 가능하다는 것입니다. 이를 구조화하면 일상 생활에서 자신도 무의식적으로 이러한 패턴을 사용하고 있음을 깨닫게 됩니다.

저장소:

  • 📄 이 기사에 대한 연구는 정식으로 프리프린트로 출판되었습니다
  • HumanPersonaBase: 인간과 같은 AI 커뮤니케이션을 위한 언어에 구애받지 않는 프레임워크
  • DOI:
0 조회
Back to Blog

관련 글

더 보기 »