Ở các bài trước, bạn đã biết cách xây Agent, giao Task, trang bị Tool, ghép thành Crew và điều phối bằng Flow. Nhưng có một vấn đề: mỗi lần chạy, agent lại bắt đầu từ con số 0. Nó không nhớ gì từ lần trước, cũng không biết tham khảo tài liệu bạn đã chuẩn bị sẵn.
Đó là lý do CrewAI có hai hệ thống bổ trợ: Memory giúp agent ghi nhớ, còn Knowledge giúp agent truy cập nguồn kiến thức bên ngoài. Bài này mình sẽ đi sâu vào cả hai, từ cơ chế hoạt động đến cách triển khai trong project thật.
Memory system trong CrewAI

CrewAI sử dụng một hệ thống Memory thống nhất, thay vì tách ra thành nhiều loại riêng biệt như trước. Hệ thống này dùng LLM để phân tích nội dung khi lưu trữ, tự suy luận phạm vi (scope), danh mục (categories) và mức độ quan trọng (importance).
Cơ chế xếp hạng kết quả
Khi truy vấn, Memory xếp hạng kết quả bằng điểm tổng hợp (composite score) kết hợp ba yếu tố:
- Semantic similarity: nội dung có liên quan đến câu hỏi không (dựa trên vector embedding)
- Recency: thông tin mới gần đây hay đã cũ (decay theo thời gian)
- Importance: mức độ quan trọng của thông tin (LLM đánh giá lúc lưu)
Công thức tính điểm:
# composite = semantic_weight * similarity + recency_weight * decay + importance_weight * importance
# Trong đó:
# - similarity = 1 / (1 + distance) từ vector index
# - decay = 0.5^(age_days / half_life_days) phân rã theo thời gian
# - importance = điểm 0-1, LLM gán khi lưu
Cây phân cấp scope
Memory còn tổ chức dữ liệu theo cây phân cấp (hierarchical scopes), giống cấu trúc thư mục. Ví dụ: /project/alpha/decisions, /agent/researcher, /company/engineering. Khi truy vấn trong một scope, chỉ nhánh đó được tìm kiếm, giúp kết quả chính xác và nhanh hơn.
Bạn có thể xem cấu trúc cây scope bất kỳ lúc nào:
memory = Memory()
# Xem toàn bộ cây scope
print(memory.tree())
# / (15 records)
# /project (8 records)
# /project/alpha (5 records)
# /agent (7 records)
# /agent/researcher (4 records)
# Xem chi tiết một scope
print(memory.info("/project/alpha"))
# ScopeInfo(path='/project/alpha', record_count=5, categories=['architecture']...)
ℹ️ Bạn không cần thiết kế cây scope từ đầu. Khi gọi remember() mà không chỉ định scope, LLM sẽ tự phân tích nội dung và đặt vào vị trí phù hợp. Cây scope sẽ tự hình thành theo thời gian.
Memory Slices
Memory còn hỗ trợ Memory Slices cho trường hợp bạn cần agent đọc từ nhiều nhánh scope khác nhau cùng lúc. Ví dụ, một agent cần đọc cả scope riêng lẫn knowledge chung của công ty, nhưng chỉ được quyền đọc (không ghi) vào nhánh công ty:
# Agent đọc từ scope riêng + knowledge chung, chỉ đọc
agent_view = memory.slice(
scopes=["/agent/researcher", "/company/knowledge"],
read_only=True
)
matches = agent_view.recall("quy trình bảo mật", limit=5)
Bật memory cho Crew

Cách đơn giản nhất: truyền memory=True khi tạo Crew. Thế là xong, CrewAI sẽ tự xử lý phần còn lại.
from crewai import Crew, Agent, Task, Process
researcher = Agent(
role="Researcher",
goal="Tìm và phân tích thông tin",
backstory="Chuyên gia nghiên cứu với nhiều năm kinh nghiệm."
)
writer = Agent(
role="Writer",
goal="Viết bài blog chất lượng",
backstory="Cây viết kỹ thuật chuyên nghiệp."
)
research_task = Task(
description="Nghiên cứu về container orchestration",
expected_output="Báo cáo tổng hợp",
agent=researcher
)
writing_task = Task(
description="Viết bài blog dựa trên nghiên cứu",
expected_output="Bài blog hoàn chỉnh",
agent=writer
)
# Bật memory bằng một dòng
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
process=Process.sequential,
memory=True, # Chỉ cần thêm dòng này
verbose=True
)
Khi memory=True, sau mỗi task, Crew tự động trích xuất các fact riêng biệt từ output và lưu vào memory. Trước mỗi task tiếp theo, agent tự động truy vấn memory để lấy context liên quan và đưa vào prompt.
Tinh chỉnh cấu hình Memory
Nếu bạn muốn tinh chỉnh, truyền thẳng một instance Memory với cấu hình riêng:
from crewai import Memory
# Ưu tiên thông tin mới, half-life ngắn (7 ngày)
memory = Memory(
recency_weight=0.5,
semantic_weight=0.3,
importance_weight=0.2,
recency_half_life_days=7
)
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
memory=memory # Truyền instance thay vì True
)
Memory scope cho từng agent
Bạn cũng có thể gán memory riêng cho từng agent bằng memory.scope(). Agent đó sẽ chỉ đọc/ghi trong scope của nó, không thấy dữ liệu của agent khác:
memory = Memory()
# Researcher có scope riêng, chỉ thấy dữ liệu trong /agent/researcher
researcher = Agent(
role="Researcher",
goal="Tìm và phân tích thông tin",
backstory="Chuyên gia nghiên cứu.",
memory=memory.scope("/agent/researcher")
)
# Writer dùng memory chung của crew (không set memory riêng)
writer = Agent(
role="Writer",
goal="Viết bài",
backstory="Cây viết kỹ thuật."
)
💡 Memory còn có tính năng consolidation: khi lưu thông tin trùng lặp, hệ thống tự nhận diện và gộp lại thay vì tạo bản ghi mới. Tránh được tình trạng memory phình lên vô tội vạ.
Memory trong Flow
Memory cũng hoạt động trong Flow. Mỗi Flow có sẵn các method self.remember(), self.recall() và self.extract_memories() để lưu trữ và truy vấn thông tin ngay trong workflow. Ví dụ, bước nghiên cứu lưu phát hiện vào memory, bước viết báo cáo truy vấn lại những phát hiện đó để tổng hợp.
Ngoài ra, method extract_memories() rất tiện khi bạn có một đoạn text dài (ví dụ biên bản cuộc họp) và muốn tách thành các fact nhỏ để lưu riêng. LLM sẽ phân tích và trích xuất từng fact, giúp truy vấn sau này chính xác hơn so với việc lưu nguyên khối text.
Knowledge sources: nạp kiến thức cho agent

Knowledge khác Memory ở chỗ: Memory ghi nhớ những gì agent đã làm và đã học trong quá trình chạy, còn Knowledge là nguồn kiến thức bạn chuẩn bị sẵn từ trước cho agent tham khảo. Giống như cho agent một thư viện tài liệu.
CrewAI hỗ trợ nhiều loại knowledge source:
- String: text thuần, truyền trực tiếp trong code
- Text file (.txt): đọc từ file text
- PDF: tài liệu PDF
- CSV, Excel, JSON: dữ liệu có cấu trúc
- Web content: nạp từ URL (cần cài thêm thư viện
docling)
Ví dụ nạp knowledge từ string và PDF:
from crewai import Agent, Task, Crew, Process
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
# Nguồn 1: thông tin dạng text
company_info = StringKnowledgeSource(
content="Công ty XYZ thành lập năm 2020, chuyên về hosting và cloud. Có 50 nhân viên, trụ sở tại TP.HCM."
)
# Nguồn 2: tài liệu PDF (đặt trong thư mục knowledge/ ở root project)
technical_docs = PDFKnowledgeSource(
file_paths=["product-specs.pdf", "api-reference.pdf"]
)
# Gán knowledge cho crew (tất cả agent đều truy cập được)
crew = Crew(
agents=[support_agent],
tasks=[answer_task],
process=Process.sequential,
knowledge_sources=[company_info, technical_docs]
)
Gán knowledge cho từng agent
Bạn cũng có thể gán knowledge riêng cho từng agent thay vì cho cả crew:
# Agent-level knowledge: chỉ agent này mới thấy
specialist = Agent(
role="Technical Specialist",
goal="Trả lời câu hỏi kỹ thuật chuyên sâu",
backstory="Chuyên gia kỹ thuật.",
knowledge_sources=[technical_docs] # Chỉ specialist mới dùng
)
⚠️ File knowledge source cần đặt trong thư mục knowledge/ ở root project. Khi khai báo file_paths, dùng đường dẫn tương đối từ thư mục knowledge/.
Storage và vector store
Phía dưới, CrewAI dùng ChromaDB (mặc định) hoặc Qdrant làm vector store để lưu và truy vấn knowledge. Mỗi knowledge source được chunk, embedding và lưu vào collection riêng. Khi agent cần thông tin, hệ thống tự động tìm kiếm các đoạn liên quan nhất.
Về storage, knowledge của crew và agent được lưu trong các collection tách biệt trên cùng ChromaDB instance:
- Crew knowledge: collection tên “crew”
- Agent knowledge: collection tên theo role của agent (ví dụ “Technical Specialist”)
- Đường dẫn lưu trữ:
~/.local/share/CrewAI/{project_name}/knowledge/(Linux) hoặc~/Library/Application Support/CrewAI/{project_name}/knowledge/(macOS)
Mỗi agent có thể dùng embedder riêng. Ví dụ agent A dùng OpenAI embedding, agent B dùng Ollama local. Nếu agent không khai báo embedder, nó sẽ dùng embedder của crew làm fallback.
Agentic RAG: tìm kiếm thông minh

Cái hay của Knowledge trong CrewAI là nó hoạt động như một dạng RAG (Retrieval-Augmented Generation) tự động. Bạn không cần viết logic retrieval riêng, không cần tạo tool tìm kiếm rồi giao cho agent. Hệ thống tự biết khi nào cần tra cứu và trả kết quả phù hợp nhất.
Quy trình phía sau:
- Knowledge source được chunk thành các đoạn nhỏ
- Mỗi đoạn được embedding thành vector và lưu vào vector store
- Khi agent nhận task, hệ thống tự truy vấn vector store với nội dung task
- Các đoạn liên quan nhất được inject vào prompt của agent
- Agent trả lời dựa trên context đã được bổ sung
Tinh chỉnh RAG
Bạn có thể tinh chỉnh RAG qua KnowledgeConfig:
from crewai.knowledge.knowledge_config import KnowledgeConfig
config = KnowledgeConfig(
results_limit=10, # Số đoạn tài liệu trả về (mặc định 3)
score_threshold=0.5 # Điểm tối thiểu để coi là liên quan (mặc định 0.35)
)
agent = Agent(
role="Support Agent",
goal="Trả lời câu hỏi khách hàng",
backstory="Nhân viên hỗ trợ kỹ thuật.",
knowledge_config=config # Áp dụng cấu hình riêng
)
Custom RAG client
Nếu bạn cần kiểm soát sâu hơn (custom retrieval pipeline, tích hợp vector store riêng), CrewAI cung cấp RAG client abstraction:
from crewai.rag.config.utils import set_rag_config, get_rag_client
# Chuyển sang Qdrant thay vì ChromaDB mặc định
from crewai.rag.qdrant.config import QdrantConfig
set_rag_config(QdrantConfig())
client = get_rag_client()
client.create_collection(collection_name="docs")
client.add_documents(
collection_name="docs",
documents=[{"id": "1", "content": "Nội dung tài liệu cần index..."}]
)
results = client.search(collection_name="docs", query="câu hỏi tìm kiếm", limit=3)
ℹ️ RAG client này tách biệt với Knowledge built-in. Dùng nó khi bạn cần truy cập vector store trực tiếp hoặc xây pipeline retrieval tùy chỉnh.
Ví dụ: crew có memory và knowledge từ PDF

Ghép tất cả lại, mình sẽ tạo một crew hỗ trợ khách hàng. Crew này vừa có knowledge từ tài liệu sản phẩm (PDF), vừa có memory để nhớ các câu hỏi đã trả lời trước đó.
from crewai import Agent, Task, Crew, Process, Memory
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai.knowledge.source.string_knowledge_source import StringKnowledgeSource
# === Knowledge: tài liệu sản phẩm ===
product_docs = PDFKnowledgeSource(
file_paths=["product-manual.pdf"] # Đặt trong thư mục knowledge/
)
faq_data = StringKnowledgeSource(
content="""
Q: Hosting có hỗ trợ Node.js không?
A: Có, gói Pro trở lên hỗ trợ Node.js 18+ qua SSH.
Q: Làm sao reset password cPanel?
A: Vào trang quản lý dịch vụ, chọn hosting cần reset, bấm "Đổi mật khẩu".
Q: Có được cài SSL miễn phí không?
A: Có, tất cả gói hosting đều hỗ trợ Let's Encrypt SSL miễn phí.
"""
)
# === Memory: ưu tiên thông tin gần đây ===
memory = Memory(
recency_weight=0.4,
semantic_weight=0.4,
importance_weight=0.2,
recency_half_life_days=14
)
# === Agent ===
support_agent = Agent(
role="Customer Support",
goal="Trả lời câu hỏi khách hàng chính xác, dựa trên tài liệu sản phẩm",
backstory="Nhân viên hỗ trợ kỹ thuật với kiến thức sâu về sản phẩm hosting.",
verbose=True
)
# === Task ===
answer_task = Task(
description="Trả lời câu hỏi: {question}",
expected_output="Câu trả lời rõ ràng, có dẫn nguồn từ tài liệu nếu có",
agent=support_agent
)
# === Crew: kết hợp cả memory lẫn knowledge ===
crew = Crew(
agents=[support_agent],
tasks=[answer_task],
process=Process.sequential,
memory=memory,
knowledge_sources=[product_docs, faq_data],
verbose=True
)
# Chạy lần 1
result1 = crew.kickoff(inputs={"question": "Hosting có cài được Node.js không?"})
print(result1)
# Chạy lần 2: agent nhớ câu hỏi lần trước nhờ memory
result2 = crew.kickoff(inputs={"question": "Lúc nãy tôi hỏi về cái gì nhỉ?"})
Ở lần chạy thứ hai, nhờ có memory, agent biết được lần trước khách hỏi về Node.js. Còn thông tin trả lời thì lấy từ knowledge (PDF và FAQ data). Hai hệ thống bổ trợ nhau: Knowledge cung cấp kiến thức nền, Memory cung cấp ngữ cảnh hội thoại.
💡 Để chạy các pipeline AI nặng với nhiều agent, memory và knowledge, bạn cần server có đủ RAM và CPU. Tham khảo Pro VPS tại AZDIGI nếu cần môi trường ổn định cho production.
Khi nào dùng Memory, khi nào dùng Knowledge

Hai hệ thống này giải quyết hai bài toán khác nhau, và bạn hoàn toàn có thể dùng cả hai cùng lúc. Dưới đây là cách phân biệt nhanh:
Dùng Memory khi
- Agent cần nhớ kết quả từ các lần chạy trước
- Bạn muốn agent tích lũy kinh nghiệm qua nhiều phiên làm việc
- Cần context hội thoại liên tục (chatbot, support agent)
- Thông tin thay đổi theo thời gian (quyết định mới, cập nhật dự án)
Dùng Knowledge khi
- Agent cần tra cứu tài liệu có sẵn (docs, manual, FAQ)
- Bạn có nguồn dữ liệu tĩnh muốn agent tham khảo
- Cần “ground” agent vào thông tin thực tế, tránh hallucination
- Dữ liệu domain-specific mà LLM chưa biết (nội bộ công ty, sản phẩm riêng)
Dùng cả hai khi
- Agent hỗ trợ khách hàng: Knowledge chứa docs sản phẩm, Memory nhớ lịch sử tương tác
- Agent nghiên cứu: Knowledge chứa papers/tài liệu, Memory lưu các phát hiện đã tổng hợp
- Agent quản lý dự án: Knowledge chứa quy trình/policy, Memory nhớ quyết định và tiến độ
ℹ️ Khác biệt cốt lõi: Knowledge là dữ liệu bạn nạp vào từ trước (read-only từ góc nhìn agent), Memory là dữ liệu agent tự tạo ra trong quá trình hoạt động (read-write).
Trong một số trường hợp ranh giới giữa hai hệ thống hơi mờ. Ví dụ, bạn có thể lưu FAQ vào Knowledge (vì nó là tài liệu cố định), nhưng cũng có thể dùng Memory để agent tự “học” những câu hỏi mới mà khách hàng hay hỏi. Cách tiếp cận tốt nhất là bắt đầu với Knowledge cho dữ liệu đã có sẵn, bật Memory khi cần agent tích lũy kinh nghiệm qua thời gian, rồi điều chỉnh dần dựa trên kết quả thực tế.
Một tip nữa: nếu bạn cần test nhanh xem agent có truy vấn đúng knowledge hay không, bật verbose=True cho cả agent và crew. CrewAI sẽ in ra log chi tiết quá trình retrieval, giúp bạn biết đoạn nào của tài liệu được inject vào prompt.
Câu hỏi thường gặp
Memory và Knowledge là hai mảnh ghép giúp agent trong CrewAI trở nên thông minh hơn so với việc chỉ dùng LLM thuần. Kết hợp với Flow, bạn có đủ công cụ để xây dựng hệ thống AI phức tạp, có khả năng ghi nhớ, tra cứu tài liệu, và điều phối workflow tự động. Quay lại bài tổng quan CrewAI nếu bạn cần ôn lại kiến thức nền.
Có thể bạn cần xem thêm
- Tool trong CrewAI: mở rộng khả năng agent
- Flow trong CrewAI: xây dựng workflow phức tạp theo sự kiện
- Agent trong CrewAI: tạo AI worker chuyên biệt
- CrewAI là gì? Hướng dẫn xây dựng hệ thống Multi-Agent AI với Python
- Task trong CrewAI: giao việc cho AI agent
- n8n + AI: Xây dựng Workflow tự động với ChatGPT và LLMs
Về tác giả
Trần Thắng
Chuyên gia tại AZDIGI với nhiều năm kinh nghiệm trong lĩnh vực web hosting và quản trị hệ thống.