파이프라인이 매번 먹는 고정 비용 — 자료를 어디에 두느냐의 문제

앞 글에서 도구 응답이 토큰을 잡아먹는 얘기를 했다. 그건 도구가 말이 많아서 생긴 문제였고, 응답을 깎으니 해결됐다.
그런데 응답을 다 깎고도 남는 비용이 있었다. 이번엔 그 얘기다.
정해진 순서로 돈다는 것
글 하나를 자동으로 뽑으려면 단계가 필요하다. 무엇을 쓸지 고르고, 이미 쓴 건 아닌지 확인하고, 자료를 모으고, 숫자가 맞는지 검증하고, 본문을 쓰고, 올린다.
이 순서는 매번 같다. 같은 순서로 돈다는 건 좋은 일이다. 어디서 틀어졌는지 알 수 있고, 한 단계만 고칠 수 있다.
문제는 매번 같은 비용도 같이 따라온다는 것이다. 글 한 편을 뽑든 다섯 편을 뽑든, 각 단계는 자기가 필요한 자료를 어딘가에서 읽어온다. 그리고 그 자료가 대화에 남으면, 뒤에 오는 모든 단계가 그걸 계속 짊어진다.
앞 글의 문제가 “도구가 뱉는 게 크다”였다면, 이번 문제는 “자료가 잘못된 곳에 머문다”였다.
전량을 받아서 참·거짓만 쓰고 있었다
제일 크게 잡아먹던 게 중복 확인이었다.
이 사이트에 같은 소재를 또 쓰면 안 되니까, 소재를 고르기 전에 “이거 이미 썼나”를 확인해야 한다. 그런데 그 확인 방법이 발행 색인을 통째로 받아오는 것이었다. 지금까지 올린 글 목록을 전부 가져와서 그 안에 있는지 보는 식이다.
전 사이트 색인이 20k 토큰쯤 됐다. 실측해보니 이 조회 하나가 발행 도구 전체 토큰의 87퍼센트를 차지하고 있었다.
정작 필요한 건 참이냐 거짓이냐였다. 목록 전체를 훑어보려는 게 아니라 “이 소재 썼어?”에 대한 답만 있으면 됐다.
그래서 가벼운 전용 조회를 만들었다. 특정 키가 어느 사이트에 쓰였는지 알려주는 것, 두 단어가 제목이나 태그에 같이 든 글을 찾아주는 것, 유형별로 제목만 묶어주는 것. 셋 다 사실만 돌려주고 판단은 하지 않는다. 찾는 건 데이터베이스가 하고 이게 중복인지 아닌지는 AI가 정한다.
여기서 하나 조심한 게 있다. 조회할 사이트를 하나라도 못 찾으면 빈 결과 대신 에러를 내게 했다. 빈 결과는 “안 썼다”로 읽히기 때문이다. 사이트 이름에 오타가 나서 조회가 실패했는데 그게 “새 소재네”로 통과하면 같은 글을 두 번 올리게 된다.
자료는 서브 안에서 증발시켰다
두 번째는 자료가 머무는 위치를 옮긴 것이다.
파이프라인을 하나의 긴 대화로 돌리면 모든 자료가 그 대화에 쌓인다. 소재를 고르며 읽은 목록, 자료를 모으며 연 파일, 검증하며 확인한 숫자가 전부 남아서 마지막 단계까지 따라온다. 정작 본문을 쓸 때 필요한 건 정리된 재료뿐인데 원자료를 전부 들고 있는 셈이다.
그래서 단계를 서브에이전트로 쪼갰다. 소재를 고르는 일, 자료를 모으는 일, 본문을 쓰는 일을 각각 독립된 작업으로 분리했다.
핵심은 규칙 하나다. 조회한 결과 원본을 위로 올려보내지 못하게 했다. 소재를 고르는 쪽은 목록이든 파일이든 자기 안에서 실컷 열어보되, 위로는 “이 소재를 이 각도로 쓰기로 했다”는 결론만 준다. 자료를 모으는 쪽도 마찬가지로 정리된 파일 경로 한 줄만 반환한다.
이러면 원자료는 그 작업 안에서만 존재하다가 작업이 끝나면 같이 사라진다. 지휘하는 쪽에는 결론만 남는다.
부수 효과도 있었다. 서로 독립적이니 여러 편을 동시에 처리할 수 있게 됐고, 각 단계가 다른 단계의 판단에 오염되지 않으니 검증도 따로 된다.
본문은 텍스트 대신 경로로
세 번째는 작은 변경인데 효과가 컸다.
완성된 본문을 발행 도구에 넘기려면 그 본문을 인자로 실어야 한다. 2~3천자짜리 글을 통째로 도구 호출에 넣는다는 뜻이고, 그러면 그게 대화에 남는다. 방금 쓴 글을 다시 한번 대화에 복사하는 셈이다.
그래서 파일 경로만 받는 방식을 추가했다. 도구가 그 경로를 열어 본문만 뽑아 발행한다. 파일 앞쪽 메타 정보와 끝의 주석은 건너뛰고 본문 구간만 표준 규칙으로 읽는다.
여기서 도구는 글의 형식을 이해하지 않는다. 어디부터 어디까지가 본문인지 자리만 알면 되고, 제목이나 태그 같은 메타는 계속 인자로 받는다. 도구가 형식까지 알려고 하면 형식이 바뀔 때마다 도구를 고쳐야 한다.
한 번에 물어보게 만들었다
네 번째는 설계 단계에서 걸러낸 것이다.
유형별 제목을 조회하는 도구를 만들 때, 처음 안은 유형 하나를 받는 것이었다. 그런데 한 번에 다섯 편을 뽑는 작업이라면 유형 수만큼 이 도구를 다시 부르게 된다. 호출할 때마다 응답이 쌓이니 애써 줄인 게 도로 무너진다.
그래서 유형 목록을 배열로 받아 한 번에 처리하고 유형별로 묶어서 돌려주게 했다. 조회 하나를 가볍게 만드는 것보다, 조회 횟수 자체를 줄이는 게 클 때가 있다.
프롬프트도 비용이다
마지막은 좀 늦게 깨달았다.
서브에게 일을 시킬 때 처음엔 지시문을 길게 썼다. 절차를 설명하고, 지켜야 할 규칙을 나열하고, 예외 상황을 덧붙였다. 잘 시키려면 자세히 말해야 한다고 생각했다.
그런데 그 지시문이 지휘하는 쪽 대화에 남는다. 서브를 다섯 번 부르면 비슷한 지시문이 다섯 번 쌓인다.
규칙은 이미 각 작업의 정의 파일에 적혀 있었다. 서브는 그걸 읽고 시작하니 다시 설명할 필요가 없었다. 그래서 지시문에서 절차와 규칙 재설명을 걷어내고, 그 작업에만 해당하는 것만 남겼다. 무엇을 맡길지와 어떤 재료를 쓸지 정도다.
읽어오는 방식도 손봤다. 큰 표를 통째로 읽지 말고 조건에 맞는 줄만 찾게 했고, 여러 값을 찾을 때 값마다 나눠 부르지 말고 한 번에 묶어 찾게 했다.
토큰 줄이기 팁 정리
토큰 얘기는 이번 편으로 마무리한다. 두 편에서 실제로 효과를 본 것만 한 줄씩 모았다.
도구를 만들 때
- 응답 기본값은 짧게 두고, 전체는 필요할 때만 따로 요청하게 한다
- 자주 하는 일에는 전용 도구를 만든다 — 없으면 제일 무거운 통로로 가게 된다
- 조회할 때는 쓸 필드만 지정한다
- 목록 전체가 필요한지, 있느냐 없느냐만 필요한지 구분한다 (대개 후자다)
- 도구는 사실만 돌려주고 판단은 AI가 한다 — 판정 로직을 넣으면 응답이 커진다
일을 나눌 때
- 원자료는 그걸 쓰는 작업 안에서만 열고, 위로는 결론만 올린다
- 큰 텍스트는 인자로 싣지 말고 경로로 넘긴다
- 여러 번 물을 것 같으면 인자를 배열로 받아 한 번에 처리한다
- 큰 파일은 통째로 읽지 말고 조건에 맞는 줄만, 여러 값은 나눠 찾지 말고 한 번에 찾는다
반복되는 지시는 파일로
- 매번 설명하던 절차와 규칙은 스킬 파일로 뺀다 — 대화에 쌓이지 않고, 고칠 곳도 한 군데가 된다
- 지시문에는 이번 작업에만 해당하는 것만 남긴다 (무엇을 맡길지, 어떤 재료를 쓸지)
- 같은 말을 두 번 하고 있다면 그건 어딘가에 적혀 있어야 할 내용이다
순서가 고정이면 코드로
- 판단이 필요 없는 순서는 AI가 지휘할 이유가 없다 — 코드로 짜면 지휘하던 문맥이 통째로 사라진다
- 코드로 옮기면 덤으로 병렬 처리와 재시도가 쉬워진다
- 대신 판단이 필요한 지점은 남겨둔다 — 전부 코드로 만들려다 예외 처리에 파묻힌다
한 줄로 줄이면 이렇다. 지금 이 데이터가 대화에 남을 필요가 있는지 매번 묻는 것. 남을 필요가 없으면 어딘가 다른 곳에서 쓰이고 사라지게 만든다.
정리하면
도구를 고치는 것과 파이프라인을 고치는 건 다른 작업이었다.
도구 쪽은 “얼마나 말이 많은가”를 보면 됐다. 응답을 깎으면 해결된다. 반면 파이프라인 쪽은 “자료가 어디에 머무는가”의 문제였다. 같은 자료를 읽더라도 그게 지휘하는 대화에 남느냐, 서브 안에서 쓰이고 사라지느냐에 따라 비용이 완전히 달라졌다.
정해진 순서로 도는 구조는 편하다. 대신 그 편함에는 매번 같은 값을 문다는 대가가 붙어 있었다. 어느 단계가 무엇을 읽고 무엇을 위로 올리는지, 그 경계를 정하는 게 결국 비용을 정하는 일이었다.



답글 남기기