![]() |
Image by Imagen 4 |
Content and Context are the King and Queen of LLM applications. While LLM models, themselves, can “understand” what people are asking, it is only by providing additional content and context that we can build systems that avoid problems, such as hallucinations, and provide accurate and useful responses. Strategies such as Retrieval Augmented Generation (RAG) and using tools to include additional content are common ways of addressing this issue.
Google provides several specific tools that can provide relevant content directly through the Gemini API calls. This includes the Grounding with Google Search tool, which has extensive support in LangChainJS.
Google has now built on this by providing a URL Context tool which allows you to develop prompts that access specific information from and about publicly available web pages. Why is this important?
Can you see the problem?
As you may remember, Gemini can be accessed on two different platforms, AI Studio and Vertex AI, with several different auth methods involved. If you’re not familiar with developing for Gemini with LangChainJS, you should check out LangChain.js and Gemini: Getting Started.
For simplicity, we’ll be using the ChatGoogle
class from the google-gauth
package, but you can use one that meets your need.
There are some cases where we might ask an LLM specific questions about a web page, or ask for a summary, or to compare two different web pages. So we might address this with something like this code:
const url = "https://js.langchain.com/";
const question = `Describe the contents of this web page: ${url}`;
const modelName = "gemini-2.0-flash-001";
const model = new ChatGoogle({
modelName,
temperature: 0,
});
const result = await model.invoke(question);
console.log(result.content);
The exact answer we get, of course, will vary from run to run, but here is an example of a pretty typical result:
I have analyzed the content of the webpage you provided: https://js.langchain.com/. Here's a breakdown of what it contains:
**Overall Purpose:**
The webpage serves as the **official documentation and entry point for Langchain.js**, the JavaScript/TypeScript version of the popular LangChain framework. LangChain is a framework designed to simplify the development of applications powered by large language models (LLMs).
**Key Content Areas:**
* **Introduction and Overview:**
* Explains what LangChain is and its purpose: building applications with LLMs.
* Highlights the core components and capabilities of LangChain.js.
* Provides a high-level overview of the framework's architecture.
* **Getting Started:**
* Guides users through the initial setup and installation process.
* Includes instructions on installing the necessary packages (likely via npm or yarn).
* Provides basic code examples to demonstrate how to use LangChain.js for simple tasks.
* **Modules/Components:**
* **Models:** Documentation on different LLMs that can be used with LangChain.js (e.g., OpenAI, Cohere, Hugging Face). Includes how to connect to these models and configure them.
* **Prompts:** Explains how to create and manage prompts for LLMs. Covers prompt templates, prompt engineering techniques, and how to optimize prompts for specific tasks.
* **Chains:** Details how to create chains of operations that link together different LLM calls and other components. This is a core concept in LangChain for building more complex workflows.
* **Indexes:** Covers how to index and retrieve data for use with LLMs. This is important for tasks like question answering over documents.
* **Memory:** Explains how to add memory to LLM applications, allowing them to remember previous interactions and maintain context.
* **Agents:** Describes how to create agents that can use LLMs to make decisions and take actions in the real world. This is a more advanced topic that involves planning and tool use.
* **Callbacks:** Explains how to use callbacks to monitor and control the execution of LangChain components.
* **Use Cases:**
* Provides examples of how LangChain.js can be used to build various types of applications, such as:
* Question answering
* Chatbots
* Text summarization
* Code generation
* Data extraction
* **Guides and Tutorials:**
* Offers more in-depth guides and tutorials on specific topics and use cases.
* Provides step-by-step instructions and code examples to help users learn how to use LangChain.js effectively.
* **API Reference:**
* Detailed documentation of all the classes, functions, and methods available in the LangChain.js library.
* Provides information on the parameters, return values, and usage of each API element.
* **Community and Support:**
* Links to the LangChain community forums, Discord server, and other resources for getting help and connecting with other users.
* Information on how to contribute to the LangChain.js project.
* **Blog:**
* Articles and updates on the latest developments in LangChain.js, including new features, bug fixes, and use cases.
**In summary, the Langchain.js website is a comprehensive resource for developers who want to use JavaScript or TypeScript to build applications powered by large language models. It provides everything from basic tutorials to advanced API documentation, making it easy to get started and build sophisticated LLM-powered applications.**
Reading through this, it looks pretty good, right? Did you notice any problems?
Did you notice, perhaps, that it hallucinated nearly all of it?
Finding the solution
While we can address this manually (such as by loading the URL ourselves and including it in the context), Gemini also provides the URL Context Tool that will handle this for us and use Google’s high speed network and cache to provide the context.
We can change the model configuration in LangChainJS to bind to the URL Context Tool with something like this:
const urlContextTool: GeminiTool = {
urlContext: {},
};
const tools = [urlContextTool];
const model = new ChatGoogle({
modelName,
temperature: 0,
}).bindTools(tools);
If we run this, we’ll get a different answer:
The webpage is the documentation site for LangChain, a framework for developing applications powered by large language models (LLMs). It highlights the JavaScript version of LangChain.
Here's a breakdown of the content:
* **Introduction:** LangChain simplifies the LLM application lifecycle, covering development, productionization, and deployment. It mentions LangGraph.js for building stateful agents.
* **Core Components:** It lists the open-source libraries that make up the framework: `@langchain/core`, `@langchain/community`, partner packages (like `@langchain/openai`), `langchain`, and LangGraph.js. It also mentions LangSmith for debugging, testing, and monitoring LLM applications.
* **Tutorials:** Offers tutorials for building various applications like simple LLM apps, chatbots, and agents.
* **How-To Guides:** Provides short answers to common questions and tasks.
* **Conceptual Guide:** Introduces key LangChain concepts.
* **API Reference:** Links to the full documentation of classes and methods.
* **Ecosystem:** Mentions LangSmith and LangGraph.
* **Additional Resources:** Includes information on security, integrations, and contributing.
* **Versions:** Allows you to select documentation for different versions of the library.
* **Migration Guides:** Provides guides for migrating between versions.
On the surface, you might think this is pretty similar to what we saw above.
The biggest difference, however, is that the page contains all of the elements that are addressed in the reply. Clearly, Gemini actually used the page content when computing an answer.
But how do we know that it has actually accessed the page to do so?
The Hidden Links
As part of the response, Gemini will tell us what URLs it tried to read and if there were any problems doing so. LangChainJS stores this as part of the response_metadata
attribute in the result.
We can examine the results with something like this:
const result = await model.invoke(question);
const urlContextMetadata = result?.response_metadata?.url_context_metadata;
console.log( urlContextMetadata );
For our prompt above, we should get something like this. If we had asked about several pages, each would be listed here.
{
urlMetadata: [
{
retrievedUrl: 'https://js.langchain.com/',
urlRetrievalStatus: 'URL_RETRIEVAL_STATUS_SUCCESS'
}
]
}
Conclusion
As we’ve seen, the Gemini URL Context tool provides a powerful and straightforward way to ground LLM responses with the context of specific web pages. By simply binding the tool to our LangChainJS model, we can ensure that Gemini has direct access to the content, hopefully preventing hallucinations and providing more accurate responses.
The ability to verify which URLs were accessed through the response_metadata
gives us an extra layer of confidence that the model is using the information we provided.
You can even combine this with other tools, such as the Grounding with Google Search tool, to further enhance the quality of results. These tools, when combined with our own knowledge and business logic systems, let us move from simply prompting a model to building robust, context-aware AI systems.
Acknowledgements
The development of LangChainJS support for Gemini’s URL Context Tool and this documentation were all supported by Google Cloud Platform Credits provided by Google. My thanks to the teams at Google for their support.
Special thanks to Linda Lawton, Denis V., Steven Gray, and Noble Ackerson for their support and friendship.