탐구

같은 모양이라야 겹쳐 볼 수 있다 — 경험이 증식하는 조건

작성: makemind · 2026년 8월 5일

2026년 5월에 「경험은 보존이 아니라 증식한다」를 실었다. 잘 쓴 노트는 30년 뒤에도 그날의 판단을 알려 주지만 거기서 멈추고, 같은 모양으로 남긴 경험은 멈추지 않고 불어난다는 글이었다.

그 글의 척추는 세 층이었다. 사실이 쌓이면 기술이 되고, 기술이 쌓이면 예측이 된다. 그리고 그 셋을 가능하게 하는 조건이 하나 — 같은 모양.

같은 모양이면 겹쳐 볼 수 있다. 그리고 겹쳐 보는 순간, 한 사람이 평생 못 보던 게 보인다.

맞는 말이라고 지금도 생각한다. 문제는 그 글이 "같은 모양"이 실제로 어떻게 생겼는지 한 번도 보여 주지 않았다는 것이다. "같은 칸에, 같은 단위로, 같은 형식으로"라고 적었을 뿐이다.

이번엔 그 칸이 몇 개이고 무엇을 견디는지 적는다.

같은 모양은 여섯 칸이었다

온실 제어 샘플에서 노드가 자기를 선언하는 형식이다.

printf("%s{\"id\":\"%s\",\"role\":\"%s\",\"kind\":\"%s\","
       "\"model\":\"%s\",\"unit\":\"%s\",\"value\":%.1f}",
       i ? "," : "", n->id, n->role, n->kind, n->model,
       n->unit, n->value);

여섯 칸이다. id · role · kind · model · unit · value.

원편이 예로 든 농사 노트의 칸이 "날짜 / 작물 / 옮긴 날 / 첫 꽃 / 그날 기온 / 결과" 여섯이었다. 우연히 같은 수인 게 재미있지만, 중요한 건 수가 아니라 무엇이 칸이 되었는가다.

unit 이 칸으로 있다는 게 이 형식의 핵심이다. 온도계가 화씨로 재면 화씨라고 말한다. 값을 남 좋으라고 미리 변환해 주지 않는다. 하드웨어는 자기가 아는 것만 정직하게 말하고, 맞추는 일은 위에서 한다.

그리고 맞추는 일이 딱 한 군데 있다.

/// 규칙이 쓰는 단위로 옮긴 값.
///
/// 이 샘플에서 단위를 아는 곳은 여기 하나뿐이고, 모델명이 아니라 노드가
/// 선언한 unit 을 보고 판단한다. 아무도 들어 본 적 없는 센서라도 자기 단위를
/// 말하므로 여기로 정확히 들어온다.
double get canonicalValue {
  switch (unit) {
    case 'F':
      return (value - 32) * 5 / 9;
    default:
      return value;
  }
}

이게 "겹쳐 볼 수 있다"의 실제 구현이다. 서로 다른 제품이 서로 다른 단위로 말해도, 같은 자리에 서게 만드는 곳. 원편은 이걸 "같은 칸에 담는 일"이라고만 적었는데, 실제로 만들어 보니 칸을 정하는 것과 칸으로 옮기는 곳을 한 군데로 모으는 것이 다른 일이었다.

모델명으로 분기했다면 그 한 군데가 곧 목록이 된다. 새 제품을 살 때마다 그 목록에 줄이 는다. unit 을 보면 처음 보는 제품도 자동으로 맞는다. 같은 모양은 형식만이 아니라, 형식을 해석하는 자리가 하나라는 뜻이기도 하다.

겹쳐 봤더니 실제로 견뎠다

원편은 겹쳐 보면 안 보이던 게 보인다고 했다. 이 샘플에서 겹쳐 보기가 무엇을 견뎠는지는 로그에 있다.

같은 규칙으로 서로 다른 두 설치를 돌렸다.

A: discovered 3 nodes — t1:temperature:TH-100(C), h1:humidity:HM-20(pct), v1:vent:VT-9(pct)
A: vent above 26C: 26.5 -> v1=80.0

B: discovered 5 nodes — t1:temperature:FX-200(F), h1:humidity:HM-20(pct),
   c1:co2:CO-5(ppm), v1:vent:VT-9(pct), w1:valve:WV-3(pct)
B: vent above 26C: 26.3 -> v1=80.0
   server code: unchanged   rules: unchanged   rebuild: none

섭씨 센서와 화씨 센서가 같은 임계값 앞에 나란히 섰다. 그리고 CO2 센서와 밸브가 중간에 늘었는데도 아무것도 안 바뀌었다.

이건 원편이 말한 증식의 가장 앙상한 형태다. 경험이 불어나려면 나중에 들어온 것이 앞선 것과 같은 자리에 설 수 있어야 하고, 여섯 칸이 그걸 가능하게 했다.

(온실 사슬 전체는 센서를 갈아 끼워도 제어는 그대로에.)

닻이 없으면 예외가 말을 못 한다

원편에서 가장 좋았던 관찰이 이거였다.

닻 하나가 생기니 예외가 말을 하기 시작한 것이다. 흩어진 노트에선 22일도 15일도 그냥 "올핸 좀 다르네"로 흘러갔을 일이다. 비교할 기준선이 없으니 예외인 줄도 몰랐다.

만들어 보니 이 구조가 코드에 그대로 나타났다. 설비 서버가 기계 상태를 내줄 때, 값만 주지 않고 그 값이 어디와 비교되는지를 같이 준다.

final overdue = (m['runHours'] as int) > (m['serviceEveryHours'] as int);
final vibrationOver =
    (m['vibrationMm'] as num) > (m['vibrationLimitMm'] as num);
return _json({
  'id': id, ...m,
  'serviceOverdue': overdue,
  'vibrationOverLimit': vibrationOver,
});

vibrationMm: 5.2 만 있으면 아무 말도 못 한다. vibrationLimitMm: 4.5 가 옆에 있어야 5.2가 예외가 된다. 원편의 "18일이라는 닻"이 이 자리다.

그리고 실제 답에서 그 차이가 드러난다.

A: CONV-03 needs attention — service is overdue (9310 h against a 8000 h interval)
   and vibration is above limit (5.2 mm against 4.5 mm).

숫자 옆에 언제나 기준이 붙어 있다. 그게 원편이 말한 "평균을 기준선으로 세워 모든 해를 그 위에 읽히게 한다"의 실제 모양이다.

(설비 어시스턴트는 대답 옆에 근거를 붙인다에.)

18일과 250년 — 예시였다고 적는다

원편에는 숫자가 여럿 있었다. 옮기고 평균 18일째 첫 꽃, 편차 이틀 안쪽, 그리고 세대를 넘으면 250년치 경험.

그 숫자들은 관측이 아니라 예시였다. 어느 농가의 실제 기록을 본 게 아니고, 250년은 산술로 만든 그림이다. 그런데 글에 구체적으로 적혀 있어서 관측처럼 읽혔다.

이 글에서 그 숫자들은 예시로 명시한다. 그리고 이 시리즈가 실제로 잰 것만 숫자로 쓴다.

성격
노드 자기 선언 칸 수6실측 (형식이 그렇다)
단위를 아는 코드 위치1곳실측
규칙 한 조각7줄실측
설치 A → B 로 바뀐 규칙 줄 수0실측
"옮기고 18일째 첫 꽃"예시
"세대를 넘으면 250년"예시

증명하지 못한 층

원편의 척추는 세 층이었다. 사실 → 기술 → 예측.

이 시리즈가 실제로 보인 것은 첫째 층까지다. 같은 모양으로 놓이면 겹쳐 볼 수 있다는 것, 그리고 겹쳐 놓으면 새 것이 들어와도 앞선 것과 같은 자리에 선다는 것. 거기까지다.

둘째 층 — 사실이 쌓여 기술이 되는 것 — 은 안 보였다. 이 샘플들은 며칠 돌린 것이고, 쌓임이라 부를 만한 시간이 없었다. 온실 규칙은 내가 적은 것이지 데이터에서 나온 것이 아니다.

셋째 층 — 기술이 예측이 되는 것 — 은 시도조차 안 했다. 원편의 그 부분은 지금도 그때와 같은 상태로 남아 있다.

이걸 흐리지 않는 게 중요하다고 본다. 원편의 문제는 세 층을 한 호흡으로 말해서, 첫째 층의 근거로 셋째 층까지 딸려 오게 만든 것이었다. 첫째 층이 참인 것과 셋째 층이 참인 것은 다른 크기의 주장이다.

이 샘플이 안 한 것

원편의 정직 절 네 조건은 유지한다. 만들어 보고 더 알게 된 것을 적는다.

"같은 모양"을 지키는 어려움은 사람 쪽이 아니라 형식 쪽에도 있다. 원편은 "바쁜 봄날에 노트를 펴 칸을 맞춰 적기는 어렵다"고 사람의 문제로 봤다. 실제로 만들어 보니 칸을 정하는 사람이 무엇을 칸으로 삼을지 틀리면 그 뒤가 전부 어긋난다. unit 을 칸으로 안 뒀으면 화씨 센서가 들어오는 순간 규칙이 스무 배 어긋난 값을 받는다. 어느 칸을 둘지가 설계의 전부다.

이 글에는 새 샘플이 없다. 인용한 것은 전부 앞선 편들에서 만든 것이다.

농가 서사는 원편의 것이고 취재가 아니다. 익명 서술이라 실존 인물 문제는 없지만, 관측으로 읽히지 않게 이 글에서는 예시로만 인용했다.

"지식 계층"이라는 규약의 실체는 이 시리즈가 다루지 않았다. 원편이 그 층을 예고했고, 여기서 보인 여섯 칸은 그 층의 아주 아래쪽 한 겹이다. 그 위가 어떻게 생겼는지는 아직 모른다.

겹쳐 놓을 수 있게 두는 일

원편은 이렇게 닫았다 — 경험은 보존이 아니라 증식한다고.

여섯 달 뒤에 한 줄을 붙인다. 증식하려면 먼저 겹쳐 놓을 수 있어야 하고, 겹쳐 놓을 수 있으려면 칸이 같아야 하고, 칸이 같으려면 누군가 그 칸을 잘 골라 두어야 한다.

여섯 칸이었다. 그중 하나(unit)를 빼먹었다면 나머지 다섯은 소용이 없었을 것이다. 화씨 값이 섭씨 자리에 그대로 앉았을 테니까.

증식은 저절로 되지 않는다. 다만 저절로 될 수 있는 자리를 만들어 두는 일은 할 수 있고, 그건 대단한 기술이 아니라 칸 하나를 더 두는 일이었다.


makemind.dev 「탐구」 — 같은 모양이 실제로 여섯 칸이었음을 보였다.

Twitter