파일 (Files)¶
개념¶
여러분이 에이전트한테 이미지, PDF, 오디오, 비디오, 텍스트 파일을 직접 넘기고 싶을 때가 많아요. CrewAI는 이를 위한 네이티브 멀티모달 파일 입력을 지원해서, 파일을 LLM 제공자(프로바이더) API가 요구하는 형식으로 자동 변환해 줍니다.
파일 기능을 쓰려면 선택 패키지인 crewai-files가 필요해요.
참고로 파일 처리 API는 현재 얼리 액세스(early access) 단계입니다.
파일 유형¶
CrewAI는 다섯 가지 구체적인 파일 유형과, 내용에서 유형을 자동으로 감지하는 일반(Generic) File 클래스를 제공합니다.
| 유형 | 클래스 | 주요 용도 |
|---|---|---|
| 이미지 | ImageFile |
사진, 스크린샷, 다이어그램, 차트 |
PDFFile |
문서, 리포트, 논문 | |
| 오디오 | AudioFile |
음성 녹음, 팟캐스트, 회의 |
| 비디오 | VideoFile |
화면 녹화, 프레젠테이션 |
| 텍스트 | TextFile |
코드 파일, 로그, 데이터 파일 |
| 일반 | File |
콘텐츠에서 유형 자동 감지 |
from crewai_files import File, ImageFile, PDFFile, AudioFile, VideoFile, TextFile
image = ImageFile(source="screenshot.png")
pdf = PDFFile(source="report.pdf")
audio = AudioFile(source="meeting.mp3")
video = VideoFile(source="demo.mp4")
text = TextFile(source="data.csv")
file = File(source="document.pdf")
유형이 정해진 클래스를 쓰면 그대로, 유형이 애매하면 일반 File로 넘겨서 자동 감지에 맡기면 돼요.
파일 소스¶
source 파라미터는 여러 입력 형태를 받고, 상황에 맞는 핸들러를 자동으로 골라 줍니다.
경로에서¶
URL에서¶
바이트에서¶
from crewai_files import ImageFile, FileBytes
image_bytes = download_image_from_api()
image = ImageFile(source=FileBytes(data=image_bytes, filename="downloaded.png"))
image = ImageFile(source=image_bytes)
바이트를 넘길 때는 FileBytes로 감싸서 파일명까지 지정할 수도 있고, 원시 바이트를 바로 전달할 수도 있어요.
파일 사용하기¶
파일은 여러 계층에서 넘길 수 있고, 더 구체적인 계층이 우선합니다.
Crew에서¶
크루를 실행할 때 파일을 넘겨요.
from crewai import Crew
from crewai_files import ImageFile
crew = Crew(agents=[analyst], tasks=[analysis_task])
result = crew.kickoff(
inputs={"topic": "Q4 Sales"},
input_files={
"chart": ImageFile(source="sales_chart.png"),
"report": PDFFile(source="quarterly_report.pdf"),
}
)
Task에서¶
특정 태스크에 파일을 붙여요.
from crewai import Task
from crewai_files import ImageFile
task = Task(
description="Analyze the sales chart and identify trends in {chart}",
expected_output="A summary of key trends",
input_files={
"chart": ImageFile(source="sales_chart.png"),
}
)
여기서 중요한 포인트가 하나 있어요. 태스크 설명의 {chart}처럼 파일의 key 이름을 중괄호로 감싸서 프롬프트 안에서 참조하는 방식이에요. 뒤에서 다시 자세히 다룰게요.
Flow에서¶
플로우에 파일을 넘기면 크루로 자동 상속됩니다.
from crewai.flow.flow import Flow, start
from crewai_files import ImageFile
class AnalysisFlow(Flow):
@start()
def analyze(self):
return self.analysis_crew.kickoff()
flow = AnalysisFlow()
result = flow.kickoff(
input_files={"image": ImageFile(source="data.png")}
)
단독 에이전트에서¶
크루 없이 에이전트 단독 실행에도 파일을 바로 넘길 수 있어요.
from crewai import Agent
from crewai_files import ImageFile
agent = Agent(
role="Image Analyst",
goal="Analyze images",
backstory="Expert at visual analysis",
llm="gpt-4o",
)
result = agent.kickoff(
messages="What's in this image?",
input_files={"photo": ImageFile(source="photo.jpg")},
)
파일 우선순위¶
여러 계층에 같은 이름의 파일이 넘어오면 더 구체적인 계층이 이깁니다.
예를 들어 Flow와 Task 양쪽에 "chart"라는 이름의 파일을 정의했다면, Task의 버전이 사용돼요.
실무에서 이 우선순위를 잘 활용하면 좋아요. 공통 자료는 Flow나 Crew 레벨에 두고, 특정 태스크만 다르게 처리해야 하는 파일은 Task 레벨에서 덮어쓰면 되니까요.
프로바이더 지원¶
프로바이더마다 지원하는 파일 유형이 달라요. CrewAI가 각 프로바이더 API에 맞게 파일을 자동으로 포맷팅합니다.
| 프로바이더 | 이미지 | 오디오 | 비디오 | 텍스트 | |
|---|---|---|---|---|---|
| OpenAI (completions API) | ✓ | ||||
| OpenAI (responses API) | ✓ | ✓ | ✓ | ||
| Anthropic (claude-3.x) | ✓ | ✓ | |||
| Google Gemini (gemini-1.5, 2.0, 2.5) | ✓ | ✓ | ✓ | ✓ | ✓ |
| AWS Bedrock (claude-3) | ✓ | ✓ | |||
| Azure OpenAI (gpt-4o) | ✓ | ✓ |
Google Gemini 모델은 비디오를 포함한 모든 파일 유형을 지원하고, 비디오는 최대 1시간, 2GB까지 처리할 수 있어요. 비디오 콘텐츠를 처리해야 한다면 Gemini를 쓰면 됩니다.
프로바이더가 지원하지 않는 유형을 넘기면(예: OpenAI에 비디오) UnsupportedFileTypeError가 발생해요. 필요한 파일 유형에 맞춰 프로바이더를 고르는 게 좋겠죠.
파일 전송 방식¶
CrewAI는 각 프로바이더에 파일을 보낼 때 최적의 방법을 자동으로 골라 줍니다.
| 방식 | 설명 | 사용 시점 |
|---|---|---|
| Inline Base64 | 파일을 요청 안에 직접 포함 | 작은 파일 (보통 5MB 미만) |
| File Upload API | 파일을 따로 업로드하고 ID로 참조 | 임계값을 넘는 큰 파일 |
| URL Reference | 직접 URL을 모델에 전달 | 소스가 이미 URL인 경우 |
프로바이더별 전송 방식을 정리하면 이렇게 돼요.
| 프로바이더 | Inline Base64 | File Upload API | URL References |
|---|---|---|---|
| OpenAI | ✓ | ✓ (> 5 MB) | ✓ |
| Anthropic | ✓ | ✓ (> 5 MB) | ✓ |
| Google Gemini | ✓ | ✓ (> 20 MB) | ✓ |
| AWS Bedrock | ✓ | ✓ (S3 URIs) | |
| Azure OpenAI | ✓ | ✓ |
이 과정을 직접 관리할 필요는 없어요. CrewAI가 파일 크기와 프로바이더 역량에 따라 가장 효율적인 방법을 자동으로 사용합니다. 파일 업로드 API가 없는 프로바이더는 모든 파일을 인라인 base64로 처리하게 되죠.
파일 처리 모드¶
파일이 프로바이더 한도를 넘을 때 어떻게 처리할지 정할 수 있어요.
from crewai_files import ImageFile, PDFFile
image = ImageFile(source="large.png", mode="strict")
image = ImageFile(source="large.png", mode="auto")
image = ImageFile(source="large.png", mode="warn")
pdf = PDFFile(source="large.pdf", mode="chunk")
mode 파라미터로 strict, auto, warn, 그리고 PDF 한정이지만 chunk까지 골라 쓸 수 있어요. 지금은 어떤 모드가 어떤 동작을 하는지 정도로만 기억해 두고, 실제로 한도를 넘기는 상황이 생기면 그때 자세히 다뤄도 좋아요.
프로바이더 제약¶
프로바이더마다 파일 크기와 크기(픽셀) 제한이 구체적으로 정해져 있어요.
OpenAI¶
- 이미지: 최대 20MB, 요청당 최대 10개 이미지
- PDF: 최대 32MB, 최대 100페이지
- 오디오: 최대 25MB, 최대 25분
Anthropic¶
- 이미지: 최대 5MB, 최대 8000x8000 픽셀, 최대 100개 이미지
- PDF: 최대 32MB, 최대 100페이지
Google Gemini¶
- 이미지: 최대 100MB
- PDF: 최대 50MB
- 오디오: 최대 100MB, 최대 9.5시간
- 비디오: 최대 2GB, 최대 1시간
AWS Bedrock¶
- 이미지: 최대 4.5MB, 최대 8000x8000 픽셀
- PDF: 최대 3.75MB, 최대 100페이지
프롬프트에서 파일 참조하기¶
태스크 설명에서 파일의 key 이름을 사용해 파일을 참조할 수 있어요. 앞서 {chart}를 잠깐 언급했었죠. 실제로 이렇게 쓰면 됩니다.
task = Task(
description="""
Analyze the provided materials:
1. Review the chart in {sales_chart}
2. Cross-reference with data in {quarterly_report}
3. Summarize key findings
""",
expected_output="Analysis summary with key insights",
input_files={
"sales_chart": ImageFile(source="chart.png"),
"quarterly_report": PDFFile(source="report.pdf"),
}
)
태스크 설명의 자연어 문장 안에서 {sales_chart}, {quarterly_report}처럼 입력 파일의 key를 그대로 꺼내 쓰는 방식이에요. 파일이 실제로 프롬프트에 어떤 형태로 들어가는지, 그 파일을 읽고 분석하는 흐름까지 에이전트가 처리합니다.
더 알아보기¶
- 파일 기능을 쓰려면
crewai-files패키지 설치가 필요해요 (uv add 'crewai[file-processing]'). - 파일 처리 API는 현재 얼리 액세스라 동작이 바뀔 수 있어요. 프로덕션에 쓰기 전에 최신 문서를 확인해 보세요.
- 비디오를 처리해야 한다면 Gemini처럼 비디오를 지원하는 프로바이더를 골라야 해요. 지원하지 않는 유형을 넘기면
UnsupportedFileTypeError가 납니다.