AIClaw의 생성된 파일 첨부 기능: 채팅 루프 내에 도구 출력 유지하기
요약
셀프 호스팅 에이전트 런타임인 AIClaw가 에이전트가 생성한 파일(스크린샷, CSV, PDF 등)을 채팅 컨텍스트 내에 유지하고 렌더링하는 기능을 소개합니다. 도구 실행 후 생성된 아티팩트를 자동으로 감지하여 대화 세션의 일부로 관리함으로써 워크플로의 연속성을 보장합니다.
핵심 포인트
- 에이전트가 생성한 파일을 채팅 API 및 UI에 직접 통합
- 도구 실행 후 샌드박스를 스캔하여 생성된 파일을 자동으로 캡처
- 로컬 파일 및 원격 URL을 통한 유연한 파일 로딩 지원
- 대화 컨텍스트 내 파일 유지를 통해 작업 세션의 연속성 확보
AIClaw는 셀프 호스팅(self-hosted) 에이전트 런타임(runtime)이므로, "정답"이 항상 가장 유용한 출력물은 아닙니다. 실제 워크플로에서는 에이전트가 생성한 파일, 즉 스크린샷, CSV, Markdown 보고서, PDF 또는 도구 실행으로 생성된 아티팩트(artifact)를 원하는 경우가 많습니다.
AIClaw는 이미 동일한 런타임 내에서 대화, 실행 단계 및 파일을 유지(persist)합니다. 이것이 유용한 이유는 생성된 파일이 사후 고려 사항으로 취급되지 않기 때문입니다. 파일들은 대화에 첨부되고, 채팅 API를 통해 반환되며, 웹 채팅 UI에서 직접 렌더링됩니다.
프로젝트: https://github.com/chowyu12/aiclaw
문제점
많은 에이전트 데모는 단순 텍스트 수준에서 멈춥니다:
- 도구가
/tmp하위 어딘가에 파일을 작성함 - 모델은 해당 파일이 존재한다고 언급함
- 사용자가 직접 파일을 찾아야 함
- 다음 턴(turn)에서 해당 아티팩트가 안정적으로 전달되지 않을 수 있음
에이전트가 브라우저 자동화(browser automation), 코드 실행(code execution), 셸 명령(shell commands) 또는 문서 스타일의 출력을 사용하기 시작하면 이러한 문제는 빠르게 발생합니다.
AIClaw의 현재 설계는 세 가지 측면에서 이 격차를 해소합니다:
- 업로드된 파일 및 URL 기반 파일을 위한 요청 시점(request-time) 파일 로딩
- 실행 중 생성된 파일에 대한 도구 출력(tool-output) 유지
- 사용자가 제공하거나 에이전트가 생성한 아티팩트 모두를 위한 채팅/UI 첨부 렌더링
파일이 런타임에 들어오는 방식
AIClaw의 채팅 요청 모델은 ChatRequest의 files를 통해 파일 참조를 지원하며, 두 가지 전송 모드가 있습니다:
local_file(로컬 파일)remote_url(원격 URL)
서버 측에서는 internal/agent/file.go가 이러한 입력값들을 실행 컨텍스트(execution context)로 로드합니다. 로컬 업로드는 유지된 파일 레코드에서 해결(resolve)되며, 원격 URL은 임시 저장소로 가져올 수 있습니다. 텍스트 및 문서 유형 또한 가능한 경우 텍스트 추출(text extraction)이 수행되므로, 모델이 단순한 파일 포인터(file pointer) 대신 콘텐츠를 직접 다룰 수 있습니다.
여기 실무에서 매우 중요한 설계 세부 사항이 하나 있습니다. AIClaw는 ListFilesByConversation(...)를 통해 이전 대화 파일들도 함께 로드하므로, 파일들이 한 번의 턴(turn)이 지나고 사라지는 대신 대화 컨텍스트(conversation context) 내에 유지됩니다.
덕분에 첨부 파일은 단순히 하나의 HTTP 요청의 일부가 아니라, 작업 세션(working session)의 일부가 됩니다.
도구 출력이 대화 첨부 파일이 되는 방식
흥미로운 점은 도구가 실행된 후에 일어나는 일입니다.
internal/agent/tool_call.go에서 AIClaw는 각 도구 호출(tool call)을 파일 인식 지속성 로직(file-aware persistence logic)으로 감쌉니다.
- 도구가 실행되기 전에 샌드박스(sandbox) 디렉토리를 스냅샷(snapshot)합니다.
- 도구를 실행합니다.
- 도구가 구조화된 파일 결과(structured file result)를 반환했는지 확인합니다.
- 반환하지 않았다면, 샌드박스 내에서 새로 생성된 파일을 스캔합니다.
- 해당 파일들을 업로드 영역(uploads area)에 영구 저장하고 스토리지에 파일 레코드를 생성합니다.
이를 통해 AIClaw는 아티팩트(artifact)를 캡처하는 두 가지 방법을 갖게 됩니다:
- 명시적인 파일 결과 (Explicit file results)
- 실행 후 샌드박스에서 감지된 새 파일 (New files detected from the sandbox after execution)
샌드박스 스캔은 .py, .js, .sh, .rb, .ts와 같은 스크립트 캐리어 파일(script carrier files)을 의도적으로 건너뛰므로, 실행 스캐폴딩(execution scaffolding)보다는 출력물에 집중합니다.
이는 실용적인 설계 선택입니다. 즉, 도구 작성자가 아티팩트를 생성하는 모든 워크플로우에 대해 항상 완벽한 맞춤형 반환 경로(custom return path)를 구축할 필요는 없다는 것을 의미합니다. 도구나 인터프리터(interpreter)가 실제 출력 파일을 생성하기만 하면, AIClaw는 이를 보존할 기회를 갖게 됩니다.
이것이 실제 에이전트 작업에 중요한 이유
이러한 파일 흐름은 자연스럽게 아티팩트를 생성하는 도구들에 특히 유용합니다:
browser는 스크린샷을 생성할 수 있습니다.code_interpreter는 플롯(plots), 표(tables), 내보낸 파일(exported files)을 생성할 수 있습니다.- 셸(shell) 기반 도구는 보고서나 변환된 데이터셋을 작성할 수 있습니다.
- 서브 에이전트(sub-agents)는 자신의 파일을 상위 실행(parent run)으로 전달할 수 있습니다.
sub_agent 출력 또한 동일한 도구 호출 경로에서 명시적으로 처리되므로, 상위 대화는 중첩된 실행(nested execution) 내부에서 파일을 잃어버리는 대신 위임된 작업으로부터 생성된 파일들을 상속받을 수 있습니다.
그것이 바로 "에이전트가 무언가를 수행했다고 말하는 것"과 "결과물이 이제 대화에 첨부되어 열 수 있는 상태가 되는 것"의 차이입니다.
API 및 스트리밍 동작 (API And Streaming Behavior)
채팅 API는 파일을 일급 응답 데이터 (first-class response data)로 반환합니다.
internal/handler/chat.go에서 비스트리밍 (non-streaming) 응답에는 다음이 포함됩니다:
message(메시지)steps(단계)files(파일)plan(계획)
model.StreamChunk의 스트리밍 형태 (streaming shape) 또한 files를 포함하므로, 생성된 아티팩트 (artifacts)를 별도의 폴링 (polling) 흐름을 거칠 필요 없이 동일한 실행 세션의 일부로 전달할 수 있습니다.
이는 AIClaw의 나머지 런타임 모델 (runtime model)과도 잘 부합합니다:
- 실행 단계 (execution steps)는 발생한 일을 보여줍니다.
- 계획 상태 (plan state)는 작업 진행 상황을 보여줍니다.
- 첨부 파일 (attachments)은 구체적인 결과물을 운반합니다.
채팅 UI의 처리 방식 (What The Chat UI Does With It)
web/src/views/chat/Index.vue에 있는 Vue 채팅 페이지는 메시지 버블 내에 첨부 파일을 직접 렌더링합니다.
현재 동작은 직관적이며 유용합니다:
- 이미지는 썸네일이 포함된 미리보기 카드 (preview cards)로 렌더링됩니다.
- 이미지가 아닌 파일은 클릭 가능한 파일 카드 (file cards)로 렌더링됩니다.
- UI에 파일 유형과 크기가 표시됩니다.
- 사용자 측의 대기 중인 업로드 및 URL 첨부 파일은 전송 전에 확인할 수 있습니다.
이것이 중요한 이유는 아티팩트 (artifact)를 모델 응답 및 실행 타임라인과 동일한 시각적 흐름 내에 유지하기 때문입니다. 생성된 파일이 존재하는지 확인하기 위해 다른 관리자 페이지로 이동할 필요가 없습니다.
실질적인 워크플로우 (A Practical Workflow)
이 설계를 사용한 현실적인 AIClaw 흐름은 다음과 같습니다:
- 대화에 CSV 파일을 업로드합니다.
- 에이전트에게 이를 분석하고 요약 보고서와 차트를 생성하도록 요청합니다.
- 코드 중심 도구 (code-oriented tool)가 차트 이미지와 보고서 파일을 작성하도록 합니다.
- 동일한 대화 내에서 어시스턴트의 답변, 실행 단계, 생성된 첨부 파일을 받습니다.
- 채팅 UI에서 파일을 직접 열거나 다음 턴 (turn)에서 재사용합니다.
동일한 패턴이 브라우저 스크린샷, 내보낸 마크다운 (markdown) 노트, 또는 위임된 하위 에이전트 (sub-agent)에 의해 생성된 파일에도 적용됩니다.
내가 이 설계를 좋아하는 이유 (Why I Like This Design)
AIClaw의 구현에서 눈에 띄는 점은 첨부 파일(attachments)이 단순히 나중에 추가된 다운로드 기능이 아니라, 런타임 계약 (runtime contract)의 일부라는 점입니다.
- 실행기 (executor)가 파일을 컨텍스트 (context)에 로드합니다.
- 도구 계층 (tool layer)이 생성된 아티팩트 (artifacts)를 유지합니다.
- 저장소 (store)가 이를 대화와 연관된 상태로 보관합니다.
- API가 이를 반환합니다.
- 채팅 UI가 이를 렌더링합니다.
이러한 엔드 투 엔드 (end-to-end) 경로는 에이전트 플랫폼이 텍스트만을 생성하는 것을 넘어, 자산 (assets)을 생성하는 업무에 사용 가능하게 만드는 핵심 요소입니다.
만약 로컬 우선 (local-first) 또는 셀프 호스팅 (self-hosted) 에이전트를 구축하고 있다면, 이는 초기에 제대로 구현해둘 가치가 있는 인터페이스 중 하나입니다. 텍스트 답변은 저렴합니다. 신뢰할 수 있는 아티팩트 처리 (artifact handling)야말로 시스템을 운영 가능한 수준으로 만드는 핵심입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기