LangChain
Add live web search to a LangChain agent, and cut the documents your chain loads down to the parts that answer the question.
On this page
A retrieval chain sends every document it loads to your model. Most of that text does not help answer the question, and you pay for every token of it.
Lineage reads each document first and keeps only the passages that answer the question. The people, organisations and dates in them stay attached, so your model can still tell who did what and when.
Set up
pip install langchain langchain-openai langchain-community requests beautifulsoup4export FLUX_API_KEY="<your key>"export OPENAI_API_KEY="<your key>"Search
Give your agent web search
Wrap the Flux search endpoint as a tool. Your model calls it when it needs something current.
import osimport requestsFLUX = "https://fluxsearch.io/api/v1"HEADERS = {"Authorization": f"Bearer {os.environ['FLUX_API_KEY']}"}from langchain.agents import create_agentfrom langchain_core.tools import tool@tooldef web_search(query: str) -> str: """Search the live web. Returns passages with provenance and their source URLs.""" response = requests.post( f"{FLUX}/search", headers=HEADERS, json={"query": query, "max_results": 5, "enrich": 3}, timeout=120, ) response.raise_for_status() passages = [ f"{passage['enriched_text']} ({result['url']})" for result in response.json()["results"] for passage in (result["lineage"] or {}).get("results", []) ] return "\n\n".join(passages) or "No passages found."agent = create_agent("openai:gpt-5-mini", tools=[web_search])question = "What is the latest milestone for commercial fusion power?"result = agent.invoke({"messages": [{"role": "user", "content": question}]})print(result["messages"][-1].content)Short answer: The latest widely reported milestone is Helion Energy’s Feb. 13, 2026 announcement that its Polaris prototype produced measurable deuterium-tritium (D-T) fusion and reached plasma tempe…Context and why it matters- Helion’s results are important because D-T fuel and very high plasma temperatures are central steps toward a commercially viable fusion plant (tritium handling, scaling across fuels, and higher tem…- Separately, the U.S. National Ignition Facility (LLNL/NIF) has repeatedly demonstrated ignition and multi‑megajoule yields (target gains >1) in recent years (2022-2025). Those are major physics mil…What still remains for “commercial fusion power”- Sustained, net electrical output to the grid from a reactor (plant-level Qnet > 1 with useful electricity delivered)- Demonstrated tritium breeding and closed fuel cycle for continuous operation- Engineering solutions for continuous, reliable industrial operation and competitive economicsSources (for the announcements above)…Call Flux as a chat model
For sourced passages on one question with no agent, point ChatOpenAI at Flux.
import osfrom langchain_openai import ChatOpenAIflux = ChatOpenAI( model="flux-search-1", base_url="https://fluxsearch.io/api/v1", api_key=os.environ["FLUX_API_KEY"],)print(flux.invoke("When is the next total solar eclipse visible from Europe?").content)ESA / Science & Exploration / Space ScienceEurope has no less than three solar eclipses between 2026 and 2028: [when: Sep 14, 2026]12 August 2026 - total solar eclipse in Greenland, Iceland, Spain & Portugal. [when: Aug 12, 2026]2 August 2027 - total solar eclipse in Spain. [when: Aug 2027]26 January 2028 - annular solar eclipse in Portugal & Spain. [when: Jan 26, 2028]Each event offers unique viewing opportunities across the continent, from totality over Spain to an annular “ring of fire” visible from Portugal and beyond.Total Solar Eclipse on 12th August 2026This…Much of Europe will see a partial eclipse.The European Space Agency (ESA) highlights Spain as one of the prime viewing locations, with the path of totality crossing the country in the evening.You can……Lineage
Trim a document before it reaches the model
Load a page as usual, then run it through FluxLineage. Only the passages that answer the question come back.
import osimport requestsFLUX = "https://fluxsearch.io/api/v1"HEADERS = {"Authorization": f"Bearer {os.environ['FLUX_API_KEY']}"}from langchain_community.document_loaders import WebBaseLoaderfrom langchain_core.documents import Documentfrom langchain_core.documents.compressor import BaseDocumentCompressorclass FluxLineage(BaseDocumentCompressor): def compress_documents(self, documents, query, callbacks=None): kept = [] for doc in documents: response = requests.post( f"{FLUX}/lineage", headers=HEADERS, json={"text": doc.page_content, "query": query}, timeout=120, ) response.raise_for_status() for passage in response.json()["results"]: metadata = {**doc.metadata, "score": passage["score"]} kept.append(Document(page_content=passage["enriched_text"], metadata=metadata)) return keptdocs = WebBaseLoader("https://docs.python.org/3/tutorial/venv.html").load()kept = FluxLineage().compress_documents(docs, "How do I create a virtual environment?")before = sum(len(doc.page_content) for doc in docs)after = sum(len(doc.page_content) for doc in kept)print(f"{before:,} characters loaded, {after:,} kept")for doc in kept: print(doc.page_content)8,854 characters loaded, 1,149 keptThe solution for this problem is to create a virtual environment, aself-contained directory tree that contains a Python installation for aparticular version of Python, plus a number of additional packages.The module used to create and manage virtual environments is calledTo create a virtual environment, decide upon a directory where you want toplace it, and run the venv module as a script with the directory path:python -m venv tutorial-envThis will create the tutorial-env directory if it doesn’t exist,and also create directories inside it containing a copy of the Python…