Knock Blog

Jev in Practice: 논문 검색 에이전트에 넣어보기

12 min read6 views

개념은 알겠는데, 실제로 써도 되는 걸까?

Jev는 TypeSafe가 만든 판단 전용 모델입니다. 문장을 쓰는 대신, 정해진 선택지 위에 확률 분포를 돌려줍니다. 지난 글에서는 이것을 생성하지 않는 AI, 즉 f(state, question) → typed decision + probability로 정리했습니다. 여기서 state는 모델에게 보여주는 판단 재료이고, 이 글에서는 논문의 제목, 카테고리, 초록입니다. 개념은 충분히 매력적이었지만, 글은 "실증은 아직"이라는 문장으로 끝났습니다. 계산같은 추론이 필요한 항목은 어렵기에, 어디에 적용해볼지 고민하던 중 자동으로 관심사를 입력하면 논문을 찾아주는 프로젝트를 만들어보면 어떨까 생각이 들었습니다.

그래서 회사에서 토이 프로젝트로 하나 만들어봤습니다. 확인하고 싶었던 것은 두 가지입니다.

Jev가 약속하는 스키마, 즉 typed decision과 calibrated probability만 믿고 workflow를 짤 수 있는가?

같은 판단을 생성형 모델에 맡길 때와 비교해서 *비용과 처리속도**에서 실제로 이득이 있는가?

대상은 매일 arXiv를 훑어 관심 분야 논문을 골라 Teams 채널에 올려주는 논문 검색 에이전트입니다. 코드는 GitHub에 있습니다.

* [nhchoi98/demo_trend_searcher](https://github.com/nhchoi98/demo_trend_searcher)

관심 분야는 world model, physical AI, 그리고 NVIDIA Cosmos 계열이고, 하루에 들어오는 후보는 700편 안팎입니다. 700편을 매일 생성형 모델로 읽히면 비용도 부담이지만, 그보다 판단 근거가 자유 텍스트로 돌아온다는 점이 더 불편합니다. 프로그램이 받아서 쓰기가 어렵기 때문입니다. 지난 글의 표현을 빌리면, 이 에이전트가 필요로 하는 것은 relevance = core, topic = physical-ai, 그리고 이 판단을 어느 정도까지 믿어도 되는가?에 가깝습니다. Jev가 맞는 자리라고 생각했습니다.

에이전트는 두 개의 loop로 되어 있습니다. Loop 1은 판단(triage), Loop 2는 요약입니다. Jev는 판단만 돌려주므로 Loop 1만 맡고, Loop 2는 GPT-5가 맡습니다. 처음에는 Jev 키가 없으면 GPT로 대신 판정하도록 만들려다가 그만뒀습니다. 판정자가 둘이면 쌓이는 로그의 기준도 섞이고, 이 실험의 목적이 Jev 검증이니 Jev를 필수로 강제했습니다.

지난 글의 개념을 어디에 썼을까?

Jev에 보낼 수 있는 질문은 세 가지뿐입니다. 선택지 중 하나를 고르는 choice, 진술이 참일 확률을 묻는 noul, 등급 서술 사이에서 점수를 매기는 score입니다. 아래 표는 지난 글에서 이름만 정리했던 개념들이 실제 코드의 어디에 들어갔는지를 대응시킨 것입니다.

질문은 어떻게 선언할까?

질문은 코드로 선언합니다. 종류가 세 가지밖에 없으니 선언도 단순합니다. 관련도 외에 주제와 기여 유형도 같은 choice 질문이고 선택지만 다릅니다. 아래에는 세 종류를 하나씩만 남겼습니다.

const label: ChoiceQuestion = {

  type: "choice",

  instructions: `A reader follows this research interest: ${config.interest}

How relevant is this paper to that interest? Most papers are unfiltered daily submissions, so most are irrelevant.`,

  options: {

    core: "Directly about the interest; the reader would want to read it.",

    adjacent: "A neighbouring area with a concrete, stated link to the interest.",

    irrelevant: "No real link to the interest, or only shared vocabulary.",

  },

};

const significance: ScoreQuestion = {

  type: "score",

  instructions: "Judging only from what the abstract claims, how significant is the contribution for someone following the area?",

  levels: [

    "Incremental: a narrow improvement or a routine application.",

    "Solid: a clear contribution that specialists in the area would want to know about.",

    "Notable: a new capability, a large-scale model or dataset, or markedly stronger results.",

    "Potentially field-shaping: likely to change how people in the area work.",

  ],

};

const tags = {

  "tag:world-model": { type: "noul", instructions: "Is this statement true of the paper? The paper learns or uses a model that predicts how an environment evolves." },

  // ... 10 more

};


label의 마지막 문장은 사전 확률을 알려주는 장치입니다. 카테고리 전체를 받아오니 대부분이 무관하다는 것을 미리 말해 둡니다. 선택지 세 개에는 각각 설명이 붙고, 관심사 문장은 설정 파일에서 그대로 들어갑니다. Jev는 "의도한 질문이 아니라 적힌 질문에 답한다"고 문서에 나와 있어서, 판정이 이상하면 코드가 아니라 이 문구부터 고치게 됩니다.

Jev에게 판단을 어떻게 맡길까?

Jev는 채팅 모델이 아니라서 요청도 프롬프트 한 덩어리가 아닙니다. "무엇을 볼지"(state)와 "무엇 중에 고를지"(questions)로 나뉩니다. 실제로 보내는 요청을 펼치면 이렇습니다. 질문 15개 중 세 종류만 하나씩 남겼습니다.

{
  "model": "jev-latest",
  "state": {
    "title": "ZYT-World: A Real-Time Controllable World Model ...",
    "categories": ["cs.CV", "cs.RO"],
    "abstract": "..."
  },
  "questions": {
    "label": {
      "type": "choice",
      "instructions": "A reader follows this research interest: ... Most papers are unfiltered daily submissions, so most are irrelevant.",
      "criteria": {
        "core": "Directly about the interest; the reader would want to read it.",
        "adjacent": "A neighbouring area with a concrete, stated link to the interest.",
        "irrelevant": "No real link to the interest, or only shared vocabulary."
      }
    },
    "significance": {
      "type": "score",
      "instructions": "Judging only from what the abstract claims, how significant is the contribution for someone following the area?",
      "criteria": ["Incremental: ...", "Solid: ...", "Notable: ...", "Potentially field-shaping: ..."]
    },
    "tag:vla": {
      "type": "noul",
      "instructions": "Is this statement true of the paper? The paper proposes, trains or evaluates a vision-language-action model."

    }

  }

}

state에는 제목, 카테고리, 초록만 넣습니다. 저자, 날짜, 링크는 판단과 무관하므로 뺍니다. 지난 글에서 "불필요하게 큰 state"가 failure mode에 있다고 적었는데, 그 조언을 따른 것입니다. 응답은 질문 이름별로 숫자만 옵니다. 아래 input_tokens는 질문 세 개만 남긴 축약 요청 기준이고, 실제 15개 질문에서는 편당 1,500 토큰 안팎입니다.

{
  "model": "jev-1.13.0",
  "answers": {
    "label": { "type": "choice", "choice": "core", "confidence": 0.78,
               "probabilities": { "core": 0.85, "adjacent": 0.10, "irrelevant": 0.05 } },
    "significance": { "type": "score", "score": 1.6, "confidence": 0.55 },
    "tag:vla": { "type": "noul", "noul": 0.08 }
  },
  "usage": { "input_tokens": 812 }
}

choice는 고른 라벨과 선택지별 확률을, score는 등급 4단계를 0~3으로 환산한 확률 가중 점수를, noul은 그 진술이 참일 확률 하나를 돌려줍니다. noul은 선택지가 둘뿐이라 별도의 confidence 없이 확률 자체가 그 역할을 합니다. 문장이 한 줄도 없습니다. 파싱할 것도, 형식이 깨질 것도 없습니다. 응답 처리 코드는 질문마다 답이 있고 타입이 맞는지 확인한 뒤 그대로 넘기는 것이 전부입니다. 이 원본 답이 호출당 한 줄로 decisions.jsonl에 남습니다. 뒤에서 비교 실험이 가능했던 것도 이 로그 덕분입니다.

confidence는 어디서 올까?

만들면서 저 스스로 가장 헷갈렸던 부분이라 따로 적습니다. confidence를 받으려면 요청에 무언가를 보내야 하는 줄 알았는데, 아닙니다. 요청에는 confidence와 관련된 것이 아무것도 없고, 응답에만 붙어 옵니다. TypeSafe 문서의 정의는 선택지가 n개일 때 다음과 같습니다.

confidence = (n × 최대 확률 − 1) / (n − 1)

3지선다에서 최대 확률이 0.85(3 × 0.85 − 1) / 2 = 0.78입니다. 세 선택지가 고르게 1/3씩이면 0, 한쪽에 다 몰리면 1입니다. 최대 확률 0.90이면 0.85가 됩니다. 뒤에서 "경계" 문턱으로 쓰는 0.85도 이 환산으로 읽으면 "최대 확률 0.9"라는 뜻입니다.

여기서 주의할 점이 하나 있습니다. confidence는 관련도가 아니라 분포가 얼마나 한쪽으로 쏠렸는지입니다. "확실히 adjacent"도 confidence는 높습니다. 그래서 리포트에 adjacent (0.91)이라고 찍혀 있으면 "인접 분야인 것이 확실하다"는 뜻이지 "관련도가 0.91"이라는 뜻이 아닙니다. 관련도는 분포 자체에서 따로 계산합니다.

분포를 그대로 쓰면 뭐가 달라질까?

지난 글에서 가장 강조했던 것이 calibration이었습니다. 실제로 써보니 "우승 라벨"보다 분포 자체가 훨씬 쓸모 있었습니다. 예를 들어 어떤 논문의 관련도 분포가 다음과 같이 돌아왔다고 가정해보겠습니다.

core: 0.41, adjacent: 0.52, irrelevant: 0.07

우승 라벨은 adjacent입니다. 그런데 프로그램이 알고 싶은 것은 "이 논문을 리포트에 넣어야 하는가?"이고, 그 답은 coreadjacent를 합친 0.93에 더 가깝습니다. core 0.3, adjacent 0.3, irrelevant 0.4처럼 1등이 irrelevant인 논문도 관련 쪽 합은 0.6이라 후보에 남습니다. 그래서 포함 여부와 우선순위를 코드에서 이렇게 만듭니다. significance는 0~3점이라 3으로 나눠 0~1로 맞추고, 가중치 0.60.4, 하한 0.82는 모델이 정해 준 값이 아니라 리포트 분량을 보며 제가 직접 잡은 숫자입니다. 하한이 어떻게 이 값이 됐는지는 뒤에서 따로 이야기하겠습니다.

const includeProbability = p.core + p.adjacent;                  // 리포트에 넣을 확률

const expectedRelevance  = p.core  1 + p.adjacent  0.5;        // 관련도 기대값

const priority = 0.6  expectedRelevance + 0.4  significance / 3;

// 저자 h-index 항은 뒤에서 하나 더 붙습니다

const included   = includeProbability >= 0.5 && priority >= 0.82;

const borderline = included && label.confidence < 0.85;          // 리포트에 "경계" 표시

모델 호출은 한 번이고, 판단을 합치는 것은 함수 하나입니다. Jev에게 "앞의 답을 보고 최종 판단해 줘"라고 다시 묻지 않습니다. 지난 글에서 Jev가 숫자 비교와 여러 단계 추론에 약하다고 했으니, 판정 결과를 다시 Jev에 넣어 종합시키는 구조는 피했습니다. TypeSafe 문서가 권하는 composite scoring 방식이기도 합니다. 가중치와 문턱이 코드에 그대로 보이니 튜닝도 코드 수정이고, 실행 사이에 규칙이 흔들리지 않습니다. 지난 글에서 "Jev의 역할은 workflow 전체를 관리하는 것이 아니라, 특정 지점에 필요한 judgment를 제공하는 것"이라고 적었는데, 그 문장이 그대로 코드 모양이 됐습니다.

판단과 생성은 어떻게 나눴을까?

앞서 말한 판단과 생성의 분리는 코드에서 인터페이스 두 개로 나타납니다. DecisionBackend는 state와 질문을 받아 typed answer를 돌려주고, TextBackend는 prose를 씁니다. Loop 1은 앞의 것만, Loop 2는 뒤의 것만 사용합니다. Loop 2에는 제목과 초록만 주고 링크, 저자, 인용은 쓰지 말라고 지시합니다. 모델이 지어낸 URL을 막기 위해서이고, References는 arXiv 피드 메타데이터로 프로그램이 붙입니다.

지난 글에 없던 숫자는 어떻게 정했을까?

지난 글에 없던 것도 두 개 붙였습니다. 둘 다 모델이 아니라 코드가 정하는 숫자입니다.

인용 수 같은 외부 신호도 넣을 수 있을까?

중요도를 Jev의 significance 하나에만 맡기기는 불안했습니다. 초록만 보고 매기는 점수이기 때문입니다. 그래서 Jev와 무관한 신호를 하나 더 넣었습니다. 실행 시작 때 그날 논문의 arXiv id를 Semantic Scholar 배치 API에 한 번에 보내 저자 최대 h-index를 받고, 40으로 나눈 값을 최대 1로 잘라 0~1로 만든 뒤 가중치 0.15로 priority에 더합니다. 앞 코드의 priority에 이 항이 더해진 것이 실제 식입니다.

여기서 설계 원칙이 하나 생겼습니다. 모르는 값은 0이 아니라 제외입니다. 제출 후 며칠은 색인이 안 된 논문이 많습니다. 도입 당일 리포트에 실린 25편 중 저자 h-index를 받아올 수 있었던 논문은 10편뿐이었습니다. 그런 논문을 0점으로 치면 신선한 논문일수록 불이익을 받습니다. 그래서 h-index를 모르면 그 항과 가중치를 함께 빼고 나머지 둘로 평균합니다. 빠진 항이 있어도 점수 범위가 흔들리지 않도록, 합산한 값은 항상 실제로 사용한 가중치의 합으로 나눕니다. 세 항을 모두 쓰면 그 합이 0.6 + 0.4 + 0.15 = 1.15입니다. 예를 들어 label 분포가 core 0.85, adjacent 0.10, significance1.6, h-index가 20이면 이렇게 됩니다.

포함 확률 0.95는 기준을 넘지만 priority 0.72는 하한 0.82에 못 미쳐 탈락입니다. 관련은 확실한데 기여도가 중간이라서입니다.

리포트가 너무 많으면?

첫 실행에서는 하루치 리포트에 182편이 실렸습니다. 읽을 수 있는 양이 아닙니다. 그런데 이걸 줄이는 데 모델을 건드릴 필요가 없었습니다. priority 하한을 0.82로 올리고 토픽과 상관없이 점수순 한 목록으로 정렬하니 25편이 됐습니다. 앞 코드에 적힌 0.82가 바로 이때 정해진 값입니다. 판단은 그대로이고, 그 판단을 어디까지 보여줄지는 코드의 숫자 하나입니다. 원본 확률이 로그에 남아 있으니 숫자를 바꾸면 이전 날짜 리포트도 다시 만들 수 있습니다. 실제로 이 글의 리포트는 문턱을 올린 뒤 다시 생성한 것입니다.

어떻게 비교했을까?

여기까지가 Jev로 짠 workflow입니다. 이제 두 번째 질문으로 넘어갑니다. 같은 판단을 GPT-5에 맡기면 비용과 처리속도가 어떻게 달라지는지, 그리고 싸고 빠른 것이 의미가 있으려면 먼저 확인해야 할 것, 즉 두 모델의 판정이 실제로 비슷한지를 같이 봤습니다.

애초에 비교가 가능할까?

이 질문을 스스로에게 먼저 했습니다. 가능했던 이유는 세 가지입니다.

* 로그가 호출 단위입니다. decisions.jsonl에 호출 한 번이 한 줄로 남고, 논문 id와 입력 해시가 같이 있습니다. 어떤 backend가 어떤 입력에 어떤 답을 했는지 나중에 조인할 수 있습니다.

* 판단 인터페이스가 분리되어 있습니다. 생성형 모델에게 같은 질문 형태를 JSON schema로 흉내내게 하면 DecisionBackend 구현체가 하나 더 생긴 셈이고, 같은 loop를 두 backend로 돌릴 수 있습니다.

* 초록은 다시 받으면 됩니다. 판정 결과에는 초록을 저장하지 않으므로, 그날 논문 id를 arXiv에서 다시 받아옵니다. 이미 답이 있는 논문은 건너뛰어서 중간에 끊겨도 다시 돌리면 이어집니다.

그래서 compare 명령 하나로 하루치 729편을 GPT-5에 같은 15개 질문으로 다시 물었습니다. 요약(Loop 2)은 돌리지 않았으니 비용은 판정 호출뿐입니다.

여기서 한 가지 주의할 점이 있습니다. GPT-5는 structured output으로 라벨과 confidence를 써내지만, 그 confidence는 모델이 자기 자신에 대해 적은 숫자이지 출력 분포가 아닙니다. 분포가 없으니 포함 확률도 0 아니면 1이 됩니다. 그래서 확률끼리는 비교하지 않았습니다. 비교한 것은 라벨, 시간, 비용이고, 중요도는 분포가 아니라 0~3 점수끼리만 맞춰 봤습니다.비용과 처리속도는 어땠을까?

두 번째 질문에 대한 답부터 보겠습니다. 첫 번째 질문(스키마)은 확률이 약속대로인지 확인해야 답할 수 있고, 그 확인에는 아래 비교 데이터가 먼저 필요하기 때문입니다. 아래에서 gate는 하루치 후보 전체를 한 번 판정해 통과시킬지 거를지 정하는 Loop 1 한 바퀴를 말합니다. 두 backend에 같은 729편을 돌린 결과입니다.

보낸 내용은 같지만 토크나이저가 달라 입력 토큰은 3.8% 차이가 납니다. 차이는 출력에서 납니다. Jev는 분포만 돌려주고 생성이 없습니다. 출력 토큰은 과금 대상도 아니라서, 질문을 15개로 쪼개도 비용은 입력 토큰 그대로입니다. GPT-5는 reasoning 토큰을 쓰고 JSON을 써냅니다. 시간 차 2.4배는 이 점과 맞물려 보이지만, 사업자와 인프라가 다르고 각각 한 번씩만 돌린 수치이므로 원인을 단정하지는 않겠습니다.

비용은 같은 729편의 gate 한 번에 GPT-5 $2.80, Jev $0.036으로 약 78배 차이입니다. 다만 두 숫자의 성격은 다릅니다. GPT-5 쪽은 청구된 실측값입니다. Jev 쪽은 TypeSafe 콘솔의 당일 합계(2,729,768 토큰에 $0.0906)를 이 실행분 토큰 비율로 나눈 추정치이고, 합계에는 이 실행 외의 호출도 들어 있습니다. 그리고 격차의 상당 부분은 모델 효율이 아니라 "출력 토큰을 과금하지 않는다"는 과금 정책에서 나옵니다. 정책이 바뀌면 이 배수도 바뀝니다.

그런데 라벨은 같을까?

싸고 빠른 것이 의미가 있으려면 판정이 비슷해야 합니다. 729편의 일치율입니다.

혼동 행렬은 어떻게 읽을까?

라벨이 갈린 20%가 어디서 갈렸는지는 혼동 행렬로 봅니다. 기준은 단순합니다. 같은 논문에 대해 Jev가 붙인 라벨을 행, GPT-5가 붙인 라벨을 열로 놓고 편수를 셉니다. 대각선이 일치, 대각선 밖이 불일치입니다.

읽는 법은 이렇습니다. 둘째 행 첫째 열의 78은 "Jev는 adjacent라 했는데 GPT-5는 core라 한 논문이 78편"입니다. 행과 열 모두 core에서 irrelevant로 관련도가 내려가는 순서이므로, 대각선 왼쪽 아래 칸은 GPT-5가 더 관련 있다고 본 경우이고 오른쪽 위 칸은 Jev가 더 관련 있다고 본 경우입니다.

이렇게 놓고 보면 방향이 뚜렷합니다. 149편이 갈렸고, 그중 145편은 GPT-5가 더 높게 봤습니다(한 칸 위 140편, 두 칸 위 5편). Jev가 더 높게 본 것은 4편뿐이고, Jev가 core라고 한 것을 GPT-5가 내린 경우는 한 건도 없습니다. GPT-5는 "robot"이나 "simulation" 같은 단어가 보이면 관련이 있다고 보는 경향이 있었습니다.

갈린 것은 누가 맞을까?

debate로 하면 안 될까?

처음에는 에이전트 여럿에게 두 답을 보여주고 토론시켜 볼까 했습니다. 그런데 이 방식에는 anchoring 문제가 있습니다. 상대의 답을 보면 그 답에 끌리기 마련이고, 토론의 결론이 "누가 맞는가"가 아니라 "누가 더 그럴듯하게 말했는가"로 흐릅니다. 그래서 블라인드로 바꿨습니다.

Claude Fable 5.1 에이전트 3개에게 갈린 149편의 초록과 Jev와 똑같은 질문문을 주고, 두 모델의 답은 보여주지 않은 채로 라벨을 매기게 했습니다. 세 심판의 다수결을 판정으로 삼았습니다. 149편 중 113편은 만장일치였고 나머지 36편은 2대 1이었으며, 셋이 완전히 갈린 논문은 없었습니다.

GPT-5가 irrelevant를 위로 올린 67편은 전부 심판이 Jev 편이었습니다. "둘 다 아님" 11편은 Jev가 adjacent, GPT-5가 core, 심판은 irrelevant라고 한 순수 로보틱스 논문들입니다. Jev도 로보틱스에 조금 후한 편이지만 adjacent까지라서 우선순위에서 걸러집니다.

여기서 짚어둘 점이 세 가지 있습니다.
첫째, 심판도 모델이고 두 후보보다 큰 모델입니다. 사람이 매긴 정답은 아니고, 셋이 같은 모델이라 오차도 독립이 아닙니다. 둘째, 채점한 것은 갈린 149편뿐입니다. 둘의 답이 같았던 580편은 보지 않았으므로, 이 결과는 Jev의 정확도가 아니라 "갈릴 때 어느 쪽이 더 그럴듯했는가"에 대한 답입니다.
셋째, 심판에게 준 질문문에는 Jev에게 준 것과 같은 "대부분은 무관하다"는 사전 문장이 들어 있습니다. 갈린 149편 중 145편이 GPT-5가 더 높게 본 경우였으므로, 이 문장이 심판을 낮은 쪽, 즉 Jev 쪽으로 밀었을 가능성을 배제할 수 없습니다. 사전 문장을 뺀 질문문으로 다시 매기는 것이 다음 확인 과제입니다. 그래도 두 모델의 답을 보지 않고 매겼고 넷 중 셋은 만장일치였으니, 사람이 149편을 다 읽기 전까지는 쓸 만한 대용이라고 생각합니다. 판정 정확도만 놓고 보면 가장 큰 생성형 모델이 가장 낫겠지만, 하루 729편의 gate에 그 모델을 매일 돌릴 수는 없습니다.

confidence는 갈릴 자리를 가리켰을까?

첫 번째 질문에 대한 답입니다. 정답이 없으므로 calibration 자체, 즉 "0.8이면 비슷한 사례 중 80%가 맞는가"는 확인할 수 없습니다. 대신 confidence가 갈릴 자리를 예고하는지를 봤습니다. Jev가 붙인 라벨 confidence 구간별로 GPT-5와의 일치율을 나눈 것입니다.

확신 구간에서는 거의 갈리지 않고, 갈리는 것은 모델 스스로 낮은 확률을 붙인 곳에 몰려 있습니다. 다만 아래 두 구간은 44%와 47%로 순서가 뒤집혀 있어, "확률이 낮을수록 더 자주 갈린다"고까지는 말할 수 없습니다. 갈린 것이 곧 틀린 것도 아닙니다. 그래서 심판 결과와 겹쳐 봤습니다. 심판 기준으로 Jev가 틀린 것은 GPT-5 편 11편과 둘 다 아님 11편을 합친 22편인데, 그중 21편이 confidence 0.85 미만이었습니다. 확률이 낮게 나온 자리를 따로 표시해 둘 이유는 충분했습니다.

문턱 0.85는 최대 확률 0.9에 대응하는 값으로 먼저 정한 숫자이고, 위 표의 구간도 그 문턱을 그대로 경계로 쓴 것입니다. 이 표는 0.85가 최적 경계임을 보인 것이 아니라, 이미 고른 경계에서 일치율이 어떻게 나뉘는지를 보여줄 뿐입니다. 다른 문턱과 비교하지는 않았습니다. 경계는 탈락이 아니라 표시이고, 최종 판단은 읽는 사람이 합니다.

이 표의 결론은 확률이 갈릴 자리를 가리켰다는 것까지입니다. 여기에 앞에서 본 것, 즉 질문 15개를 세 가지 primitive로 선언하고 돌아온 분포를 코드가 그대로 받아 포함 여부와 우선순위를 만들었다는 사실을 합치면, 스키마 약속 위에 workflow를 짜도 된다고 말할 수 있습니다.

한계는 없었을까?

심판 기준으로 Jev가 틀린 22편은 방향이 갈립니다. 15편은 irrelevantadjacent로 한 칸 올렸는데, 전부 adjacent에서 멈추고 core까지 간 경우는 없어서 우선순위 문턱에서 걸러졌습니다. 나머지 7편은 진짜 coreadjacent로 한 칸 낮춘 경우입니다. 전부 confidence가 낮았고 포함 확률은 0.9 이상이었는데, 우선순위 문턱에 걸려 그날 리포트에서 빠졌습니다. 그런 논문을 버린 것은 모델이 아니라 제가 짠 문턱이었습니다. 제어를 코드가 쥔다는 말은, 틀리면 코드가 책임진다는 뜻이기도 했습니다.

그래서 어떻게 이해하면 될까?

처음의 두 질문으로 돌아가 보겠습니다.

* 스키마 약속 위에 workflow를 짤 수 있는가? 그렇습니다. 세 가지 primitive로 질문 15개를 선언했고, 분포를 코드가 받아 포함 여부와 우선순위를 만들었습니다. confidence는 갈릴 자리를 가리켰습니다.

* 비용과 속도에서 이득이 있는가? 관련도 라벨은 80%, 리포트 포함 여부는 90%가 같았고, 그것을 얻는 데 시간은 2.4분의 1, 비용은 약 78분의 1이었습니다. 라벨이 갈린 149편에 대해서는 모델 심판단의 다수결이 85%에서 Jev 쪽을 택했습니다.

하루치, 한 도메인, 사람 정답 없음. 이 세 가지는 이 글이 넘지 못한 선입니다. 리포트된 논문의 인용 수를 30일 뒤에 기록해 두고 있으니, significance와 h-index가 인용을 예측했는지는 다음 글에서 볼 수 있을 것입니다. 그래도 지난 글의 "실증은 아직"에 대한 첫 번째 답으로는 충분하다고 생각합니다. 코드와 그날의 로그, 비교 리포트는 모두 [저장소](https://github.com/nhchoi98/demo_trend_searcher)에에) 있습니다.

Comments

Loading comments...