Không cần KYC — không ID, không ảnh selfie, không giấy tờ. Thanh toán bằng crypto: BTC, USDT, USDC, ETH, SOL, LTC
Ngôn ngữ: Tiếng Việt
Lấy khóa API

Docs · LangChain · LlamaIndex

Web search trong LangChain và LlamaIndex: một tool và một retriever

Hai dạng bao quát hầu hết framework. Một tool cho phép agent tự quyết định khi nào cần search. Một retriever gắn web trực tiếp vào chuỗi retrieval, trong đó mỗi trang được đọc trở thành một document với URL trong metadata.

Cập nhật lần cuối: · 6 phút đọc

Trả lời nhanh

Làm thế nào để thêm web search trực tiếp vào LangChain hoặc LlamaIndex?

Bọc lời gọi /search của LLMWebSearch trong một @tool của LangChain, một retriever của LangChain hoặc một FunctionTool của LlamaIndex. Mỗi cái trả về các nguồn đã xếp hạng với 3 trang đầu dưới dạng Markdown kèm URL, sẵn sàng để trích dẫn. Không cần cài package nào của chúng tôi: đoạn code bên dưới chính là phần tích hợp. Mỗi lần search tốn 1 credit, từ 1,20 US$/1K lượt tìm kiếm tính đến tháng 10 năm 2026. Không cần KYC; thanh toán bằng crypto.

Mỗi wrapper dùng để làm gì

Tool LangChainAgent gọi search_web khi nó quyết định cần web
Retriever LangChainChuỗi lấy document mới cho mỗi câu hỏi, không cần hỏi
FunctionTool LlamaIndexCùng hàm search_web đó, cho agent LlamaIndex
Packagelangchain-core hoặc llama-index-core, cộng với requests
KeyLLMWEBSEARCH_API_KEY trong biến môi trường
Thanh toánMột credit trả cho một lượt tìm kiếm: tối đa 20 kết quả được xếp hạng, với nội dung của 3 trang đầu được đọc và trả về dưới dạng Markdown. Đọc từ 4 đến 10 trang thì tính 2 credit. Lượt gọi kết thúc bằng lỗi không tốn gì

Làm thế nào để xây dựng một tool search cho agent LangChain?

Trang trí một hàm bằng @tool từ langchain_core.tools. LangChain đọc tên, các tham số có kiểu và docstring để mô tả tool cho model, nên hãy giữ docstring ngắn gọn và chính xác. Hàm trả về một chuỗi với các nguồn được đánh số, phù hợp với mọi chat model và giữ URL ngay cạnh văn bản.

Gọi trực tiếp với .invoke() để kiểm thử, sau đó truyền nó vào danh sách tools của agent.

Tool LangChain: search_web
import os

import requests
from langchain_core.tools import tool

API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}


@tool
def search_web(query: str, read: int = 3) -> str:
    """Search the live web. Returns numbered sources with URLs; the first `read` include page text."""
    body = {"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000}
    resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


print(search_web.invoke({"query": "postgres connection pool size"})[:500])

Làm thế nào để dùng web trực tiếp làm retriever?

Kế thừa BaseRetriever và trả về một Document cho mỗi trang được đọc. Văn bản của trang nằm trong page_content; URL, tiêu đề, thứ hạng và ngày nằm trong metadata, nơi các chuỗi có trích dẫn nguồn tìm đến. Kết quả không có nội dung bị bỏ qua, vì retriever nên đưa ra văn bản mà model có thể trích dẫn.

Retriever chạy ở mọi câu hỏi. Điều đó đúng cho chuỗi hỏi-đáp về chủ đề thời sự, và lãng phí cho một cuộc trò chuyện mà phần lớn lượt không cần search; trong trường hợp đó hãy dùng tool.

Retriever LangChain: LLMWebSearchRetriever
import os
from typing import List

import requests
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever


class LLMWebSearchRetriever(BaseRetriever):
    """Live web search results as Documents, one per page that was read."""

    max_results: int = 5
    read: int = 3
    max_chars: int = 6000

    def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
        resp = requests.post(
            "https://llmwebsearch.com/api/v1/search",
            headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
            json={"q": query, "max_results": self.max_results, "read": self.read, "max_chars": self.max_chars},
            timeout=60,
        )
        resp.raise_for_status()
        docs = []
        for r in resp.json()["results"]:
            if r["content_status"] != "ok":
                continue
            meta = {"source": r["url"], "title": r["title"], "position": r["position"], "published_at": r.get("published_at")}
            docs.append(Document(page_content=r["content"], metadata=meta))
        return docs


retriever = LLMWebSearchRetriever(read=3)
for doc in retriever.invoke("pgbouncer transaction mode limitations"):
    print(doc.metadata["position"], doc.metadata["source"], len(doc.page_content))

Làm thế nào để cung cấp cùng chức năng search cho agent LlamaIndex?

Viết một hàm thường và bọc nó bằng FunctionTool.from_defaults từ llama_index.core.tools. LlamaIndex xây dựng tên và mô tả của tool từ tên hàm, signature và docstring. Gọi tool trả về một ToolOutput mà content của nó là văn bản agent sẽ đọc.

Hàm này giống với hàm dùng cho LangChain, nên một đội dùng cả hai framework có thể chia sẻ nó.

LlamaIndex: FunctionTool
import os

import requests
from llama_index.core.tools import FunctionTool


def search_web(query: str, read: int = 3) -> str:
    """Search the live web and return numbered sources; the first `read` include their page text."""
    resp = requests.post(
        "https://llmwebsearch.com/api/v1/search",
        headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
        json={"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000},
        timeout=60,
    )
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


search_tool = FunctionTool.from_defaults(fn=search_web)
print(search_tool.metadata.name)
print(search_tool.call(query="postgres connection pool size").content[:300])

Làm sao để giữ cửa sổ ngữ cảnh trong tầm kiểm soát?

Đặt max_chars ngay trong lệnh gọi API thay vì cắt bớt sau đó: ít dữ liệu truyền đi hơn và framework không bao giờ phải giữ phiên bản dài. 5.000 ký tự mỗi trang và 3 trang là khoảng 4.000 token, thoải mái cho hầu hết model.

Với các retrieval chain kết hợp web trực tiếp với tài liệu của riêng bạn, hãy gán trọng số thấp hơn cho tài liệu web hoặc tách thành một mục prompt riêng. Trang web thay đổi và có thể sai; tài liệu của bạn thường là nguồn tham chiếu.

Tôi có thể lưu những gì retriever trả về vào vector database không?

Có, theo quan điểm của chúng tôi. Chúng tôi không huấn luyện bất kỳ model nào trên truy vấn của bạn hay trên những gì API trả về, và chúng tôi không thêm quy tắc riêng nào chống lại việc lưu trữ kết quả; quyền của các trang có nội dung bạn đọc vẫn áp dụng. Lưu URL và published_at cùng mỗi chunk, để agent có thể trích dẫn trang và bạn có thể loại bỏ các chunk cũ dần.

Hầu hết các nhóm lưu cache kết quả web của những câu hỏi thường gặp trong một ngày hoặc một tuần. Việc đó giảm các tìm kiếm lặp lại, và mỗi tìm kiếm tránh được là một credit tiết kiệm.

LangChain và LlamaIndex: các câu hỏi thường gặp

Có package langchain-llmwebsearch không?

Không. Chúng tôi không phát hành package nào. Đoạn code trên trang này đủ ngắn để tự sở hữu: sao chép, thay đổi các giá trị mặc định và giữ nó trong repository của bạn.

Tôi có thể làm cho tool chạy async không?

Có. Thay requests bằng httpx.AsyncClient và định nghĩa hàm với async def. @tool của LangChain trang trí trực tiếp các hàm async; trong LlamaIndex, truyền phiên bản async vào FunctionTool.from_defaults dưới dạng async_fn.

Làm sao để đọc một trang mà agent tìm thấy ở nơi khác?

Thêm một tool thứ hai để gửi URL tới https://llmwebsearch.com/api/v1/extract. Đọc các trang mà bạn đã có URL tốn 1 credit cho mỗi nhóm 3 trang bắt đầu được trả về kèm nội dung, tối đa 20 URL mỗi lượt gọi; các URL bị từ chối hoặc thất bại không được tính. Tài liệu tham chiếu extract cho thấy request.

Từ 1,20 US$/1K lượt tìm kiếm · không cần KYC

Lấy khóa API