작동 원리

방문자가 "좀 더 알아봐 줘"라고 칠 때 벌어지는 일

요청을 직접 치는 것과 메뉴에서 고르는 것의 결과가 달라서는 안 됩니다. 키워드 목록으로 하면 일곱 개 언어에서 반드시 새고, 메시지마다 모델에 물으면 느리고 비쌉니다. 무엇을 측정했는지, 라우터가 왜 두 단계인지, 그리고 문서가 열려 있을 때 같은 문장이 왜 다른 길로 가는지.

입력창 옆의 +가 기능 메뉴입니다 — 더 깊이 조사하기, 문서 써 주기, 사람 연결하기. 대부분은 이 메뉴를 열지 않습니다. 대신 요청을 그냥 칩니다 — "research it", "查查看", "もっと深く調べて". 친 것과 고른 것의 결과가 다르면, 이 메뉴는 장식이 됩니다.

그래서 플랫폼은 입력된 메시지를 같은 기능으로 라우팅합니다. 이 페이지는 그 방법에 관한 것입니다. 가장 먼저 떠오르는 두 가지 구현이 모두 실패하는데, 비슷한 것을 만들기 전에 그 실패를 알아 둘 가치가 있습니다.

키워드 목록이 지는 이유

트리거 문구 목록은 지원하는 모든 언어에서 맞아야 하고, 사람들이 실제로 치는 방식을 견뎌야 합니다.

  • reserach it please — 철자가 틀렸고, 목록은 하나도 맞히지 못합니다.
  • "研究一下呗" — 아무도 추가할 생각을 못 한 표현.
  • go deeper on that one — 목록의 단어가 하나도 등장하지 않습니다.

문구는 계속 추가할 수 있습니다. 할 수 없는 건 다 채우는 것입니다. 언어가 하나 늘 때마다 목록은 배로 불어나고, 놓친 것은 소리 없이 지나갑니다. 방문자는 요청을 쳤고, 평범한 답을 받았고, 그 일을 처리해 줄 기능이 있었다는 사실을 알 방법이 없습니다.

메시지마다 모델에 묻는 것도 지는 이유

또 다른 뻔한 방법 — 메시지마다 작은 모델에게 "이 사람이 기능을 부르고 있는가"를 묻는 것 — 은 정확도 는 충분하지만, 모든 메시지 앞에 모델 호출을 하나 놓습니다. 그 대다수는 누가 봐도 평범한 질문입니다. 방문자가 체감하는 지연이고, 답이 애초에 뻔했던 메시지에 쓰는 비용입니다.

두 단계: 값싼 문지기, 그다음 판정

라우터는 임베딩 문지기 + 모델 판정입니다.

1단계 — 임베딩. 각 기능에는 몇 개의 앵커 문구가 있고, 공유되는 반례 앵커 — 트리거 문구와 의미상 가까운 일상적인 응답 — 도 있습니다. 메시지는 양쪽 모두와 비교됩니다. 임베딩은 다국어라서 앵커 한 벌이 일곱 언어를 덮습니다. *"深挖一下"*와 *"research it"*은 공간의 같은 영역에 떨어집니다. 어느 쪽과도 가깝지 않으면 라우터는 여기서 멈추고, 모델은 한 번도 호출되지 않습니다.

2단계 — 모델. 버튼을 누르는 것처럼 보이면, 작은 모델이 후보 중 하나를 고르거나 없음이라고 답합니다.

순서가 중요하고, 처음 시도했던 것과 정반대입니다. 임베딩은 "이 문장이 요청의 모양인가"에는 강하고 "이 사람이 기능을 쓰려는 것인가, 기능에 대해 묻는 것인가"에는 약합니다 — How does your deep research feature work?는 진짜 트리거와 똑같아 보입니다. 그리고 바로 그 구분이 모델이 잘하는 일입니다. 그래서 값싼 단계가 거르고, 정확한 단계가 결정합니다.

반례 앵커는 무엇을 위한 것인가

앵커만으로는 tell me moredig deeper를 가를 수 없습니다 — 의미상 정말로 가깝기 때문입니다. 가르는 것은 tell me more가 반례 쪽에 있다는 사실입니다. 최근접 이웃이 트리거가 아니라 평범한 응답이 됩니다. 두 부류는 테스트에서 오작동한 뒤에 추가된 것입니다.

부류없을 때 벌어진 일
짧은 후속 질문and in Tokyo?심층 조사로 라우팅됨
낯선 고유명사에 대한 질문what is ANVISA"가서 찾아봐"로 읽힘
같은 주제의 긴 질문"我这个产品在当地属于哪一类"아무도 요청하지 않은 문서를 쓰기 시작
"방금 말한 것 정리해 줘""把刚才说的整理一下发我邮箱""새 문서를 써라"로 읽힘

세 번째가 가장 시사적입니다. 문서 써 주기의 앵커는 긴 문장이어야 하고(짧은 앵커는 긴 요청에 대해 점수가 낮습니다), 긴 문장인 이상 그 에이전트의 주제를 필연적으로 끌고 옵니다. 그래서 같은 주제의 긴 질문이 유사도 사다리를 타고 올라옵니다. 실측 0.711 — 진짜로 문서를 요청하던 문장들보다 높은 값이었습니다.

숫자

독립적으로 작성한 110개 샘플(발동해야 할 60개, 발동하면 안 되는 50개), 일곱 언어, 표현은 앵커와 일부러 다르게 썼습니다.

라우터정확도
임베딩만84.5%
임베딩 문지기 + 모델 판정95.5%

문지기의 문턱값은 취향으로 고른 것이 아니라, 같은 샘플에 대해 값마다 전부 돌려 본 결과입니다.

문턱값모델 호출잡아낸 진짜 요청(60개 중)오발동(50개 중)
0.00110609
0.45100607
0.5588605
0.6077594
0.7071593

0.55는 진짜 요청을 아직 하나도 잃지 않은 마지막 줄입니다. 그 위로는 오발동을 하나 줄일 때마다 진짜 요청 하나를 대가로 내야 하고, 이 표본 크기에서 한두 개 차이는 잡음입니다 — 재현율을 잡음과 바꾸지는 않습니다.

같은 문장, 두 가지 의미

"브라질 경로에 대한 절을 하나 추가해 줘."

문서가 열려 있지 않다면 이건 무언가를 써 달라는 요청입니다. 오른쪽에 문서가 열려 있다면 문서를 고쳐 달라는 요청입니다. 같은 말, 다른 답 — 그리고 틀렸을 때의 대가는 생각보다 큽니다. 보고서를 다듬던 방문자가 절을 추가해 달라고 했더니 두 번째 별개의 문서가 만들어졌습니다.

첫 번째 수정은 규칙이었습니다 — 문서가 열려 있는 동안에는 문서 쓰기로 절대 라우팅하지 않는다. 버그는 멎었지만 다른 것이 망가졌습니다. 정말로 두 번째 문서를 원하던 사람이 더 이상 그것을 요청할 수 없게 된 겁니다. 두 번째 규칙(차트 요청에는 문자 그대로 "차트"라는 단어가 있어야 한다)도 같은 모양, 같은 대가였습니다. *"그 숫자들을 다른 방식으로 보여 줘"*를 알아보지 못했습니다.

규칙 위에 규칙을 쌓는 것은, 결정을 내리는 부품이 잘못됐다는 신호입니다. 이제 맥락은 판정 단계 자체로 들어갑니다 — 모델에게 문서가 열려 있다고 알려 주고 선택지를 하나 더 줍니다: 열린 문서를 편집. 이것은 어디로도 라우팅하지 않습니다. 문서 편집 도구는 이미 그 턴에서 사용할 수 있고, 그 도구들이 맡아야 할 일이기 때문입니다. 원래의 두 버그는 그대로 고쳐진 채이고, 두 개의 진짜 요청도 되살아났습니다.

의도적인 비대칭이 하나 있습니다. 모델에 닿지 못해 임베딩 추측으로 물러나야 할 때, 문서가 열려 있으면 기준을 높입니다. 거기서 잘못 라우팅하면 턴 전체가 납치되기 때문입니다 — 21일 심사 기간을 논의하던 방문자가 *"21일 심사 기간의 차트는 그릴 수 없습니다"*를 받게 됩니다. 반면 같은 실수가 평범한 대화에서 일어나면 기껏해야 불필요한 차트 한 장입니다.

당신의 에이전트에게 의미하는 것

  • 에이전트 메뉴에 있는 기능만 입력으로 발동할 수 있습니다. 심층 조사를 켜지 않았다면, 방문자가 요청해도 평범한 답이 갈 뿐 사지 않은 기능이 동작하지는 않습니다.
  • 트리거 문구를 직접 쓸 필요가 없습니다. 테넌트별 키워드 목록은 어떤 언어에도 없습니다.
  • 대상이 필요한데 문장에 없는 요청은 추측이 아니라 "입력창에 채워진 채로" 돌아옵니다. 주제가 분명하지 않은 채 *"research it"*이라고 친 사람은 입력창에 주제가 들어간 것을 보고 보내기 전에 고칠 수 있습니다 — 잘못 추측했을 때의 대가가 1분 낭비에서 두 단어 수정으로 내려갑니다.