Skip to content

Think-Aloud 모드

어노테이터가 작업하면서 말을 하면 Potato가 그 발화 전사를 그대로 근거로 저장합니다. 음성 인식은 faster-whisper로 전부 로컬에서 돌아가므로 오디오가 기기를 떠나지 않고, 파이프라인에 클라우드 API도 LLM도 없습니다.

v2.7.0의 새 기능

LLM 이전에 판단을 이해하는 가장 표준적인 방법은 사고구술 프로토콜이었지만, 이 방법은 주석 도구와 만나면 늘 살아남지 못했습니다. Think-Aloud 모드는 어노테이터가 작업하면서 그냥 말을 하게 합니다.

말한 그대로의 전사가 근거로 저장되며, 요약하지 않는 것은 의도한 선택입니다. 사고구술 프로토콜을 바꿔 말하는 순간 수집하려던 자료 자체가 오염되기 때문입니다. 라벨은 규칙 기반 파서가 잡아내는 정해진 표현을 써서 음성으로 확정할 수 있고, 파이프라인 어디에도 LLM이 없습니다.

음성 인식은 faster-whisper를 통해 전부 로컬에서 돌아가며, 39 MB짜리 tiny.en 모델이면 CPU만으로도 실시간입니다. 오디오는 기기를 벗어나지 않고, 호출할 클라우드 API도 토큰당 청구서도 없습니다.

참고: Think-Aloud는 여러분의 어노테이터를 전사합니다. Whisper나 클라우드 ASR API, 내려받은 자막처럼 이미 가지고 있는 전사본에 주석을 달고 싶다면 그것은 별개의 기능입니다. 전사 형식을 보십시오. 둘 다 Whisper가 얽혀 있어 자주 헷갈립니다.

감지된 음성 라벨과 함께 말한 그대로 남은 추론 전사본. 모델의 사고 사슬과 견줘 볼 사람의 사고 사슬입니다.

사람의 사고 사슬 기록하기

목적은 근거를 모으는 것만이 아닙니다. Think-Aloud는 사람이 라벨에 이르기까지 실제로 어떻게 추론하는지를 담아내므로, 같은 항목에서 그 사람의 사고 사슬을 모델의 사고 사슬과 나란히 놓고 볼 수 있습니다.

Potato의 프로세스 보상 주석모델이 어떻게 추론하는지를 단계별로 나눕니다. Think-Aloud는 사람이 어떻게 하는지를 담습니다. 둘 다 기록을 담는 자리이며, 같은 항목에서 나란히 놓았을 때 흥미로운 차이가 드러납니다.

동작 방식

  1. 어노테이터가 🎤 소리 내어 생각하기를 누르고 자유롭게 말합니다.
  2. 오디오는 6초 단위의 완결된 청크로 수집되어 로컬에서 전사됩니다.
  3. 음성으로 라벨을 확정하려면 인정되는 표현 중 하나를 씁니다.
    • "I label this Polite" / "I'd call it neutral"
    • "My answer is impolite"
    • "Final answer: polite" / "I go with neutral"
  4. 감지되면 UI에서 해당 선택지가 자동으로 선택되고, 평소의 저장 파이프라인이 실행되며, 작은 배지가 확인해 줍니다: 인식됨: Impolite ✓. 나중에 새 표현을 말하면 라벨이 바뀌므로 마지막 확정이 이깁니다.
  5. require_spoken_label: true이면 확정된 라벨 없이 다음을 누를 때 기대하는 표현을 보여주는 안내가 한 번 뜹니다. 다음을 한 번 더 누르면 그대로 넘어가고, 라벨을 클릭하는 방식은 언제나 됩니다.

생각하는 동안 입에 올린 말은 모두 무시됩니다. "This seems polite, but…"는 아무것도 확정하지 않습니다. 정해진 표현만 확정하며, 그래서 규칙 기반 파싱으로 충분합니다. 잘못 들은 경우는 퍼지 라벨 매칭이 흡수하므로 "in polite"는 Impolite로 풀립니다.

준비

bash
pip install faster-whisper   # local STT; first recording downloads the model (~39 MB)

브라우저에 마이크 권한이 필요합니다. localhost는 보안 컨텍스트로 인정됩니다.

구성

yaml
thinkaloud:
  enabled: true
  schema: politeness          # scheme whose labels can be spoken (default: first radio)
  stt: auto                   # faster_whisper | mock | auto
  model: tiny.en              # tiny.en is CPU real-time; base.en is sturdier
  chunk_seconds: 6            # recording chunk length
  require_spoken_label: true  # nudge on Next without a committed label
  # stems:                    # override accepted phrasing regexes (advanced)
  # fillers: [um, uh, hmm, i guess, maybe]
  # language: en
옵션기본값설명
sttautofaster_whisper(로컬), mock(테스트와 개발용), 또는 auto. auto는 faster-whisper를 고르고, 없으면 도움이 되는 오류를 냅니다.
modeltiny.enfaster-whisper 모델 id면 무엇이든 됩니다.
chunk_seconds6각 청크는 완결된 오디오 파일입니다.
stems내장값인정되는 표현의 정규식 어간이며, 각각 뒤따르는 단어를 캡처합니다.
fillersum, uh, hmm, …머뭇거림 집계에 쓰는 어휘 목록입니다.
require_spoken_labeltrue확정된 것이 없을 때 다음 버튼에서 한 번 뜨는 안내입니다.

무엇을 얻는가

  • 말한 그대로의 근거 스트림. (어노테이터, 인스턴스)마다 정렬되며 라벨 표현은 따로 분리됩니다. 전사본에서 확정 표현을 뺀 것이 근거입니다.
  • 결정론적인 머뭇거림 신호: 무음 청크 수와, 설정할 수 있는 어휘 목록에 대한 군말 단어 수입니다. 모델이 아니라 산술로 계산합니다.
  • 검토 페이지/thinkaloud/review(관리자)에 있으며, 모든 세션의 전사본, 음성으로 확정한 라벨, 신뢰도, 머뭇거림 통계를 보여줍니다.
  • 부수적으로 손을 쓰지 않는 주석 작업이 되며, 실질적인 접근성 개선과 반복사용긴장성손상(RSI) 완화가 따라옵니다.

데이터와 API

전사본은 {output_annotation_dir}/thinkaloud/transcripts.jsonl에 남습니다(덧붙이기 전용, 청크당 레코드 하나).

엔드포인트메서드인증용도
/thinkaloud/api/chunkPOST세션멀티파트 오디오 청크 → 전사 + 감지
/thinkaloud/api/textPOST세션텍스트 청크(오디오 없는 경로)
/thinkaloud/api/stateGET세션인스턴스에 대한 세션 집계
/thinkaloud/reviewGET관리자전사본 검토 페이지
/thinkaloud/api/exportGET관리자모든 세션을 JSON으로

설계 노트

  • 파서는 마지막 두 청크로 이루어진 이동 창을 대상으로 돌기 때문에, 청크 경계에 걸친 표현도 감지됩니다.
  • 라벨 매칭은 완전 일치, 접두사 일치, 그다음 임계값 0.8의 difflib 순이며 완전 일치를 우선합니다. "polite"가 "Impolite"와 퍼지 매칭으로 충돌하는 일은 없습니다.
  • STT 백엔드를 추가하려면 potato/thinkaloud/stt.pySTTBackend를 상속하고 create_stt에 등록하면 됩니다.

추가 자료