입력/출력 설정

입력/출력 설정 (Set Input/Output)

트레이스에 LLM 애플리케이션의 입력과 출력을 어떻게 공급하는지 배우는 페이지예요. 대부분 앱에서는 init()이 지원하는 프로바이더·프레임워크 통합에서 이를 자동으로 캡처해요. 기본값을 재정의하고 싶을 때는 트레이스 컨텍스트나 스팬 업데이트 헬퍼를 쓰면 된답니다.

출처: 문서

본문

개요 (Overview)

트레이스와 스팬 둘 다 입력과 출력을 가져요. 대부분의 앱에서 init()은 지원하는 프로바이더·프레임워크 통합으로부터 이를 자동으로 캡처해요.

별도의 스팬을 만들지 않고 트레이스 I/O를 재정의하고 싶다면 트레이스 컨텍스트를 사용해요. 직접 만든 스팬의 경우에는 스팬 업데이트 헬퍼를 써서 함수의 인자와 반환값에서 캡처된 값을 재정의하면 돼요.

트레이스에 I/O를 설정하는 것은 Confident AI의 스레드 뷰에서도 중요하고, 온라인 평가(online evaluations)가 테스트 케이스의 input과 actual_output으로 읽는 값이기도 해요.

트레이스 I/O 설정 (Set Trace I/O)

기본적으로 트레이스는 루트 스팬에서 캡처한 입력과 출력을 상속해요. 래퍼 스팬을 만들지 않고 트레이스 속성을 설정하려면 계측된 호출 주위에 트레이스 컨텍스트를 열면 돼요:

Python

from langchain_openai import ChatOpenAI
from confident_trace import init, trace_context

init()
model = ChatOpenAI(model="gpt-4o")

def llm_app(query: str):
    with trace_context(input=query):
        return model.invoke(query)

TypeScript

import { ChatOpenAI } from "@langchain/openai";
import { init, traceContext } from "confident-trace";

init();
const model = new ChatOpenAI({ model: "gpt-4o" });

const llmApp = (query: string) =>
  traceContext({ input: query }, () => model.invoke(query));

LangChain 호출이 계측되도록 Node preload로 진입점을 실행하는 걸 잊지 마세요.

여기서 트레이스 컨텍스트는 원시 사용자 텍스트를 트레이스 입력으로 설정하고, init()은 LangChain 호출과 그 출력을 자동으로 캡처해요. 컨텍스트는 트레이스도 스팬도 만들지 않아요. 계측된 호출이 트레이스를 시작하죠.

input과 output은 어떤 JSON 직렬화 가능한 타입이든 될 수 있어요. 다만 대화 스레드(conversation threads)에서는 보통 문자열이 가장 깔끔하게 표시돼요.

트레이스 컨텍스트는 트레이스가 시작되기 전에 아는 값만 공급할 수 있어요. 의도적으로 바깥 스팬을 만들었고 나중에 값을 설정해야 한다면 그 스팬 안에서 활성 트레이스를 업데이트하세요. I/O만 설정하려고 래퍼 스팬을 추가하지는 마세요. 두 패턴 모두 Update Trace Properties에서 볼 수 있어요.

스팬 I/O 설정 (Set Span I/O)

기본적으로 래핑된 함수의 인자가 스팬 입력이 되고, 반환값이 출력이 돼요 (withSpan 콜백은 반환값만 캡처해요). 스팬이 활성인 동안 두 값 중 하나를 재정의할 수 있어요.

각 스팬 타입(span type)은 I/O에 대한 기대치가 있어요. 예를 들어 "retriever" 스팬 type은 input으로 문자열을, retrieval_context로 문자열 리스트를 기대해요. 이런 것들을 직접 설정하면 위반할 수 있으니 주의하세요. 이런 형태를 지키면 스팬에 메트릭을 실행할 때 오류가 생길 가능성이 줄어들어요.

Python

from confident_trace import init, span, update_span

init()

@span(type="retriever", name="retrieve")
def retrieve(query: str) -> list[str]:
    documents = vector_store.similarity_search(query, k=3)
    update_span(input=query, output=documents, retrieval_context=documents)
    return documents

TypeScript

import { init, span, updateSpan } from "confident-trace";

init();

const retrieve = span(
  { name: "retrieve", type: "retriever" },
  async (query: string) => {
    const documents = await vectorStore.similaritySearch(query, 3);
    updateSpan({ input: query, output: documents, retrievalContext: documents });
    return documents;
  },
);

스팬 업데이트 헬퍼는 현재 스팬에 써요. 이 예시에서는 리트리버 함수의 기본 I/O를 대체하고, 반환된 문서를 검색 컨텍스트(retrieval context)로도 기록해요.

input과 output 외에도, 두 헬퍼는 보통 테스트 케이스에 넣는 평가 필드들 — metadata, context, retrieval_context, expected_output, tools_called, expected_tools — 을 JSON 호환 데이터로 받아들여요. 설정한다고 자체로 메트릭이 실행되지는 않아요. 단지 값이 준비되어 온라인 평가(online evals)가 쓸 수 있게 해줄 뿐이죠.

명시적 값은 항상 자동 캡처를 덮어써요. 생략된 필드는 호출 사이에 그대로 유지되지만, metadata는 예외로, 공급된 객체가 이전 값을 대체해요. 여기서 설정한 모든 것은 콘텐츠 컨트롤(content controls)을 통과해요 — 명시적 I/O에도 삭제·크기 제한이 적용된답니다.

스트리밍 응답의 I/O (I/O for Streamed Responses)

함수가 응답을 스트리밍한다면 트레이스 출력이 자동으로 캡처되지 않아요 — 함수가 돌려주는 것은 제너레이터이지 최종 텍스트가 아니거든요. 스트리밍된 청크를 모아서 스트림이 끝나면 출력을 명시적으로 설정해요:

Python

from confident_trace import init, span, update_trace

init()

def stream_response(query: str):
    with span("stream_response", type="agent"):
        chunks = []
        for chunk in llm.stream(query):
            chunks.append(chunk)
            yield chunk

        update_trace(input=query, output="".join(chunks))

TypeScript

import { init, span, updateTrace } from "confident-trace";

init();

const streamResponse = span({ name: "stream_response", type: "agent" }, async function* (query: string) {
  const chunks: string[] = [];
  for await (const chunk of llm.stream(query)) {
    chunks.push(chunk);
    yield chunk;
  }

  updateTrace({ input: query, output: chunks.join("") });
});

이렇게 하지 않으면 트레이스가 출력 없이 Confident AI에 나타나요. 서버리스 환경에서 실행 중이라면 flush()를 호출하기 전에 스트림이 끝났는지도 확인하세요 — flush and shutdown을 참고해요.

스레드의 I/O (I/O for Threads)

트레이스로 스레드를 만드는 다중 턴 AI 앱에서는 문자열을 제공하는 것을 강력히 권장해요. 여기서 input은 사용자 입력을, output은 AI 생성 출력을 나타내요. 연속되는 사용자/LLM 동작의 경우에는 input이나 output을 생략해도 돼요.

스레드 온라인 평가를 실행하려면 input과 output도 필요해요. 이 값들이 대화형 테스트 케이스의 턴으로 사용되거든요.

다음 단계 (Next Steps)

트레이스와 스팬 I/O를 구성했다면, 트레이스를 대화로 연결하거나 평가를 시작해요.

Thread Traces

트레이스를 스레드로 묶어 다중 턴 대화를 추적하고 전체 워크플로를 평가해요.

Online Evaluations

트레이스·스팬·스레드가 Confident AI에 유입되는 대로 실시간으로 평가를 실행해요.

더 알아보기