Views
No views yet
Search != Crawl != Rerank"So sánh LangGraph và CrewAI năm 2026"
1[
2 {
3 "title": "...",
4 "url": "https://..."
5 },
6 {
7 "title": "...",
8 "url": "https://..."
9 }
10]1[
2 {
3 "title": "...",
4 "snippet": "LangGraph is..."
5 }
6]100-300 ký tựLangGraph vs CrewAI: A detailed comparison...5000 từLLM chỉ đọc snippet1Search
2 ↓
3URL
4 ↓
5Download page
6 ↓
7Extract text
8 ↓
9LLM đọchttps://blog.langchain.com/...1# LangGraph vs CrewAI
2
3...1url
2 ↓
3playwright
4 ↓
5render javascript
6 ↓
7clean html
8 ↓
9markdown1# Article title
2
3Some text...
4
5## Section
6
7Some text...1Search
2 ↓
3Snippet
4 ↓
5LLM20 URLsLangGraph memory architecture11. LangGraph Docs
22. LangChain Blog
33. Reddit
44. Youtube
55. Random Medium
6...
720 URLs120 x 3000 từ
2
3≈ 60000 từ1Question
2+
320 documents
4
5 ↓
6
7Top 311. LangGraph Docs
22. LangChain Blog
33. Github1RTX 4060 Laptop
2Qwen3 4B1Search
2 ↓
3Crawl
4 ↓
5LLM chọn1urls = search(query)
2
3pages = crawl(urls[:10])
4
5selected = llm_select_relevant_pages(
6 query,
7 pages
8)1SearchProvider
2 SearXNG
3
4ContentProvider
5 Crawl4AI
6
7LLMProvider
8 Ollama(Qwen3)1Question
2
3 ↓
4
5Search
6
7 ↓
8
9Top 10 URLs
10
11 ↓
12
13Crawl
14
15 ↓
16
17Markdown
18
19 ↓
20
21LLM Filter
22
23 ↓
24
25Top 3 pages
26
27 ↓
28
29Summary
30
31 ↓
32
33Report1Question
2
3 ↓
4
5Search
6
7 ↓
8
9Crawl
10
11 ↓
12
13Embedding
14 (Qwen Embedding)
15
16 ↓
17
18Cosine Similarity
19
20 ↓
21
22Top 5
23
24 ↓
25
26LLM1Ollama (Qwen3)
2+
3SearXNG
4+
5Crawl4AI
6+
7Qwen Embedding (sau này)1OpenAI -> Ollama (Qwen3)
2Tavily -> Free / Self-hosted SearchGET /search?q=langgraph&format=json1{
2 "results": [...]
3}1Planner
2 ↓
3Tavily Search
4 ↓
5Summary1Planner
2 ↓
3SearXNG
4 ↓
5Summary1docker run -d \
2 --name searxng \
3 -p 8080:8080 \
4 searxng/searxng1curl \
2"http://localhost:8080/search?q=langgraph&format=json"GET https://api.search.brave.com/res/v1/web/search1Tavily
2 ↓
3Brave Searchpip install duckduckgo-searchpip install ddgs1from ddgs import DDGS
2
3with DDGS() as ddgs:
4 results = ddgs.text(
5 "LangGraph Open Deep Research",
6 max_results=10
7 )https://s.jina.ai/search?q=langgraphhttps://r.jina.ai/http://example.com1Search
2 ↓
3URL
4 ↓
5Reader
6 ↓
7Markdown1Qwen3:4B
2Ollama
3LangGraph1Open Deep Research Refactor
2
3LLM:
4 Ollama
5 Qwen3:4B
6
7Search:
8 SearXNG
9
10Crawler:
11 Crawl4AI
12
13Reranker:
14 BGE-reranker-v2-m3
15
16Workflow:
17 LangGraph
18
19Storage:
20 Local SQLite1Search
2 ↓
3Fetch Page
4 ↓
5Clean Text1SearchService
2 SearXNG
3
4CrawlerService
5 Crawl4AI
6
7ContentExtractor
8 Trafilatura
9
10RerankerService
11 BGE-Reranker1Question
2
3 ↓
4
5SearchService
6
7 ↓
8
920 URLs
10
11 ↓
12
13CrawlerService
14
15 ↓
16
1720 Markdown Pages
18
19 ↓
20
21Reranker
22
23 ↓
24
25Top 5
26
27 ↓
28
29LLM Summary1ResearchService
2├── SearchProvider
3│ └── SearXNG
4│
5├── CrawlProvider
6│ └── Crawl4AI
7│
8├── RankingProvider
9│ └── BGE-Reranker
10│
11└── LLMProvider
12 └── Ollama Qwen3| Open Deep Research | Hiện tại của bạn |
|---|---|
| OpenAI GPT-4o | Ollama Qwen3:4B ✅ |
| Tavily Search | SearXNG ✅ |
1Question
2 ↓
3SearXNG
4 ↓
5URLs1Question
2 ↓
3Qwen31Search
2 ↓
3URLs
4 ↓
5Read URL
6 ↓
7Page Content
8 ↓
9LLMhttps://docs.langchain.com/...1# Memory overview
2
3LangGraph manages short-term memory...
4...pip install trafilatura1import trafilatura
2
3url = "https://docs.langchain.com/oss/python/concepts/memory"
4
5downloaded = trafilatura.fetch_url(url)
6
7text = trafilatura.extract(downloaded)
8
9print(text[:2000])ReadURLTool1Question
2 ↓
3Embedding
4
5Document
6 ↓
7Embedding
8
9Cosine Similarityollama pull nomic-embed-textollama pull mxbai-embed-largenomic-embed-text1import ollama
2
3embedding = ollama.embed(
4 model="nomic-embed-text",
5 input="What is LangGraph memory?"
6)1docs.langchain.com/page1
2docs.langchain.com/page2
3docs.langchain.com/page31same article
2same article
3same articleclass URLDeduplicator:class DocumentDeduplicator:hash(content)embedding similarityHow does LangGraph memory work?1Planner
2
3↓11. LangGraph memory architecture
22. Short-term memory
33. Long-term memory
44. Checkpointer
55. Store API5 search queriesSearch 1 lầnSearch N lầnCollected Evidence1Tôi đã trả lời đủ chưa?
2
3YES -> Report
4
5NO -> Search tiếp1while True:
2
3 search()
4
5 summarize()
6
7 if enough_information():
8 breakQuestion -> Answer1Question
2
3↓
4Evidence
5
6↓
7Outline
8
9↓
10Report1# Overview
2
3# Memory Architecture
4
5# Short-term Memory
6
7# Long-term Memory
8
9# Best Practices
10
11# References1Qwen3
2+
3SearXNG
4+
5Trafilatura1Qwen3
2+
3SearXNG
4+
5Trafilatura
6+
7nomic-embed-text
8+
9Cosine SimilarityPlannerReflection LoopSearch again?Report Writer1OpenAI ✅
2Tavily ✅
3
4Crawler ❌
5Embedding ❌
6Planner ❌
7Reflection ❌
8Report ❌1Trafilatura
2+
3nomic-embed-textSearch EngineResearch Engine1Supervisor
2 ↓
3ConductResearch Tool Call
4 ↓
5researcher_subgraph.ainvoke(...)
6 ↓
7Researcher
8 ↓
9Researcher Tools
10 ↓
11Search API1Supervisor Agent
2 ↓
3Researcher Agent
4 ↓
5Search Tool1Agent
2 ↓
3Agent
4 ↓
5Tool1SupervisorManager
2 ↓
3ResearchTask
4 ↓
5ResearchExecutor
6 ↓
7SearchProvider
8 ↓
9CrawlerProviderresearcher_subgraph1domains/
2└── researcher/SupervisorManager.decide()ResearchTask[]ResearchExecutor.execute()1class ResearchResult(BaseModel):
2
3 research_topic: str
4
5 summary: str1class ResearchExecutor:
2
3 async def execute(
4 self,
5 task: ResearchTask
6 ) -> ResearchResult:
7
8 return ResearchResult(
9 research_topic=
10 task.research_topic,
11
12 summary=
13 f"Fake research for "
14 f"{task.research_topic}"
15 )1results = await asyncio.gather(
2 *[
3 executor.execute(task)
4 for task in tasks
5 ]
6)1Supervisor
2 ↓
3ResearchTask
4 ↓
5ResearchResult1services/
2├── search/
3└── crawler/SearXNG1class SearchProvider:
2
3 async def search(
4 self,
5 query: str
6 )1[
2 SearchResult(...),
3 SearchResult(...),
4]1class CrawlProvider:
2
3 async def crawl(
4 self,
5 url: str
6 )1PageContent(
2 title=...
3 content=...
4)ResearcherManager1class ResearcherManager:
2
3 async def research(
4 self,
5 task: ResearchTask
6 ) -> ResearchResult:1Research Topic
2 ↓
3SearchProvider
4 ↓
5Top URLs
6 ↓
7CrawlerProvider
8 ↓
9Collected Docs
10 ↓
11LLM Summary1Supervisor Agent
2 ↓
3Researcher Agent
4 ↓
5Search Tool1SupervisorManager
2 ↓
3ResearchTask
4 ↓
5ResearcherManager
6 ↓
7SearchProvider
8 ↓
9CrawlerProvider
10 ↓
11LLMBước tiếp theo có phải tạo N researcher subgraph không?
Chưa.1ResearchResult
2ResearchExecutor1tasks
2 ↓
3asyncio.gather(...)
4 ↓
5resultsresearcher_subgraph.ainvoke(...)ResearcherManager bên trong. Đây sẽ là một bước refactor rất tự nhiên và ít rủi ro hơn nhiều.Crawler LibraryCrawling Platform1urls = [
2 "https://langchain.com",
3 "https://github.com/langchain-ai/langgraph"
4]
5
6for url in urls:
7
8 html = requests.get(url).text
9
10 markdown = html_to_markdown(html)Không cần database1URL
2 ↓
3HTML
4 ↓
5Markdown
6 ↓
7LLMAgentic Crawling Platform1- crawl history
2- cache
3- session
4- metadata1Question:
2What is LangGraph?https://langchain.com/langgraph1URL
2 ↓
3Browser render
4 ↓
5Markdown5 giây1Question:
2Compare LangGraph with CrewAIhttps://langchain.com/langgraphrender lại từ đầu1SELECT markdown
2FROM cache
3WHERE url = ...10ms100 websites1url
2
3crawl_time
4
5status
6
7title
8
9content_hash1URL nào đã crawl
2
3URL nào lỗi
4
5URL nào timeout1Google
2 ↓
3
4URL A
5
6DuckDuckGo
7 ↓
8
9URL Acrawl URL A hai lầnURL A đã tồn tạihttps://langchain.com/blogcrawlcrawl lạicontent_hashhash cũ == hash mớikhông cần re-index1context
2
3cookies
4
5storage_state1cookies
2
3auth sessionkhông phải login lạiOpen Deep Research1Question
2 ↓
3
4SearXNG
5 ↓
6
7Top K URLs
8 ↓
9
10Crawl4AI
11 ↓
12
13Markdown
14 ↓
15
16LLMstateless service1result = await crawler.arun(url)
2
3markdown = result.markdown1- cache website
2- tránh crawl lại
3- research nhiều vòng
4- incremental crawling1services/
2
3 crawler/
4
5 cache/
6
7 storage/1Postgres
2
3hoặc
4
5SQLiteCrawl4AI DBimplementation detail1Document Cache
2Research Cachebusiness data1SearXNG
2 ↓
3Top URLs
4 ↓
5Crawl4AI
6 ↓
7Markdown
8 ↓
9LLM1cache
2history
3deduplication
4session persistence
5incremental crawling~/.crawl4ai/crawl4ai.db~/.crawl4ai/crawl4ai.db.backup_...ls ~/.crawl4aiSQLite database1mv ~/.crawl4ai/crawl4ai.db \
2 /mnt/data/crawl4ai/crawl4ai.dbln -s /mnt/data/crawl4ai ~/.crawl4aiSSD hệ thống nhỏmuốn mount volume docker1import sqlite3
2
3conn = sqlite3.connect(
4 "/home/hachan/.crawl4ai/crawl4ai.db"
5)1SELECT name
2FROM sqlite_master
3WHERE type='table';1UPDATE ...
2DELETE ...1Crawl4AI update version
2↓
3schema thay đổi
4↓
5code của bạn hỏngREAD ONLY1SearXNG
2 ↓
3Crawl4AI
4 ↓
5Markdown
6 ↓
7Qdrantcrawl4ai.db1class CrawledDocument:
2
3 url: str
4
5 markdown: str
6
7 title: str
8
9 crawl_time: datetime1URL
2 ↓
3
4Crawl4AI
5
6 ↓
7
8Markdown
9
10 ↓
11
12MinIO1URL
2 ↓
3
4Crawl4AI
5
6 ↓
7
8Markdown
9
10 ↓
11
12Postgresinternal cachestorage/1src/
2
3services/
4 crawler/
5
6 storage/
7
8 postgres.py
9
10 minio.py1URL
2 ↓
3
4Crawl4AI
5
6 ↓
7
8Markdown
9
10 ↓
11
12Storage Service1Crawl4AI
2↓
3Firecrawl
4↓
5Browserbase