Questions
8 of 24
1What is a Tool in LangChain and how does it differ from a plain function or API call?
2What is the difference between the tool() helper, DynamicTool, and StructuredTool class?
3How does an LLM decide which tool to call — what role does the tool description play?
4What is the role of Zod schema in tool definitions and how does it map to OpenAI's function calling spec?
5What is a ToolNode in LangGraph and how does it differ from calling a tool manually inside a graph node?
6How do you wrap a REST API call with auth headers inside a Tool in TypeScript?
7How do you handle async errors and retries inside a Tool without crashing the agent loop?
8How do you pass runtime context (userId, authToken, DB connection) into a Tool using RunnableConfig?
9How do you build a Toolkit (grouped set of related tools) using BaseToolkit?
10How do you validate and sanitize tool output before it is passed back to the LLM?
11How do you stream tool call results back to the client in real time?
12How do you implement tool-level authorization — allowing certain tools only for certain users?
13How do you build stateful tools that read/write to a database across multiple agent turns?
14How do you prevent tool abuse or infinite loops where an agent keeps calling the same tool repeatedly?
15How do you implement parallel tool calling — when the LLM decides to call multiple tools simultaneously?
16How do you create a human-in-the-loop tool that pauses the agent and waits for user approval before executing?
17How do you unit test and mock tools in isolation without invoking the LLM?
18How do you implement tool call caching to avoid redundant API calls for identical inputs?
19How do you design a multi-agent system where one agent's tool is actually another agent (agent-as-tool pattern)?
20How does LangGraph's ToolNode handle tool call errors and surface them back into the message state?
21What is the difference between tool_choice: "auto", "required", and "none" when binding tools to an LLM?
22How do you implement dynamic tool loading — where the set of available tools changes based on user role or session state?
23How do you trace and observe tool call latency in production using LangSmith?
24What are the token cost implications of registering too many tools and how do you mitigate it?
08 / 24

How do you pass runtime context (userId, authToken, DB connection) into a Tool using RunnableConfig?

You pass runtime context into a Tool by leveraging the context parameter in RunnableConfig, which propagates through the entire call chain, allowing tools to access values like userId, authToken, or tenantId without coupling them to the tool's input schema.

LangChain's RunnableConfig provides a clean, dependency-injection style way to pass contextual information through your agent's execution chain. By configuring a contextSchema on your agent, you define the shape of the runtime data you expect. This context is then automatically made available in the second argument of any tool's function, allowing the tool to access user-specific information like userId, authentication tokens, or database connections without the LLM needing to know about them or the user having to provide them. This keeps your tool's input schema focused on what the LLM should generate (e.g., query or productId), while sensitive or operational context is injected separately.

1. Define the Context Schema
  1. 1

    Define a Zod object that specifies the shape and types of the context your tools will need. This can include userId, authToken, tenantId, or even a database connection pool. This schema ensures type safety throughout your application.

Defining the Context Schema
2. Create a Tool That Accesses the Context
  1. 1

    When defining your tool, the async function receives config as its second parameter. The config.configurable object contains the merged context. You can then use the userId, authToken, or any other context value inside your tool's logic.

Tool Implementation with Context Access
3. Pass Context When Invoking the Agent
  1. 1

    When you invoke your agent, you pass the runtime context as a property of the configurable object. This context is then propagated down to the tools.

Invoking the Agent with Context

For more complex scenarios where you need to pass a database connection pool or other non-serializable resources, you should instantiate these as singletons or request-scoped objects and store them directly in the configurable object. If you're using the createAgent factory, you can enforce the context schema by passing it to the contextSchema parameter. This ensures that all tools receive the correctly typed context and will cause a type error if you forget to provide required fields.

Enforcing Context Schema with createAgent

A significant benefit of this pattern is testability. You can easily unit-test your tools by passing a mock context directly to their invoke method, without needing to spin up a full agent or mock network requests if you design your tool to use dependency injection.

Unit Testing a Tool with Mock Context

This pattern is a clean application of dependency injection for LangChain tools. It separates the concerns of what the LLM decides (the input arguments) from what the application provides (the runtime context). This makes your tools more reusable, testable, and secure, as sensitive information like auth tokens never need to be generated by the LLM or passed through the prompt.