A LangChain agent with web search can answer with fresher context, but freshness is not enough.
When the answer looks wrong, you need to know what the agent searched, which URLs it used, when the search happened, and which results were passed into the final prompt. Without that trace, debugging becomes guesswork.
This walkthrough shows a small pattern for making a LangChain search step auditable with source URLs and timestamps using TalorData SERP API.
Basic setup
The confirmed LangChain package is langchain-talordata.
pip install langchain-talordata
Set the package environment variable:
export TALOR_API_KEY="<TALORDATA_TOKEN>"
A common starting point:
from langchain_talordata import TalorSerpTool
search_tool = TalorSerpTool.from_env()
The package reads TALOR_API_KEY. The value should be your TalorData token.
What should be logged
A useful search trace should answer five questions:
- What did the user ask?
- What query did the agent search?
- When did the search happen?
- Which URLs were returned?
- Which URLs were selected for the final answer?
That means the log should preserve both the tool call and the selected evidence.
A simple trace shape
Start with a small structure:
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from typing import Any
@dataclass
class SearchTrace:
user_request: str
generated_query: str
searched_at: str
selected_sources: list[dict[str, Any]]
result_count: int
The timestamp should be created when the search result is fetched, not after the final answer is generated.
def utc_now() -> str:
return datetime.now(timezone.utc).isoformat()
Shape the search results
Do not pass the entire SERP response into the final prompt by default. Keep a compact source object.
def compact_source(item: dict) -> dict:
return {
"position": item.get("position"),
"title": item.get("title"),
"url": item.get("link"),
"snippet": item.get("description"),
}
For many agent tasks, the first useful source fields are position, title, URL, and snippet.
Build the search wrapper
Your exact wrapper depends on how your LangChain app calls tools, but the boundary should be clear:
def search_with_trace(user_request: str, generated_query: str) -> tuple[list[dict], dict]:
searched_at = utc_now()
result = search_tool.invoke(generated_query)
organic = result.get("organic", []) if isinstance(result, dict) else []
selected_sources = [compact_source(item) for item in organic[:5]]
trace = SearchTrace(
user_request=user_request,
generated_query=generated_query,
searched_at=searched_at,
selected_sources=selected_sources,
result_count=len(organic),
)
return selected_sources, asdict(trace)
If your tool call returns a different object shape, adapt the extraction layer. The key idea is the same: preserve the generated query, timestamp, and selected URLs.
Use the trace in the final answer
The final prompt should receive only selected sources, not the entire raw response.
Example prompt input:
User request:
{user_request}
Search query:
{generated_query}
Search timestamp:
{searched_at}
Selected sources:
{selected_sources}
Answer the user using the selected sources. If the sources are weak or incomplete, say so.
This gives the model a clearer boundary between evidence and reasoning.
Store the trace
For a prototype, writing JSON lines is enough:
import json
def append_trace(path: str, trace: dict) -> None:
with open(path, "a", encoding="utf-8") as file:
file.write(json.dumps(trace, ensure_ascii=False) + "\n")
In production, this trace may belong in a database, observability system, or internal evaluation table.
What this helps debug
A source trace helps answer:
- Did the agent search the wrong query?
- Did the SERP return weak results?
- Did the source selection remove something important?
- Did the answer rely on inference instead of evidence?
- Was the answer generated from fresh or old search context?
That is much better than trying to inspect a final answer with no search record.
Final thought
Adding web search to an agent is useful. Making the search auditable is what makes it maintainable.
Start by logging the generated query, timestamp, selected URLs, and result count. That small trace will save a lot of debugging time later.
If you want to test this pattern with live Google results, TalorData gives new accounts 500 responses to build and inspect a small source-logging workflow.
Top comments (0)