AI 에이전트로 시장을 분석한다는 것 / 4
market-analyst — 옳은 말은 정보가 아니다
적중률 98%가 나왔다. 좋은 신호가 아니었다. 검증 가능한 주장을 내라고 했더니 에이전트는 틀리지 않는 법을 배웠다
목차
2편에서 데이터가 침묵할 수 없게 만들었고, 3편에서 기준이 침묵할 수 없게 만들었다. 이제 그 위층이다. 다섯 페르소나가 토론하고, 검증 가능한 명제를 발행하고, 시간이 지나면 데이터로 채점받는 층.
1편에서 왜 LLM이 필요한지를 적었다. 정량 게이트는 LLM의 일이 아니고, LLM의 일은 검증 가능한 명제를 만드는 것이라고. 이 글은 그 문장을 정직하게 재심하는 글이다.
결론부터 적으면, LLM은 필요했다. 그런데 내가 만든 진짜 물건은 LLM이 아니었다.
98%
어느 날 적중률을 들여다보다 이상한 숫자를 봤다. 5월에 생성된 명제들의 확인율이 98%였다. 마흔여덟 건이 CONFIRMED, 한 건이 INVALIDATED.
기뻐할 뻔했다. 그런데 같은 화면의 다른 숫자가 63%였다. 최근 90일 기준선. 그럼 5월에 무슨 일이 있었길래 시스템이 갑자기 천재가 됐나.
천재가 된 게 아니었다. 시장을 맞히는 법을 배운 게 아니라, 틀리지 않는 법을 배운 것이었다.
항상 참인 문장들
확인된 명제들을 전부 꺼내 현행 기준으로 다시 채점했다. 사람의 인상이 끼어들지 않도록 재채점은 코드로 돌렸다. 이런 것들이 나왔다.
신용스프레드가 3.3 아래를 유지할 것. 직전 180일 중 98%의 날에 이미 참이었던 조건이다. 이건 예측이 아니라 관찰의 연장이다. 내일도 해가 뜬다고 적어놓고 다음 날 맞혔다고 기록하는 것과 같다.
섹터 상대강도가 어떤 값 위에 있을 것. 그 어떤 값이 생성 시점의 현재값에서 5도 떨어져 있지 않았다. 지금과 거의 같을 것이라는 말이다. 이런 명제가 마흔다섯 건이었다.
5월과 6월의 확인된 명제 여든 건을 전부 재채점했다. 예순 건이 무정보였다. 스무 건만 실제로 정보가 있는 예측이었다.
여기서 이 시스템의 가장 불편한 문제가 보였다. 나는 명제에 "검증 가능할 것"을 요구했다. 그 요구는 정확했고, 에이전트는 그 요구를 완벽하게 만족시켰다. 검증 가능한 명제 중에서 가장 안전한 것은 항상 참인 명제다. 나는 정보를 원했는데, 내가 잰 것은 적중이었다. 그리고 LLM은 내가 원한 것이 아니라 내가 잰 것을 최적화했다.
적중률과 정보량은 다른 축이다. 98% 적중은 정보 0에 수렴한다.
빈 승리를 학습하는 루프
더 나쁜 게 있었다.
이 시스템은 확인된 명제를 에이전트의 학습 재료로 되돌린다. 무엇이 맞았는지를 다음 토론에 넣어주는 구조다. 그런데 맞았다고 기록된 것의 대부분이 빈 승리였다면, 에이전트가 학습하는 것은 시장이 아니라 빈 승리를 만드는 기술이다.
이건 스스로 강화된다. 안전한 명제를 낸다, 확인된다, 그게 좋은 명제라고 학습된다, 더 안전한 명제를 낸다. 성과 지표는 계속 올라가고 시스템은 계속 나빠진다. 재채점을 하면서 오염된 명제에서 나온 학습 기록까지 따로 대조해야 했던 이유다.
누적 평균도 공범이었다. 표본이 쌓일수록 최근의 저하가 평균에 묻힌다. 숫자는 계속 좋아 보였다. 롤링 윈도우로 분리해서 보고 나서야 최근 구간의 하락이 드러났다. 평균은 위로하는 숫자고, 윈도우는 알려주는 숫자다.
고친 곳은 프롬프트가 아니었다
여기서 자연스러운 처방이 하나 있다. 프롬프트를 고치면 된다. "당연한 명제를 내지 마라, 정보량 있는 예측을 해라"라고 쓰면 되지 않나.
안 된다. 그리고 안 되는 이유가 이 글에서 제일 중요한 부분이다.
무엇이 당연한지는 모델이 알 수 없다. 신용스프레드가 지난 180일 중 며칠이나 3.3 아래였는지는 시장 데이터의 속성이지 프롬프트의 속성이 아니다. 모델에게 "당연한 말 하지 마"라고 요구하는 것은, 모델이 접근할 수 없는 사실을 근거로 자기검열하라는 요구다. 성실한 모델일수록 그럴듯하게 실패한다.
그래서 생성이 아니라 심사를 고쳤다. 명제가 만들어지는 시점에 게이트를 세웠다. 목표 조건이 직전 구간의 기저율 밴드 안에 들어오면 생성 자체를 차단한다. 상대강도 목표가 현재값에서 유의미한 거리만큼 떨어져 있지 않으면 차단한다. 자기 자신을 참조하는 지표는 검증 대상에서 제외한다. 현상 유지형 명제는 확인 조건과 같은 엄격함을 유지 조건에도 대칭으로 적용한다.
이 게이트들은 모델의 협조를 구하지 않는다. 기저율은 데이터베이스에서 계산되고, 밴드 안에 들어오는 목표 조건은 모델이 무엇을 의도했든 발행되지 않는다. 프롬프트가 설득이라면 게이트는 조건문이다.
정직하게 덧붙이면, 게이트 이후 무정보 명제가 실제로 몇 건까지 줄었는지 나는 아직 측정하지 못했다. 감사는 5~6월 빈티지만 대상으로 했고, 그 이후 빈티지는 별도 감사 전까지 판정을 비워두고 있다. 추정으로 마킹하지 않는다는 규칙을 스스로에게 적용한 결과다. 그러니 이 글이 말할 수 있는 건 "게이트가 무정보 명제를 없앴다"가 아니라, "무정보 명제가 왜 통과했는지는 규명했고, 같은 경로는 구조적으로 막았다"까지다.
엄격함은 프롬프트에 살지 않는다. 게이트에 산다. 생성자에게 정보량을 요청할 수는 없고, 채점자가 강제할 수 있을 뿐이다.
과거를 고쳐 쓰지 않았다
3편에서 왜곡된 구간의 지표를 다시 계산하지 않고 기록으로 남겼다고 적었다. 여기서도 같은 결정을 했다.
무정보로 판명된 예순 건을 CONFIRMED에서 내리지 않았다. 상태는 그대로 두고 품질 표시만 붙였다. 적중률 집계에서만 뺐다.
당시의 판정 로직으로는 그 명제들이 확인된 게 맞았기 때문이다. 그건 틀린 판정이 아니라 느슨한 기준의 정확한 결과다. 그리고 "이 시스템이 한때 이런 것을 성공이라고 불렀다"는 사실 자체가 가장 값진 학습 데이터다. 기록을 고쳐 쓰면 성능이 좋아지는 게 아니라, 어떻게 속았는지에 대한 증거가 사라진다.
그래서 LLM은 필요했나
필요했다. 여든 건 중 스무 건은 진짜 예측이었다. 정량 게이트로는 절대 나오지 않는 종류의 문장들이다. 어떤 메가트렌드가 어떤 병목을 지나 어떤 종목으로 이어지는지, 그 연결을 문장으로 만들고 검증 가능한 형태로 좁히는 일은 지금도 LLM이 가장 잘한다.
하지만 1편에서 내가 만들었다고 말한 것과 실제로 만든 것은 달랐다. 나는 "시장을 분석하는 에이전트"를 만들었다고 생각했는데, 돌아보면 토론을 고친 횟수보다 토론을 의심하는 장치를 고친 횟수가 많았다. 게이트, 계측, 감사, 그리고 적중률을 어떻게 세는지에 대한 규칙들. 쓸모가 증명되지 않은 부속은 그 과정에서 덜어냈다. 여러 모델을 섞어 쓰던 구성을 하나로 정리했고, 밥값을 못 하던 심사 채널 하나는 공식적으로 없앴다.
LLM을 쓰는 시스템에서 진짜 제품은 생성기가 아니라 채점기다. 생성기는 사서 쓸 수 있고 계속 좋아진다. 채점기는 도메인마다 직접 만들어야 하고, 만들지 않으면 생성기가 채점기의 빈틈을 정확히 찾아낸다. 악의가 있어서가 아니라, 그게 최적화라는 것의 정의라서 그렇다.
2편에서 데이터가, 3편에서 기준이 침묵할 수 없게 만들었다. 이 층에서 한 일은 같은 문장의 세 번째 변주다. 에이전트가 빈말을 할 수 없게 만드는 것.
다음 편에서는 이 모든 것의 마지막 심판대로 간다. 명제가 아니라 돈으로 채점받는 층 — 광망에서 모델 포트폴리오로, 그리고 SPY 대비 알파로. 거기서는 시스템이 나를 속일 방법이 하나 더 있었다.
나는 검증 가능한 주장을 요구했고, 에이전트는 틀리지 않는 법을 배웠다. 잘못 배운 쪽은 에이전트가 아니었다.