에이전틱스
도메인 6. 프롬프트와 컨텍스트 엔지니어링

6.1컨텍스트 엔지니어링

예상 학습 시간 30

컨텍스트는 넣을 수 있는 만큼 넣는 것이 아니라 관리하는 대상입니다. 이 수업에서는 무엇이 자리를 잡아먹는지 찾아내고, 정리·압축·격리로 대응하는 방법을 다룹니다.

무엇이 자리를 차지하는가

컨텍스트가 부족해지는 원인은 대개 모델의 응답이 아닙니다. 순서대로 이렇습니다.

  1. 도구 결과 — API 응답이나 검색 결과를 그대로 넣으면 한 번에 수천 토큰이 들어갑니다.
  2. 첨부한 참고 자료 — 문서 전체를 넣는 경우입니다.
  3. 누적된 대화 이력 — 턴이 쌓이면서 늘어납니다.
  4. 도구 정의 — 도구가 많으면 정의만으로도 상당합니다.
  5. 모델의 응답

그래서 손대는 순서도 이와 같아야 합니다. 이력 압축부터 시작하는 경우가 많은데, 원인이 도구 결과라면 압축해도 다음 턴에 다시 채워집니다. 먼저 재고 큰 것부터 손대는 것이 원칙입니다.

def context_breakdown(messages, tools) -> dict:
    return {
        "tools": approx_tokens(json.dumps(tools)),
        "history": approx_tokens(json.dumps(messages[:-2])),
        "latest": approx_tokens(json.dumps(messages[-2:])),
    }

도구 결과 정리

가장 효과가 큰 조치입니다. 도구가 돌려주는 것을 그대로 넣지 말고, 모델이 판단에 쓸 부분만 남깁니다.

def prune(name: str, raw: dict) -> str:
    if name == "search":
        hits = raw["results"][:5]
        body = [{"id": h["id"], "title": h["title"], "excerpt": h["text"][:300]} for h in hits]
        # 잘랐다는 사실과 전체 규모를 함께 알린다
        return json.dumps({"shown": len(body), "total": raw["total"], "items": body},
                          ensure_ascii=False)
    return json.dumps(raw, ensure_ascii=False)

세 가지를 지켜야 합니다.

  • 필요한 필드만. 내부 식별자, 타임스탬프, 메타데이터는 대개 필요 없습니다.
  • 개수 제한. 상위 몇 건만 넣습니다.
  • 잘랐다는 표시. 전체 규모를 함께 알려야 모델이 더 필요할 때 다시 요청합니다.

세 번째를 빠뜨리면 모델은 보이는 것이 전부라고 믿고 답합니다. "43건 중 5건 표시"처럼 적는 한 줄이 실제로 답의 정확도를 바꿉니다.

압축과 격리

정리해도 부족하면 다음 수단으로 갑니다.

압축 — 오래된 이력을 요약으로 바꿉니다. 남길 것은 확정된 사실과 결정이고, 버릴 것은 시행착오입니다.

def compact(messages: list, keep: int = 6) -> list:
    if len(messages) <= keep + 2:
        return messages
    summary = summarize(messages[:-keep])   # 결정과 확정 사실만
    return [{"role": "user", "content": f"이전 대화 요약:\n{summary}"}] + messages[-keep:]

격리 — 서브에이전트에 맡겨 그쪽 컨텍스트에서 처리하고 결과만 받습니다. 큰 입력을 읽고 작은 결과를 내는 작업에 효과가 큽니다.

둘의 차이를 알아 둘 필요가 있습니다. 압축은 이미 쌓인 것을 줄이고, 격리는 애초에 쌓이지 않게 합니다. 검색 결과처럼 매번 크게 들어오는 것이라면 격리가 낫고, 이미 길어진 대화를 이어 가야 한다면 압축입니다.

압축에는 손실이 따릅니다. 요약하면서 나중에 필요할 세부가 사라질 수 있으므로, 원본을 밖에 남겨 두고 필요하면 다시 꺼낼 수 있게 하는 편이 안전합니다.

무엇을 넣지 않을 것인가

넣을 수 있다고 다 넣으면 오히려 답이 나빠집니다. 관련 없는 내용이 많으면 모델이 무엇을 근거로 삼아야 할지 흐려집니다.

판단 기준은 이 정보가 없으면 답이 달라지는가입니다. 달라지지 않으면 넣지 않습니다.

자주 넣게 되지만 대개 불필요한 것들이 있습니다.

  • 전체 스키마 정의 — 이번 질의에 관련된 테이블만 있으면 됩니다.
  • 지난 대화 전체 — 이번 주제와 무관한 앞부분은 압축 대상입니다.
  • 모든 도구 — 이 작업에서 쓸 수 있는 것만 노출합니다.

마지막 항목이 자주 간과됩니다. 도구를 스무 개 붙여 두면 정의가 매번 실려 갈 뿐 아니라, 모델이 매번 그중에서 고르느라 오선택이 늘어납니다. 작업 종류에 따라 도구 묶음을 나눠 주는 것이 실무 대응입니다.

시험 함정

  • 컨텍스트가 부족할 때 이력 압축부터 손대는 순서 — 원인이 도구 결과면 다음 턴에 다시 채워집니다.
  • 도구 결과를 원본 그대로 넣어야 정확하다는 서술 — 필요한 필드만 남기는 것이 실무입니다.
  • 결과를 자르면서 잘랐다는 사실을 알리지 않는 처리 — 모델이 보이는 것을 전부로 믿습니다.
  • 압축과 격리를 같은 수단으로 보는 선택지 — 하나는 쌓인 것을 줄이고 다른 하나는 쌓이지 않게 합니다.
  • 요약으로 압축하면 손실이 없다는 서술 — 원본을 밖에 남겨 다시 꺼낼 수 있게 해야 합니다.
  • 도구를 많이 노출할수록 유연하다는 선택지 — 정의가 컨텍스트를 먹고 오선택이 늘어납니다.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

에이전트가 세 번째 턴부터 컨텍스트 한계에 걸립니다. 계측해 보니 도구 정의가 약 800토큰, 대화 이력이 약 1,200토큰, 검색 도구가 매 호출마다 약 9,000토큰을 반환합니다. 가장 먼저 할 조치는 무엇입니까?

빌드 연습 · 컨텍스트 구성을 계측하고 큰 것부터 줄이기

35
  1. 1.구성 계측

    도구 정의·이력·도구 결과가 각각 몇 토큰인지 잽니다.

    기대 결과 · 세 항목의 비중이 표로 나옵니다.

  2. 2.가장 큰 항목 정리

    비중이 가장 큰 항목을 줄이는 처리를 넣습니다.

    기대 결과 · 총 입력 토큰이 눈에 띄게 줄어듭니다.

  3. 3.절단 표시

    줄인 결과에 표시 건수와 전체 건수를 함께 넣습니다.

    기대 결과 · 모델이 추가 요청을 하는 턴이 관찰됩니다.

  4. 4.압축 적용

    이력이 길어지면 오래된 부분을 요약으로 바꿉니다.

    기대 결과 · 확정 사실은 남고 시행착오는 사라집니다.

  5. 5.도구 묶음 분리

    작업 종류별로 노출할 도구를 나눕니다.

    기대 결과 · 한 요청에 실리는 도구 정의가 줄어듭니다.

출처 및 더 읽기