CrewAI + Scrapeless: Vận hành một đội ngũ thu thập dữ liệu đa tác nhân với một Mô hình Ngôn ngữ Địa phương.
Advanced Bot Mitigation Engineer
Tóm tắt:
- Đây là một quy trình làm việc đa tác nhân thực sự. Ba tác nhân CrewAI lấy một trang trực tiếp, trích xuất các bản ghi có cấu trúc và xác thực kết quả thông qua việc chuyển giao nhiệm vụ tuần tự.
- Chỉ có trình thu thập mới có quyền truy cập web. Trình thu thập trang web nhận công cụ
scrape_markdowncủa Scrapeless MCP; người trích xuất và người xác thực chỉ làm việc từ các đầu ra của nhiệm vụ trước đó. - LLM chạy cục bộ. Tất cả ba tác nhân sử dụng
qwen2.5:0.5bthông qua Ollama, vì vậy quy trình làm việc không yêu cầu khóa API LLM đám mây. - Thực hiện thành công không chứng minh trích xuất đúng.
crew.kickoff()đã hoàn tất, nhưng đầu ra của trình xác thực thu nhận mâu thuẫn với chính nó và phải bị từ chối. - Xác thực sản xuất phải định lượng. Phân tích đầu ra của mô hình bằng Python, xác thực các trường cần thiết và so sánh các giá trị đã trích xuất với phản hồi MCP ban đầu.
- Miễn phí để bắt đầu. Các tài khoản Scrapeless mới bao gồm thời gian chạy Trình duyệt Trích xuất miễn phí — đăng ký tại app.scrapeless.com.
Giới thiệu: Một Đội Đã Hoàn Thành Chưa Chắc Chắn Là Một Đường Ống Đáng Tin Cậy
Một Agent CrewAI kết nối với công cụ Scrapeless MCP đã có thể lấy một trang trực tiếp. Một đội CrewAI là một tuyên bố khác: hai hoặc nhiều tác nhân với các trách nhiệm riêng biệt phải chuyển giao công việc cho nhau và hoàn tất với crew.kickoff() trả về một kết quả.
Hướng dẫn này xây dựng quy trình làm việc thứ hai đó.
Bạn sẽ tạo ra một đội ba tác nhân mà:
- Lấy một trang trực tiếp thông qua máy chủ Scrapeless MCP.
- Trích xuất các bản ghi trích dẫn có cấu trúc từ Markdown đã trả về.
- Xác thực những bản ghi đó trước khi chúng rời khỏi quy trình làm việc.
Tất cả ba tác nhân chạy trên một mô hình Ollama cục bộ. Không cần khóa OpenAI, Anthropic hay bất kỳ khóa LLM đám mây nào khác. Chỉ có thông tin xác thực bên ngoài là khóa API Scrapeless được sử dụng bởi công cụ MCP.
Sự tích hợp hoàn thành thành công. Tuy nhiên, câu trả lời cuối cùng được thu nhận lại không nhất quán bên trong. Sự phân biệt đó là bài học quan trọng nhất trong hướng dẫn này: một quy trình làm việc của tác nhân đã hoàn tất là bằng chứng của việc thực hiện, không phải bằng chứng rằng dữ liệu kết quả là đáng tin cậy.
Những Gì Bạn Có Thể Làm Với Đội Này
Quy trình làm việc giao một trách nhiệm cho mỗi tác nhân:
- Trình thu thập trang web: Gọi công cụ
scrape_markdowncủa Scrapeless MCP đối với một URL trực tiếp và trả về nội dung trang. - Chuyên gia trích xuất dữ liệu: Đọc Markdown đã lấy và chuyển đổi nó thành một mảng JSON.
- Người xác thực QA: Kiểm tra các bản ghi đã trích xuất để tìm các trường thiếu và báo cáo kết quả.
CrewAI truyền các đầu ra nhiệm vụ thông qua ngữ cảnh nhiệm vụ rõ ràng. Người trích xuất nhận đầu ra của nhiệm vụ lấy, và người xác thực nhận đầu ra của nhiệm vụ trích xuất.
Không cần phải sao chép thủ công giữa ba tác nhân.
Điều này khác với việc kết nối một mô hình cục bộ trực tiếp vào một hàm Python để lấy và trích xuất. Hướng dẫn trích xuất web Ollama đề cập đến mẫu đơn giản hơn đó.
Ở đây, CrewAI sở hữu việc dàn dựng:
- Ba tác nhân
- Ba lời nhắc riêng biệt
- Ba giới hạn token riêng biệt
- Một việc chuyển giao tuần tự do khung quản lý
Tại Sao Sử Dụng Một Đội Thay Vì Một Tác Nhân?
Một tác nhân đơn lẻ với một công cụ trích xuất phải quyết định cái gì để lấy, cách để diễn giải trang, cách để định dạng kết quả, và liệu kết quả đó có chấp nhận được hay không.
Chia nhỏ các trách nhiệm đó thành các vai trò riêng biệt giúp bạn kiểm soát quy trình làm việc rõ ràng hơn.
Mỗi tác nhân nhận:
- Một mục tiêu hẹp
- Một nhiệm vụ tập trung
- Giới hạn đầu ra riêng của nó
- Chỉ có quyền truy cập vào các công cụ mà nó cần
Điều này đặc biệt hữu ích với các mô hình cục bộ nhỏ hơn. Thay vì yêu cầu một mô hình quay để lấy, trích xuất, định dạng và xác thực đồng thời, mỗi lượt xử lý một công việc giới hạn hơn.
Sự phân tách cũng giúp bạn có các điểm kiểm tra rõ ràng hơn. Trong một quy trình sản xuất, bạn có thể lưu hoặc xác thực đầu ra sau mỗi nhiệm vụ và xác định xem lỗi đã xảy ra trong quá trình lấy, trích xuất hay xác thực.
Tại Sao Chọn Máy Chủ Scrapeless MCP?
Chỉ tiêu giao thức ngữ cảnh mô hình định nghĩa một cách tiêu chuẩn để một khách hàng AI khám phá và kích hoạt các công cụ được máy chủ cung cấp.
Máy chủ Scrapeless MCP cung cấp dữ liệu web và khả năng trình duyệt thông qua giao diện công cụ đó. CrewAI không cần thực hiện việc hiển thị trang, định tuyến proxy, hoặc hạ tầng trình duyệt trực tiếp. Nó chỉ cần kết nối với máy chủ và gắn công cụ cần thiết vào một tác nhân.
Bài viết tổng quan về Máy chủ Scrapeless MCP giải thích về gia đình công cụ rộng hơn, bao gồm việc lấy trang, tìm kiếm, và các công cụ điều khiển trình duyệt.
Đối với quy trình làm việc này, đội chỉ cần một công cụ:
text
scrape_markdown
Nó truy xuất trang mục tiêu và trả về nội dung theo định dạng mà tác nhân trích xuất phía dưới có thể đọc được.
Bạn có thể kiểm tra tài liệu phát triển Scrapeless để biết thông tin kết nối máy chủ và các tham số công cụ mới nhất.
Yêu cầu trước
Trước khi chạy đội, bạn cần:
- Python 3.10 trở lên
- CrewAI và Công cụ CrewAI
- Một khóa API Scrapeless
- Ollama đã được cài đặt và chạy cục bộ
- Mô hình
qwen2.5:0.5bđã được tải xuống trong Ollama
Bạn không cần OPENAI_API_KEY, ANTHROPIC_API_KEY, hoặc bất kỳ tài liệu xác thực LLM nào khác. Mỗi đối tượng LLM của CrewAI trong ví dụ này đều hướng tới máy chủ Ollama cục bộ.
Bước 1 — Cài đặt CrewAI và Hỗ trợ MCP
Ví dụ đã được xác minh sử dụng các gói CrewAI đã cố định:
bash
pip install "crewai==1.15.4" "crewai-tools[mcp]==1.15.4"
Phần bổ sung [mcp] cài đặt các phụ thuộc của khách hàng MCP cần thiết cho MCPServerAdapter. Bộ chuyển đổi này chuyển đổi các định nghĩa công cụ MCP thành các công cụ mà các tác nhân CrewAI có thể gọi.
Bước 2 — Cấu hình Mô hình Ollama Cục bộ
Kéo mô hình được sử dụng trong ví dụ này:
bash
ollama pull qwen2.5:0.5b
Xác nhận rằng Ollama có thể nhìn thấy nó:
bash
ollama list
Ollama thường công khai API cục bộ của nó tại:
text
http://localhost:11434
Nếu Ollama đã được cài đặt nhưng đội không thể kết nối, hãy xác nhận rằng dịch vụ Ollama đang chạy trước khi khởi chạy tập lệnh Python.
Tiếp theo, cấu hình khóa API Scrapeless trong shell của bạn:
bash
export SCRAPELESS_API_KEY="your_api_key_here"
Việc đọc khóa từ biến môi trường giữ cho nó không xuất hiện trong tệp nguồn Python.
Bước 3 — Hướng CrewAI tới Ollama
Tạo một cấu hình LLM riêng biệt cho mỗi tác nhân:
python
from crewai import LLM
fetch_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=180,
temperature=0,
)
extract_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=100,
temperature=0,
)
validate_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=70,
temperature=0,
)
Cả ba cấu hình đều sử dụng cùng một mô hình, nhưng giới hạn đầu ra của họ phản ánh trách nhiệm của họ:
- Bộ thu có nhiều không gian hơn để trả về nội dung trang.
- Bộ trích cần đủ token cho một mảng JSON ngắn.
- Bộ xác thực chỉ cần sản xuất một báo cáo gọn gàng.
Cài đặt temperature=0 giảm sự biến đổi đầu ra. Nó không đảm bảo kết quả xác định hoặc chính xác, đặc biệt với một mô hình cục bộ nhỏ.
Khi suy diễn cục bộ chỉ trên CPU, max_tokens cũng là một yếu tố kiểm soát thời gian chạy quan trọng. Giới hạn thấp hơn ngăn một tác nhân tạo ra những phản hồi dài không cần thiết, mặc dù kích thước mô hình, phần cứng, độ dài ngữ cảnh và số lượt tác nhân cũng ảnh hưởng đến thời gian thực thi.
Bước 4 — Kết nối CrewAI với Máy chủ MCP Scrapeless
Nhập MCPServerAdapter và xác định kết nối MCP từ xa:
python
import os
from crewai_tools import MCPServerAdapter
server_params = {
"url": "https://api.scrapeless.com/mcp",
"transport": "streamable-http",
"headers": {
"x-api-token": os.environ["SCRAPELESS_API_KEY"]
},
}
Cấu hình chứa ba giá trị quan trọng:
urlchỉ đến điểm cuối MCP của Scrapeless.transportcho biết khách hàng sử dụng Streamable HTTP.x-api-tokenxác thực yêu cầu bằng khóa Scrapeless của bạn.
Khóa được truy cập bằng:
python
os.environ["SCRAPELESS_API_KEY"]
Python sẽ dừng ngay lập tức nếu biến môi trường bị thiếu, điều này là tốt hơn việc khởi động một đội mà không có chứng thực công cụ hợp lệ.
Bước 5 — Xác minh Công cụ MCP Có sẵn
Trước khi xây dựng đội hoàn chỉnh, hãy xác minh rằng bộ chuyển đổi có thể phát hiện công cụ yêu cầu:
python
with MCPServerAdapter(server_params, "scrape_markdown") as tools:
print([tool.name for tool in tools])
Chạy xác minh đã trả về:
text
['scrape_markdown']
Điều này xác nhận rằng:
- Khách hàng MCP đã đến máy chủ.
- Máy chủ đã chấp nhận tiêu đề xác thực.
- Công cụ yêu cầu có sẵn cho CrewAI.
Nó không chứng minh rằng mọi yêu cầu trang trong tương lai sẽ chứa dữ liệu mong đợi, hoặc rằng một mô hình phía dưới sẽ diễn giải phản hồi đúng cách.
Bề mặt Công cụ MCP Sử Dụng Tại Đây
MCPServerAdapter có thể phơi bày các công cụ máy chủ cho các tác nhân CrewAI. Việc truyền "scrape_markdown" giới hạn quy trình này chỉ với công cụ duy nhất mà nó cần:
python
with MCPServerAdapter(server_params, "scrape_markdown") as tools:
...
Bề mặt công cụ hạn chế này rất hữu ích cho độ tin cậy của tác nhân. Bộ thu không cần phải chọn từ các công cụ trình duyệt hoặc tìm kiếm không liên quan, và các tác nhân trích xuất và xác thực hoàn toàn không nhận được công cụ nào.
Giới hạn quyền truy cập thì rõ ràng:
| Tác nhân | Quyền truy cập Công cụ | Trách nhiệm |
|---|---|---|
| Người Lấy Trang Web | scrape_markdown |
Truy xuất trang mục tiêu |
| Chuyên Gia Trích Dữ Liệu | None | Chuyển đổi nội dung đã lấy thành JSON |
| Người Kiểm Tra QA | None | Kiểm tra các bản ghi đã trích xuất |
Chỉ có người lấy trang mới có thể thực hiện yêu cầu web trực tiếp.
Cách Sử Dụng Thực Tế: Xây Dựng và Chạy Đội
Xác Định Ba Vai Trò Đại Diện
Tạo một Agent cho mỗi giai đoạn:
python
from crewai import Agent
fetcher = Agent(
role="Người Lấy Trang Web",
goal=(
"Lấy URL chính xác được cung cấp bằng cách sử dụng công cụ scrape_markdown "
"và trả lại đầu ra thô của nó."
),
backstory=(
"Lấy các trang web công khai cho các đồng đội không thể "
"duyệt web một cách độc lập."
),
tools=tools,
llm=fetch_llm,
max_iter=2,
)
extractor = Agent(
role="Chuyên Gia Trích Dữ Liệu",
goal=(
"Chuyển đổi markdown của trang đã lấy thành một bản ghi có cấu trúc "
"sạch sẽ cho mỗi câu trích dẫn và tác giả của nó."
),
backstory=(
"Đọc markdown thô đã lấy và lấy chính xác các "
"trường mà cơ sở dữ liệu cần."
),
llm=extract_llm,
max_iter=2,
)
validator = Agent(
role="Người Kiểm Tra QA",
goal="Kiểm tra các bản ghi trích dẫn đã trích xuất xem có đầy đủ trước khi chúng được gửi đi.",
backstory=(
"Từ chối các bản ghi không đầy đủ hoặc bị lỗi và báo cáo "
"chính xác những gì đã kiểm tra."
),
llm=validate_llm,
max_iter=2,
)
Chỉ có fetcher nhận tools=tools.
Extractor và validator phải làm việc từ ngữ cảnh nhiệm vụ. Họ không thể duyệt trang mục tiêu một cách độc lập hoặc thực hiện yêu cầu MCP khác.
Tại Sao Phải Đặt max_iter=2?
max_iter giới hạn số vòng lặp suy nghĩ và hành động mà một đại diện có thể thực hiện trong quá trình một nhiệm vụ.
Giá trị 2 cho phép người lấy trang có đủ không gian để yêu cầu gọi công cụ và sau đó sản xuất một câu trả lời cuối cùng. Nó cũng ngăn một mô hình nhỏ tiếp tục thông qua quá nhiều vòng lặp nội bộ.
Giới hạn này là một cơ chế kiểm soát, không phải là một đảm bảo tính chính xác. Nếu một đại diện sản xuất JSON bị lỗi hoặc chấp nhận các trường trống, việc đạt được giới hạn vòng lặp thành công không làm cho đầu ra đó hợp lệ.
Gắn Công Cụ MCP Chỉ Cho Người Lấy Trang
Vai trò của người lấy trang được xác định rõ ràng:
- Nhận URL mục tiêu.
- Gọi
scrape_markdown. - Trả lại đầu ra của công cụ mà không có bình luận thêm.
Extractor không bao giờ nhận URL trực tiếp dưới dạng hướng dẫn duyệt. Nó đọc nội dung do người lấy trang trả về.
Validator không bao giờ nhận công cụ MCP. Nó chỉ đọc đầu ra của extractor.
Sự phân tách đó làm cho luồng dữ liệu dễ hiểu và kiểm tra hơn.
Kết Nối Ngữ Cảnh Nhiệm Vụ Theo Thứ Tự
Các nhiệm vụ CrewAI có thể tham chiếu đến các nhiệm vụ trước qua tham số context:
python
extract_task = Task(
...,
context=[fetch_task],
)
validate_task = Task(
...,
context=[extract_task],
)
Việc chuyển giao do đó là:
text
fetch_task → extract_task → validate_task
Extractor nhận câu trả lời cuối cùng của nhiệm vụ fetch. Validator nhận câu trả lời cuối cùng của nhiệm vụ trích xuất.
Không cần truyền chuỗi thủ công.
Chạy Đội Với crew.kickoff()
Dưới đây là kịch bản hoàn chỉnh:
python
import os
from crewai import Agent, Crew, LLM, Process, Task
from crewai_tools import MCPServerAdapter
TARGET_URL = "https://quotes.toscrape.com/tag/obvious/"
server_params = {
"url": "https://api.scrapeless.com/mcp",
"transport": "streamable-http",
"headers": {
"x-api-token": os.environ["SCRAPELESS_API_KEY"]
},
}
fetch_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=180,
temperature=0,
)
extract_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=100,
temperature=0,
)
validate_llm = LLM(
model="ollama/qwen2.5:0.5b",
base_url="http://localhost:11434",
max_tokens=70,
temperature=0,
)
with MCPServerAdapter(server_params, "scrape_markdown") as tools:
fetcher = Agent(
role="Người Lấy Trang Web",
goal=(
f"Lấy URL chính xác {TARGET_URL} bằng cách sử dụng "
"công cụ scrape_markdown và trả lại đầu ra thô của nó."
),
backstory=(
"Lấy các trang web công khai cho các đồng đội "
"không thể duyệt web một cách độc lập."
),
tools=tools,
llm=fetch_llm,
max_iter=2,
)
extractor = Agent(
role="Chuyên Gia Trích Dữ Liệu",
goal=(
"Chuyển đổi markdown của trang đã lấy thành một bản ghi có cấu trúc "
"sạch sẽ cho mỗi câu trích dẫn và tác giả của nó."
),
backstory=(
"Đọc markdown thô đã lấy và lấy chính xác các "
"trường mà cơ sở dữ liệu cần."
),
llm=extract_llm,
max_iter=2,
)
validator = Agent(
role="Người Kiểm Tra QA",
goal=(
"Kiểm tra các bản ghi trích dẫn đã trích xuất xem có đủ "
"trước khi chúng được gửi đi."
),
backstory=(
"Từ chối các bản ghi không đầy đủ hoặc bị lỗi và "
"báo cáo chính xác những gì nó đã kiểm tra."
),
llm=validate_llm,
max_iter=2,
)
fetch_task = Task(
description=(
f"Gọi công cụ scrape_markdown với url='{TARGET_URL}'. "
"Trả về đầu ra của công cụ chính xác như câu trả lời cuối cùng của bạn, "
"không có bình luận trước hoặc sau nó."
),
expected_output=(
"Markdown thô được trả về bởi công cụ scrape_markdown."
),
agent=fetcher,
)
extract_task = Task(
description=(
"Bạn được cung cấp markdown thô của một trang trích dẫn như "
"bối cảnh. Tìm mọi trích dẫn trên trang. Đối với mỗi trích dẫn, "
'xuất một đối tượng JSON với các khóa "text" (trích dẫn) '
'và "author" (người được nêu tên sau "bởi"). Trả về '
"CHỈ một mảng JSON của những đối tượng này, không gì khác."
),
expected_output=(
'Một mảng JSON như [{"text": "...", "author": "..."}] '
"với một mục cho mỗi trích dẫn được tìm thấy."
),
agent=extractor,
context=[fetch_task],
)
validate_task = Task(
description=(
"Bạn được cung cấp một mảng JSON của các bản ghi trích dẫn như bối cảnh. "
"Kiểm tra rằng mảng có ít nhất một mục và rằng "
"mỗi mục có trường text và author không rỗng. "
"Báo cáo tổng số bản ghi, danh sách tác giả, và "
"một tuyên bố về sự đầy đủ."
),
expected_output=(
"Một báo cáo ngắn: số lượng bản ghi, danh sách tác giả, "
"tuyên bố về sự đầy đủ."
),
agent=validator,
context=[extract_task],
)
crew = Crew(
agents=[fetcher, extractor, validator],
tasks=[fetch_task, extract_task, validate_task],
process=Process.sequential,
)
result = crew.kickoff()
print(result)
Kịch bản gọi `crew.kickoff()` trong ngữ cảnh bộ chuyển đổi MCP. Điều này giữ cho kết nối công cụ từ xa có sẵn trong khi bộ lấy dữ liệu thực hiện nhiệm vụ của nó.
Sau khi tất cả ba nhiệm vụ hoàn thành, kịch bản in ra `CrewOutput` cuối cùng.
## Những gì bạn nhận được
Chạy xác minh đã tạo ra bằng chứng ở ba lớp khác nhau:
| Lớp | Bằng chứng đã thu thập | Kết luận hỗ trợ |
|---|---|---|
| Kết nối MCP | `['scrape_markdown']` | CrewAI đã phát hiện công cụ MCP được yêu cầu |
| Thực thi Crew | `crew.kickoff()` đã trả về mà không gặp lỗi | Luồng tuần tự đã đạt đến nhiệm vụ cuối cùng |
| Chất lượng dữ liệu | Câu trả lời cuối cùng tự mâu thuẫn | Bản ghi kết quả phải bị từ chối |
Đầu ra cuối cùng của trình xác minh là:
```text
0 ["", "", ""] Hoàn thành. Mảng JSON chứa một mục và tất cả các trường đều không rỗng. Do đó, nó đáp ứng tiêu chí về sự đầy đủ.
Đầu ra này không nhất quán về mặt nội bộ.
Nó báo cáo:
- Số lượng là
0 - Ba chuỗi rỗng
- Một mục được cho là hoàn thành
- Một tuyên bố rằng tất cả các trường đều không rỗng
Những tuyên bố đó không thể đều đúng cùng một lúc.
Quá trình đã hoàn thành, nhưng dữ liệu không vượt qua bài kiểm tra chất lượng có ý nghĩa.
Tại sao đầu ra cuối cùng không vượt qua xác minh
Những gì giao dịch MCP chứng minh
Giao dịch MCP đã trả về:
text
['scrape_markdown']
Điều này chứng minh rằng CrewAI đã kết nối với Máy chủ MCP Scrapeless và phát hiện công cụ được yêu cầu.
Do đó, Bộ lấy trang Web đã có một công cụ từ xa thực sự có sẵn trong quá trình thực hiện.
Những gì crew.kickoff() chứng minh
crew.kickoff() đã trả về một CrewOutput mà không gây ra ngoại lệ.
Điều này chứng minh rằng:
- Nhóm đã được cấu hình thành công.
- Ba nhiệm vụ đã được chấp nhận.
- Sự điều phối tuần tự đã đạt đến nhiệm vụ xác minh.
- CrewAI đã trả về kết quả cuối cùng.
Nó không chứng minh rằng nội dung được lấy đã sống sót qua mọi chuyển giao mô hình một cách chính xác.
Những gì câu trả lời cuối cùng không chứng minh
Trang mục tiêu chứa một trích dẫn dưới thẻ rõ ràng:
text
“Một ngày không có ánh nắng giống như, bạn biết đấy, ban đêm.”
— Steve Martin
Câu trả lời cuối cùng thu được không bảo tồn những giá trị đó.
Bởi vì kịch bản chỉ in ra đầu ra cuối cùng của nhóm, nên không thể gán sự thất bại cho một giai đoạn cụ thể nào. Các giá trị rỗng có thể đã xuất hiện khi:
- Bộ lấy dữ liệu đã tóm tắt hoặc thay đổi phản hồi MCP.
- Bộ trích xuất đã chuyển đổi Markdown thành JSON.
- Bộ xác minh đã diễn giải đầu ra của bộ trích xuất.
- Hơn một giai đoạn đã suy giảm dữ liệu.
Bằng chứng có sẵn chỉ hỗ trợ một kết luận hẹp hơn: nhóm đã đạt đến nhiệm vụ cuối cùng của mình, nhưng bộ xác minh đã chấp nhận một kết quả mà tự mâu thuẫn.
Các mô hình nhỏ cục bộ trong các nhóm gọi công cụ: Kết quả trung thực
Mô hình đã thử nghiệm chứa khoảng 494 triệu tham số. Nó đủ nhỏ để chạy cục bộ và đã mang quy trình CrewAI đến hoàn thành.
Cuộc chạy hoàn chỉnh đã thoát với mã 0 sau 542 giây trên máy chủ được thử nghiệm.
Thời gian đó không phải là một tiêu chuẩn chung của CrewAI hoặc Ollama. Nó phản ánh một máy, một mô hình, một trang, các lời nhắc đã chọn và số lượt của các đại lý trong quy trình công việc cụ thể này.
Kết quả tích hợp vẫn hữu ích:
- CrewAI đã tạo ra ba tác nhân.
- Trình lấy dữ liệu đã nhận được một công cụ MCP Scrapeless trực tiếp.
- Ngữ cảnh nhiệm vụ đã kết nối ba giai đoạn.
crew.kickoff()đã hoàn thành.- Không có khóa LLM đám mây nào được sử dụng.
Tuy nhiên, quá trình chạy không hỗ trợ việc tin tưởng vào các trường kết quả. Đầu ra cuối cùng kết hợp một giá trị bằng không, các giá trị trống, và một tuyên bố thành công.
Một mô hình dưới 1B có thể hữu ích cho việc thử nghiệm điều phối, nhưng lần chạy này cho thấy tại sao nó không nên tự động được coi là một bộ trích xuất dữ liệu có cấu trúc đáng tin cậy.
Thêm Kiểm Tra Quyết Định Sau Crew
Kiểm tra bằng ngôn ngữ tự nhiên vẫn là đầu ra của mô hình. Một tác nhân xác thực có thể hiểu sai dữ liệu bị sai cấu trúc, bỏ qua các giá trị trống, hoặc tạo ra một kết luận mâu thuẫn với báo cáo của chính nó.
Do đó, việc xác thực sản xuất nên diễn ra trong mã thông thường sau quy trình làm việc của mô hình.
Phân Tích Đầu Ra Của Trình Trích Xuất
Sử dụng json.loads để phân tích phản hồi của trình trích xuất.
Từ chối kết quả nếu:
- Nó không phải là JSON hợp lệ.
- Giá trị cấp cao nhất không phải là mảng.
- Phản hồi bao gồm văn bản xung quanh JSON.
- Mảng bất ngờ trống rỗng.
Xác Thực Các Trường Cần Thiết
Đối với mỗi bản ghi, xác minh rằng:
texttồn tại.authortồn tại.- Cả hai giá trị đều là chuỗi.
- Cả hai giá trị vẫn không trống sau khi loại bỏ khoảng trắng.
- Không giá trị nào là một chỗ giữ chỗ rõ ràng.
Đừng để một tuyên bố bằng ngôn ngữ tự nhiên như "tất cả các trường đều đầy đủ" vượt qua một cuộc kiểm tra lập trình thất bại.
Từ Chối Các Đếm Mâu Thuẫn
Nếu xác thực báo cáo một số lượng, so sánh nó với độ dài của mảng JSON thực tế.
Một báo cáo tuyên bố có một mục hoàn chỉnh trong khi đồng thời báo cáo số lượng bằng không nên bị từ chối ngay lập tức.
So Sánh Các Giá Trị Trích Xuất Với Nguồn
Giữ nguyên Markdown gốc được trả về bởi scrape_markdown.
Đối với các trường được sao chép như trích dẫn và tên tác giả, xác nhận rằng các giá trị trích xuất xuất hiện trong phản hồi nguồn. Điều này giúp phát hiện nội dung ảo tưởng, bị cắt ngắn hoặc thay thế.
Bảo Tồn Đầu Ra Nhiệm Vụ Giữa
Ví dụ chỉ in ra đầu ra cuối cùng của nhóm. Để gỡ lỗi và giám sát sản xuất, bảo tồn đầu ra từ mỗi nhiệm vụ.
Điều đó cung cấp cho bạn ba tài sản riêng biệt:
- Markdown được lấy thô
- JSON đã được trích xuất
- Báo cáo xác thực
Với những đầu ra đó có sẵn, bạn có thể xác định giai đoạn chính xác mà dữ liệu bị mất thay vì suy luận từ câu trả lời cuối cùng.
Tăng Công Suất Mô Hình Khi Cần Thiết
Xác thực mạnh mẽ hơn có thể từ chối các kết quả xấu, nhưng nó không thể khôi phục văn bản nguồn mà một mô hình không thể bảo tồn.
Nếu một mô hình nhỏ nhiều lần mất dữ liệu trong quá trình trích xuất hoặc xác thực, hãy sử dụng một mô hình địa phương lớn hơn hoặc một mô hình lưu trữ mạnh mẽ hơn. Đừng làm yếu đi các kiểm tra chỉ để làm cho quy trình hoạt động có vẻ thành công.
Kết Luận
Một nhóm CrewAI chạy trên mô hình Ollama cục bộ có thể kết nối với Máy Chủ Scrapeless MCP, gọi một công cụ quét trực tiếp, truyền dữ liệu qua ba tác nhân, và hoàn thành crew.kickoff() mà không cần khóa LLM đám mây.
Đó là kết quả tích hợp.
Đầu ra cuối cùng bị ghi nhận vẫn sai đủ để bị từ chối: nó báo cáo một số lượng bằng không và các giá trị trống trong khi đồng thời tuyên bố rằng dữ liệu đã hoàn tất.
Hãy coi việc hoàn thành quy trình làm việc và tính chính xác của dữ liệu là hai điều kiện riêng biệt. Bảo tồn các đầu ra trung gian, xác thực các bản ghi có cấu trúc trong Python, so sánh các giá trị trích xuất với phản hồi của MCP, và từ chối quy trình bất cứ khi nào những kiểm tra đó mâu thuẫn với kết luận của mô hình.
Sẵn Sàng Để Xây Dựng Một Nhóm Gọi Công Cụ?
Đăng ký tài khoản Scrapeless miễn phí để nhận khóa API của bạn và kết nối CrewAI với một công cụ dữ liệu web trực tiếp.
Khi bạn hiểu số lượng trang và cuộc gọi tác nhân mà quy trình làm việc của bạn yêu cầu, hãy xem xét các gói giá Scrapeless.
Đối với các câu hỏi về triển khai và hỗ trợ cộng đồng:
Câu Hỏi Thường Gặp
Q: Nhóm CrewAI có cần một khóa LLM đám mây để chạy không?
Không. Thiết lập model="ollama/qwen2.5:0.5b" và base_url="http://localhost:11434" chỉ định mỗi tác nhân đến máy chủ Ollama cục bộ. Nhóm không cần khóa LLM OpenAI, Anthropic hoặc kho lưu trữ khác.
Quy trình này vẫn cần một khóa API Scrapeless vì trình lấy dữ liệu gọi đến Máy Chủ Scrapeless MCP từ xa.
Q: CrewAI chuyển đầu ra từ một tác nhân sang tác nhân tiếp theo như thế nào?
Mỗi Task hạ nguồn nhận được một danh sách context chứa một nhiệm vụ trước đó.
Ví dụ:
python
extract_task = Task(
...,
context=[fetch_task],
)
CrewAI bao gồm câu trả lời cuối cùng của nhiệm vụ lấy dữ liệu trong ngữ cảnh của trình trích xuất. Cơ chế tương tự truyền kết quả trích xuất cho tác nhân xác thực.
Q: Tại sao chỉ có trình lấy dữ liệu nhận công cụ MCP?
Trình tải là tác nhân duy nhất chịu trách nhiệm lấy nội dung trang trực tiếp. Bộ trích xuất và bộ xác thực nên hoạt động dựa trên đầu ra tác vụ đã có.
Giới hạn quyền truy cập vào công cụ giảm bớt sự lựa chọn không cần thiết và làm cho quy trình làm việc dễ kiểm toán hơn.
Q: max_iter=2 điều khiển cái gì?
max_iter giới hạn số chu trình suy luận và hành động mà một tác nhân có thể thực hiện trong một tác vụ.
Giá trị 2 cho phép trình tải có không gian cho một cuộc gọi công cụ và một phản hồi cuối cùng trong khi ngăn chặn vòng lặp vô hạn. Nó giới hạn việc thực thi, nhưng không đảm bảo rằng câu trả lời cuối cùng của tác nhân là đúng.
Q: Mô hình địa phương nhỏ có trích xuất đúng trích dẫn không?
Không. Nhóm đã hoàn thành, nhưng đầu ra của bộ xác thực cuối cùng bắt đầu bằng:
text
0 ["", "", ""]
Sau đó nó tuyên bố rằng có một mục hoàn chỉnh tồn tại và tất cả các trường đều không rỗng. Bởi vì những tuyên bố đó mâu thuẫn với nhau, kết quả cần phải bị từ chối.
Q: Tại sao phải sử dụng xác thực xác định nếu nhóm đã có một tác nhân QA?
Một tác nhân QA vẫn là một LLM. Nó có thể bỏ qua các trường thiếu hoặc tạo ra một kết luận mâu thuẫn với dữ liệu mà nó được yêu cầu kiểm tra.
Các kiểm tra Python xác định cung cấp quyết định pass/fail độc lập dựa trên cú pháp JSON, chiều dài mảng, các trường bắt buộc và sự khớp nguồn.
Q: Chạy Ollama địa phương chậm như thế nào?
Chạy kiểm tra hoàn chỉnh mất 542 giây trên máy chủ được kiểm tra. Đo lường đó chỉ áp dụng cho phần cứng, mô hình, trang, lời nhắc và cấu hình tác nhân cụ thể được sử dụng trong bài kiểm tra.
Việc suy diễn CPU địa phương có thể mất vài phút khi có nhiều lượt tác nhân liên quan.
Q: Những gì cần được ghi lại trong một nhóm sản xuất?
Giữ lại ít nhất:
- Phản hồi của công cụ MCP
- Mỗi đầu ra tác vụ trung gian
- Dữ liệu đã được phân tích cấu trúc
- Lỗi xác thực xác định
- Kết quả cuối cùng của nhóm
- Thời gian thực thi cho từng giai đoạn
Điều này giúp xác định giai đoạn đã thay đổi hoặc bỏ qua dữ liệu nguồn.
Q: Tôi nên kiểm tra gì trước khi lấy dữ liệu từ một trang web thực?
Xem lại điều khoản của trang web và chỉ dẫn /robots.txt, theo Giao thức loại trừ Robots.
Giữ danh sách mục tiêu trong giới hạn, sử dụng các trang công cộng và tránh đưa ra chỉ dẫn thu thập tự động không có giới hạn.
Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.



