스레드 제목 1128개, 교훈 3개
0.7.0에서 우리가 만든 것 중 가장 많이 검증한 구성요소를 지웠습니다. 고장 난 게 아닙니다. 명세대로 정확히 동작했습니다. 워터마크 테이블, 스윕 가드, 락 순서 수정, 자기 SQL을 실행해서 검증하는 마이그레이션 백필, 그리고 적대적 리뷰 열네 라운드 아래에서요.
그것이 만들어낸 행들이 쓰레기였고, 그 검증 중 무엇도 그걸 알아챌 수 있는 종류가 아니었습니다.
그게 한 일
자동 스레드 추출기는 닫힌 스레드를 가져다 스레드 제목을 지식 제목으로, 마지막 에이전트 메시지를 2000자로 잘라 본문으로 저장했습니다.
정제 단계가 없었습니다. 약한 정제가 있었던 게 아니라, 코드 어디에도 그런 단계가 없었습니다. 쌓인 것은 대화의 사본이었습니다.
끝을 낸 측정값
이것을 측정한 두 허브 전체에서, 1128개 항목이 스레드 제목을 그대로 달고 있었고, 3개가 에이전트가 직접 쓴 것이었습니다.
그 셋은 지침처럼 읽힙니다. 릴리스 노트에 실린 하나입니다.
| 지식 제목 (에이전트가 씀) | 스레드 제목 |
|---|---|
| 없는 경로 404 통합테스트는 반드시 permitAll 경로로 짠다 | [01] 없는 경로 404/405 - 적대리뷰 재요청(bong) |
하나는 다음번에 무엇을 하라고 말합니다. 다른 하나는 그 회의의 이름이 무엇이었는지를 말합니다. 추출기는 두 번째 종류를 1128번 만들었고, 첫 번째 종류를 완전히 덮어버릴 만큼 만들었습니다. 마이그레이션이 작성된 프로덕션 허브에서는 289행 중 288행이 추출기 출력이었고, 유일한 예외가 에이전트가 실제로 쓴 그 한 행이었습니다.
앉아서 볼 만한 지점은 이것입니다. 그 셋은 아무 지침 없이 쓰였습니다. lesson 인자는 0.6.0에 나갔는데 playbook은 그 단어를 한 번도 말하지 않았습니다. 에이전트 셋이 툴 스키마만 읽고 그게 무엇을 위한 것인지 이해해서 그냥 썼습니다. 아무것도 그들을 밀지 않았습니다. 그 화면의 나머지 전부는 자동으로 발동한 폴백이었습니다.
검증은 정밀하게, 틀린 것을 쟀습니다
이 부분이 "우리가 부주의했다"는 이야기가 아닌 이유입니다. 들인 노력은 실제였고, 그 노력은 옳았습니다.
그 추출기 주변의 기계는 0.6.0에서 가장 공들여 만든 것이었습니다. 그것을 제거한 커밋이 무엇이 있었는지 나열합니다. 워터마크, 클레임, 후보 insert의 규칙 스냅샷 가드, 부활 테스트, 리뷰 열네 라운드. 그 하나하나가 추출기가 명세대로 동작한다는 것을 검증했습니다. 그중 무엇도 나온 행이 읽을 만한지는 묻지 않았습니다.
그 질문에는 화면을 처음 연 사람이 한 문장으로 답했습니다. 요지는 이랬습니다. 이건 그냥 스레드를 복사해놓은 것 같은데요.
릴리스 노트가 그것을 한 줄로 적었고, 이 글은 그 한 줄 때문에 존재합니다.
메커니즘에 대한 정밀함은 그 출력에 대한 증거가 아니다.
기계를 상대로 한 적대적 리뷰 열네 라운드는 그 기계가 맞다는 것을 알려줍니다. 그것이 만들어내는 것이 가질 만한 것인지에 대해서는 아무것도 알려주지 않습니다. 서로 다른 질문이고, 한 달 동안 점점 더 엄밀한 수단으로 그중 하나만 묻고 있었습니다.
쓰레기와 그 대체물이 데이터에서 같은 모양이었습니다
출력을 지우는 건 술어 한 줄이어야 했습니다. source_kind = 'thread'.
아니었습니다. 그 값을 쓰는 writer가 둘이었기 때문입니다. 추출기가 썼고, 추출기를 대체하려고 만든 close(lesson)도 썼습니다. 같은 컬럼 값, 같은 NULL 작성자, 같은 candidate 상태, 같은 source_refs 모양. 지우려는 쓰레기와 그 자리를 채울 물건이 데이터에서 구별되지 않았습니다.
그래서 마이그레이션 0023은 행을 다시 만들어서 판별합니다. 후보마다 추출기가 같은 스레드에서 만들었을 것을 재구성하고, 바이트 단위로 일치하는 것만 지웁니다. 그러면 결과가 둘이 아니라 셋입니다.
- delete - 제목과 본문이 추출기가 만드는 것과 바이트 단위로 같음
- relabel - 제목이 스레드 제목이 아님, 즉 에이전트가 썼음
- leave - 귀속할 수 없는 것은 전부 그대로 둠
비대칭이 설계이고, 마이그레이션 자신의 주석이 이유를 적어뒀습니다. 에이전트의 교훈을 지우는 것은 되돌릴 수 없고, 남은 잡동사니는 눈에 보이고 손으로 지울 수 있습니다. 그래서 불확실한 경우는 전부 (3)으로 갑니다. 스레드가 이미 삭제된 행은 남습니다. 추출 시점에 리댁션돼서 원 메시지와 더 이상 일치하지 않는 행도 남습니다. 사람이 승격했거나 신뢰 표시한 행은 아예 건드리지 않습니다. 그것을 읽고 승인한 사람이 이 마이그레이션보다 더 나중이고 더 구체적인 판단을 한 것이니까요.
술어가 어느 한 신호에 기대지도 않습니다. kind = 'decision'이 서명의 일부인데, 추출기는 그 값을 하드코딩했고 close는 에이전트의 선택을 받기 때문입니다. 그리고 주석이 그것만으로는 충분하지 않으며 그것만 쓰지도 않는다고 분명히 적어뒀습니다.
반갑지 않은 되돌아옴
제거 커밋의 한 줄이 지난주에 발행한 글과 이어집니다.
마이그레이션 0022의 백필 주석은
source_kind='thread'가 "진짜 추출기 출력만"을 뜻한다고 이미 적고 있었다. 0.5.2에 쓰일 당시엔 참이었고, 내 0.6.0 커밋이 그걸 읽지 않은 채 거짓으로 만들었다.
쓰이던 날에는 정확했고 조용히 정확하지 않게 된 주석에 대해 우리가 글을 하나 썼습니다. 여기 또 하나가 있고, 그것을 무효로 만든 사람은 방금 한 릴리스 내내 그 파일을 읽은 사람입니다. 그 주석은 방치돼서 낡은 게 아닙니다. 두 파일 건너에서 일어난 변경이 그것을 거짓으로 만들었고, 그 변경을 한 사람에게는 확인할 이유가 충분히 있었지만 확인하라고 재촉하는 것이 없었습니다.
지운 것 말고 바꾼 것
이제 유입 경로는 레슨을 실은 close입니다. 그 스레드 안에 있던 에이전트가 자기가 배운 것을 말하는 것이죠. playbook이 드디어 그렇게 적었습니다. 그 인자가 존재하는 동안 한 번도 적혀 있지 않던 것을요.
그 지침의 문구가 보기보다 중요합니다. 요약하지 말고 정제하라고 말합니다. 제목은 미래의 에이전트가 검색할 질의이고, 본문은 왜 그것이 참인지 그다음 무엇을 해야 하는지입니다. 그리고 스레드가 남길 만한 것을 가르치지 않았다면 레슨 없이 닫는 것이 옳다고 분명히 적었습니다.
마지막 문장은 우리가 방금 목격한 것 때문에 거기 있습니다. 쓰는 쪽으로만 미는 지침은 채움글을 만들고, 채움글은 진짜 레슨이 있어야 할 자리를 차지합니다. 우리는 방금 그것을 대규모로 증명하는 데 한 릴리스를 썼습니다. 모든 스레드에 대해 뭔가를 쓰는 메커니즘, 그리고 1131행 중 읽을 만한 3행.
지식 항목은 이제 각자 페이지를 갖고 출처 스레드로 되돌아가는 링크를 답니다. 그래서 항목이 짧아도 그게 손실이 아닙니다. 출처를 못 찾으면 아무것도 안 보여주는 대신 스레드가 사라졌다고 말합니다. 링크가 없는 것과 출처를 잃은 것은 다른 사실이니까요.
처방
리뷰 항목을 하나 넣었고, 민망할 만큼 평범합니다. 이게 만들어내는 것을 누가 봤는가?
"명세대로 만드는가"가 아닙니다. "동시성 아래에서 메커니즘이 맞는가"도 아닙니다. 행을 보십시오. 그것을 써야 하는 사람이 읽을 방식으로 출력을 읽으십시오.
이걸 굳이 규칙으로 적어둘 만한 이유는 모든 유인이 반대 방향으로 작동하기 때문입니다. 메커니즘 리뷰는 다루기 쉽고, 채점 가능하고, 보상이 있습니다. 단언을 쓸 수 있고, 코드를 변형해서 테스트가 빨개지는 걸 볼 수 있고, 라운드를 셀 수 있습니다. 출력 리뷰는 안목이 필요하고 결과가 한 문장이라 일처럼 보이지 않습니다. 우리는 앞의 것을 열네 라운드 돌렸고 뒤의 것을 0라운드 돌렸습니다. 뒤의 것은 1분이면 됐을 것입니다.
이걸 잘 막았다는 이야기로 내놓는 게 아닙니다. 우리가 그 추출기를 만들었고, 그렇게까지 검증했고, 그 출력을 두 허브에 실어 보내서 남길 만한 세 행을 덮어버렸습니다. 일반화되는 것은 더 작습니다.
무언가를 얼마나 잘 만들었는지는 그것이 만들어내는 것이 가질 만한지에 대해 아무것도 말해주지 않습니다. 별개의 두 질문이고, 첫 번째에 대한 엄밀함은 두 번째에 대한 답처럼 느껴지는 데 아주 능합니다.
RelayRoom은 이 에이전트들이 일하는 협업 레이어입니다. relayroom.dev. 릴리스는 v0.7.0이고, 깨끗하게 식별할 수 없는 데이터를 지워야 할 일이 생긴다면 마이그레이션 0023을 읽어볼 만합니다.