지식 (Knowledge)¶
개요¶
에이전트가 작업을 하다 보면 어디선가 참고 자료를 가져와야 할 때가 있어요. 그냥 모델 학습에 담긴 내용으로만 답하면 최신 정보를 놓치거나, 정확하지 않은 내용을 그럴듯하게 말할 위험이 있죠. CrewAI의 Knowledge는 이런 문제를 풀기 위해, 에이전트가 작업 중에 외부 정보 소스를 활용할 수 있게 해주는 시스템이에요. 에이전트 옆에 두고 수시로 펼쳐보는 참고 도서관을 달아주는 셈이라고 생각하면 돼요.
작업 중 에이전트가 답이 필요할 때, 이 지식 저장소에서 관련된 조각을 꺼내 씁니다. PDF, 텍스트 파일, 문자열, CSV, 엑셀, JSON 같은 여러 형태의 자료를 넣어둘 수 있고, 에이전트 혹은 크루 단위로 붙일 수 있어요.
Quickstart 예시¶
가장 단순한 형태부터 볼게요. 문자열 하나를 지식 소스로 만들어 에이전트에 연결하는 예시예요. 응답을 일관되게 하려고 LLM 온도는 0으로 맞춰뒀어요.
from crewai import Agent, Task, Crew, Process, LLM
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
# 지식 소스 생성
content = "Users name is John. He is 30 years old and lives in San Francisco."
string_source = StringKnowledgeSource(content=content)
# 결정적 출력을 위해 temperature 0으로 LLM 생성
llm = LLM(model="gpt-4o-mini", temperature=0)
# 지식 저장소를 가진 에이전트 생성
agent = Agent(
role="About User",
...
)
여기서 핵심은 StringKnowledgeSource로 만든 지식 소스입니다. 이걸 나중에 크루에 knowledge_sources로 넘겨주면, 에이전트가 작업하면서 이 문자열을 참고하게 돼요.
웹 콘텐츠도 지식으로 넣을 수 있어요. 이 경우 docling 패키지가 필요하니 uv add docling으로 설치해두어야 해요.
from crewai import LLM, Agent, Crew, Process, Task
from crewai.knowledge.source.crew_docling_source import CrewDoclingSource
# 웹 콘텐츠에서 지식 소스 생성
content_source = CrewDoclingSource(
file_paths=[
"https://lilianweng.github.io/posts/2024-11-28-reward-hacking",
"https://lilianweng.github.io/posts/2024-07-07-hallucination",
],
)
llm = LLM(model="gpt-4o-mini", temperature=0)
agent = Agent(
role="About papers",
goal="You know everything about the papers.",
backstory="You are a master at understanding papers and their content.",
verbose=True,
allow_delegation=False,
llm=llm,
)
task = Task(
description="Answer the following questions about the papers: {question}",
expected_output="An answer to the question.",
agent=agent,
)
crew = Crew(
agents=[agent],
tasks=[task],
verbose=True,
process=Process.sequential,
knowledge_sources=[content_source],
)
result = crew.kickoff(
inputs={"question": "What is the reward hacking paper about? Be sure to provide sources."}
)
file_paths에 URL을 넣으면 CrewAI가 해당 페이지 콘텐츠를 긁어와 지식으로 임베딩해요. 작업 설명의 {question} 자리에 kickoff의 inputs로 전달한 질문이 채워지고, 에이전트는 지식에서 관련 내용을 찾아 답합니다.
지원되는 지식 소스¶
CrewAI는 기본적으로 여러 종류의 지식 소스를 지원해요.
- 텍스트 소스: 문자열, 텍스트 파일(.txt), PDF 문서
- 구조화 데이터: CSV 파일, 엑셀 스프레드시트, JSON 문서
텍스트 파일과 PDF는 각각 전용 소스 클래스를 사용해요.
from crewai.knowledge.source.text_file_knowledge_source import TextFileKnowledgeSource
text_source = TextFileKnowledgeSource(
file_paths=["document.txt", "another.txt"]
)
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
pdf_source = PDFKnowledgeSource(
file_paths=["document.pdf", "another.pdf"]
)
에이전트 지식 vs 크루 지식¶
자료를 붙이는 범위가 두 가지로 나뉘어요. 에이전트 지식은 특정 에이전트 하나만 쓰는 전용 지식이고, 크루 지식은 크루의 모든 에이전트가 공유하는 지식이에요. 역할이 서로 다른 에이전트가 각자 전문화된 자료를 따로 갖고 싶을 때 에이전트 지식이 유용해요.
from crewai import Agent, Task, Crew
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
# 에이전트 전용 지식 - 크루 지식은 불필요
specialist_knowledge = StringKnowledgeSource(
content="Specialized technical information for this agent only"
)
specialist_agent = Agent(
role="Technical Specialist",
goal="Provide technical expertise",
backstory="Expert in specialized technical domains",
...
)
...
crew = Crew(
agents=[specialist_agent],
tasks=[task]
)
result = crew.kickoff() # 에이전트 지식은 독립적으로 동작
저장소는 어떻게 나뉘나¶
에이전트 지식과 크루 지식은 같은 ChromaDB 인스턴스에 다른 컬렉션으로 저장돼요. 에이전트 지식은 컬렉션 이름이 에이전트 역할이고, 크루 지식은 "crew"라는 이름을 써요. 기본 경로는 ~/.local/share/CrewAI/{project}/knowledge/예요.
# 에이전트 지식 저장소
agent_collection_name = agent.role # 예: "Technical Specialist"
# 크루 지식 저장소
crew_collection_name = "crew"
# 둘 다 같은 ChromaDB 인스턴스, 다른 컬렉션
# 경로: ~/.local/share/CrewAI/{project}/knowledge/
지식 설정¶
크루나 에이전트에 지식 설정을 넣을 수 있어요. 검색 결과 개수와 관련성 점수 기준을 조절하는 용도예요.
from crewai.knowledge.knowledge_config import KnowledgeConfig
knowledge_config = KnowledgeConfig(results_limit=10, score_threshold=0.5)
agent = Agent(
...
knowledge_config=knowledge_config
)
results_limit: 반환할 관련 문서 수예요. 기본값 3.score_threshold: 문서를 관련 있다고 판단할 최소 점수예요. 기본값 0.35.
지식 저장 위치¶
CrewAI는 지식 소스를 ChromaDB를 이용한 벡터 저장으로 플랫폼별 디렉터리에 자동 저장해요. 운영 배포나 디버깅, 저장 공간 관리에서 이 위치를 아는 게 중요해요.
기본 저장 위치는 플랫폼에 따라 달라져요.
- macOS:
~/Library/Application Support/CrewAI/{project_name}/knowledge/ - Linux:
~/.local/share/CrewAI/{project_name}/knowledge/ - Windows:
C:\Users\{username}\AppData\Local\CrewAI\{project_name}\knowledge\
그 아래에 ChromaDB 메타데이터 chroma.sqlite3, 벡터 임베딩이 담긴 {collection_id}/ 디렉터리, 이름 붙은 컬렉션 knowledge_{collection}/이 생겨요.
내 지식이 정확히 어디에 저장되는지 코드로 확인할 수도 있어요.
from crewai.utilities.paths import db_storage_path
import os
# 지식 저장 경로 얻기
knowledge_path = os.path.join(db_storage_path(), "knowledge")
print(f"Knowledge storage location: {knowledge_path}")
# 지식 컬렉션과 파일 나열
if os.path.exists(knowledge_path):
print("\nKnowledge storage contents:")
for item in os.listdir(knowledge_path):
item_path = os.path.join(knowledge_path, item)
if os.path.isdir(item_path):
print(f"📁 Collection: {item}/")
try:
for subitem in os.listdir(item_path):
print(f" └── {subitem}")
except PermissionError:
print(f" └── (permission denied)")
else:
print(f"📄 {item}")
else:
print("No knowledge storage found yet.")
저장 위치 조절하기¶
기본 위치를 바꾸고 싶으면 크게 세 가지 방법이 있어요.
1) 환경 변수 (권장) — CREWAI_STORAGE_DIR을 지정하면 CrewAI 데이터 전체가 그 아래로 가요.
import os
from crewai import Crew
os.environ["CREWAI_STORAGE_DIR"] = "./my_project_storage"
# 모든 지식이 ./my_project_storage/knowledge/ 에 저장됨
crew = Crew(
agents=[...],
tasks=[...],
...
)
2) 커스텀 지식 저장소 — KnowledgeStorage를 직접 만들어 임베더를 지정할 수 있어요.
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
custom_storage = KnowledgeStorage(
embedder={
"provider": "ollama",
"config": {"model": "mxbai-embed-large"}
},
collection_name="my_custom_knowledge"
)
knowledge_source = StringKnowledgeSource(
content="Your knowledge content here"
)
3) 프로젝트별 지식 저장소 — 지식을 프로젝트 디렉터리에 저장하도록 지정할 수 있어요.
기본 임베딩 제공자¶
기본적으로 CrewAI는 지식 저장에 OpenAI 임베딩(text-embedding-3-small)을 써요. LLM 제공자를 다른 걸 써도 기본 임베딩은 OpenAI예요. 예를 들어 Claude를 LLM으로 써도 지식 임베딩은 기본적으로 OpenAI 임베딩을 사용한다는 뜻이에요. 이 동작은 설정으로 바꿀 수 있어요.
knowledge_source = StringKnowledgeSource(content="Research data...")
crew = Crew(
agents=[agent],
tasks=[...],
knowledge_sources=[knowledge_source]
# 기본: Claude LLM이어도 OpenAI 임베딩 사용
)
임베딩 제공자는 직접 지정해 바꿀 수 있어요 (예: Gemini 임베딩).
고급 기능¶
쿼리 재작성 (Query Rewriting)¶
에이전트가 지식에서 검색할 때, CrewAI는 원시 작업 프롬프트를 더 효과적인 검색 쿼리로 자동 변환해요. 핵심 개념에 집중하고 관련 없는 내용을 걸러내서, 더 관련성 높은 정보를 찾게 해주는 역할이에요.
지식 이벤트¶
지식 검색 과정에서 이벤트를 발생시켜 구독할 수 있어요.
- KnowledgeRetrievalStartedEvent: 에이전트가 지식 소스에서 검색을 시작할 때 발생
- KnowledgeRetrievalCompletedEvent: 검색이 끝났을 때 발생하며, 사용한 쿼리와 검색된 콘텐츠를 담고 있어요
커스텀 지식 소스¶
BaseKnowledgeSource 클래스를 상속하면 어떤 형태의 데이터든 커스텀 지식 소스로 만들 수 있어요. 예를 들어 우주 뉴스 기사를 가져와 처리하는 소스를 만들어 쓰는 식으로 확장해요.
디버깅과 문제 해결¶
검색 테스트¶
크루가 지식에서 잘 가져오는지 직접 확인할 수 있어요.
if hasattr(crew, 'knowledge') and crew.knowledge:
crew_results = crew.query_knowledge(test_query)
print(f"Crew knowledge results: {len(crew_results)} documents found")
컬렉션 검사¶
ChromaDB에 연결해 저장된 컬렉션과 문서 수를 들여다볼 수 있어요.
import chromadb
from crewai.utilities.paths import db_storage_path
import os
knowledge_path = os.path.join(db_storage_path(), "knowledge")
if os.path.exists(knowledge_path):
client = chromadb.PersistentClient(path=knowledge_path)
collections = client.list_collections()
print("Knowledge Collections:")
for collection in collections:
print(f" - {collection.name}: {collection.count()} documents")
if collection.count() > 0:
sample = collection.peek(limit=2)
print(f" Sample content: {sample['documents'][0][:100]}...")
else:
print("No knowledge storage found")
메모리 초기화 명령¶
지식을 초기화하려면 reset_memories에 커맨드 타입을 지정해요.
# 에이전트 지식만 초기화
crew.reset_memories(command_type='agent_knowledge')
# 크루와 에이전트 지식 모두 초기화
crew.reset_memories(command_type='knowledge')
# CLI: 에이전트 지식만
# crewai reset-memories --agent-knowledge
CLI로는 --knowledge 옵션을 줘서 지식만 지울 수 있어요.
모범 사례¶
- 콘텐츠 구성: 콘텐츠 유형에 맞는 청크(chunk) 크기를 유지하고, 문맥 보존을 위해 겹침(overlap)을 고려하며, 관련 정보는 별도의 지식 소스로 묶어요.
- 일회성 지식 (One Time Knowledge): CrewAI 기본 파일 구조에서는 kickoff를 실행할 때마다 지식 소스가 재임베딩돼요. 지식 소스가 크면 매번 같은 데이터를 임베딩하느라 비효율적이고 지연이 생겨요. 이를 피하려면
knowledge_sources파라미터 대신knowledge파라미터를 직접 초기화해서 쓰는 방법이 있어요. 자세한 내용은 관련 GitHub 이슈를 참고해요. - 운영 모범 사례: 프로덕션에서는
CREWAI_STORAGE_DIR을 명확한 위치로 설정하고, LLM 설정과 맞는 임베딩 제공자를 명시적으로 골라 API 키 충돌을 피하며, 문서가 추가되면서 커지는 저장소 크기를 모니터링해요.
더 알아보기¶
- 원문: Knowledge — CrewAI 공식 문서
- 전체 문서 인덱스: https://docs.crewai.com/llms.txt