Fixing Langchain.js's ToolCallingAgentOutputParser Error with Ollama LLM and a Custom Tool

Temp mail SuperHeros
Fixing Langchain.js's ToolCallingAgentOutputParser Error with Ollama LLM and a Custom Tool
Fixing Langchain.js's ToolCallingAgentOutputParser Error with Ollama LLM and a Custom Tool

Understanding and Fixing ToolCallingAgentOutputParser Errors in Langchain.js

When working with Langchain.js v2, developers often aim to create efficient agents using custom tools and language models like Ollama. However, integrating these components can sometimes lead to errors that are difficult to debug.

One such error is the "parseResult on ToolCallingAgentOutputParser only works on ChatGeneration output," which can occur when building a custom tool within the agent framework. Understanding the root cause of this issue is crucial to ensure the agent and tool work correctly.

This article explores a simple implementation of a custom tool that adds 2 to a number input, using Langchain's createToolCallingAgent and the Ollama model. By analyzing the error and its context, we can better grasp how to troubleshoot it.

The following sections will guide you through the code, explain the error, and provide solutions to address this problem. Whether you're new to Langchain.js or experienced, this guide will help you move past this issue efficiently.

Command Example of Use
tool() This function from Langchain.js defines a custom tool that performs an operation. In this article, it's used to create a tool that adds 2 to an input number, wrapping the logic in an easily callable structure.
z.object() A part of the Zod library, used for schema validation in Langchain. This ensures that the input to the custom tool is a number, providing strong input validation to prevent errors during execution.
createToolCallingAgent() This command creates an agent that can call the defined tools in response to user queries. It's key to integrating tools with language models like Ollama, making it possible to invoke tools during conversation.
ChatPromptTemplate.fromMessages() Used to generate a chat prompt template with placeholders. This template organizes different types of messages (system, human, placeholders) for the agent to use, improving its conversational flow.
MessagesPlaceholder Acts as a placeholder in the prompt template for dynamic content, such as chat history or agent scratchpad. This allows the conversation context to be injected dynamically during execution.
AgentExecutor() This class manages the execution of agents and tools. In the example, it helps in running the query through the agent and collecting the result from the tool's output.
await agentExecutor.invoke() Used to run the query through the agent and wait for the result asynchronously. This is crucial for interacting with language models and tools, as it ensures the code waits for the operation to complete before moving on.
try-catch This error-handling structure is used within the custom tool to catch invalid input types. By catching exceptions, it ensures that the system returns helpful error messages without breaking the execution flow.
expect() From the Chai assertion library, expect() is used in the unit test to verify the output of the custom tool. It's essential for testing whether the tool performs as expected.

Understanding the Custom Tool and Agent Error Handling in Langchain.js

In the example provided, we are working with Langchain.js v2 to create a custom tool that integrates with the Ollama language model. The main purpose of the tool is to perform a simple mathematical operation: adding 2 to the input value. The tool is built using Langchain’s tool function, which defines reusable functions that can be invoked by an agent. To ensure the tool works correctly, the input schema is validated with the Zod library, guaranteeing that the input is a valid number. This ensures proper error handling and prevents the tool from failing due to invalid inputs.

The custom tool is then incorporated into an agent using the createToolCallingAgent function. This command allows the agent to call the tool when needed, and the agent is powered by the Ollama model, which is configured with specific parameters such as temperature to control the creativity of the responses. To facilitate smooth interaction between the agent and the tool, a chat prompt template is used. This template organizes the conversation by defining different types of messages, such as system messages, human input, and placeholders. The placeholders, such as MessagesPlaceholder, allow the conversation to be dynamic, with elements like the chat history being included.

One of the key issues addressed in this example is the error handling around the Langchain agent's output parsing. The error message "parseResult on ToolCallingAgentOutputParser only works on ChatGeneration output" stems from a mismatch between the type of output expected by the parser and the actual output generated. To handle this error, the custom tool is wrapped in robust logic, ensuring that all inputs and outputs conform to expected formats. This is further managed by the AgentExecutor class, which coordinates the execution of the agent and tools, making sure that the query and tool output are properly synchronized.

Finally, the scripts implement asynchronous execution using await, allowing the system to handle operations without blocking other processes. The agent waits for the tool to return its result before proceeding, ensuring that the response is both accurate and timely. Additionally, unit tests are included to validate the tool's functionality, ensuring that it consistently produces the correct output. These tests not only confirm the tool’s mathematical operation but also check how well it handles invalid input, improving the overall reliability of the solution. This modular and error-resistant design makes the scripts reusable and effective for various applications within Langchain.js.

Fixing the Langchain.js Error with Modular Approach

Solution 1: JavaScript with modular approach and error handling using Langchain.js and Ollama LLM

import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { Ollama } from "@langchain/ollama";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { createToolCallingAgent } from "langchain/agents";
import { AgentExecutor } from "langchain/agents";
// Initialize LLM with Ollama
const llm = new Ollama({
    model: "llama3",
    temperature: 0.7,
});
// Custom tool to add 2 to the input number
const magicTool = tool(
    async (input) => {
        return input + 2;
    },
    {
        name: "magic_function",
        description: "Applies a magic function to an input",
        schema: z.object({ input: z.number() }),
    };
);
const tools = [magicTool];
// Setup ChatPromptTemplate with placeholders
const prompt = ChatPromptTemplate.fromMessages([
    ["system", "You are a helpful assistant called iHelp"],
    ["placeholder", "{chat_history}"],
    ["human", "{input}"],
    ["placeholder", "{agent_scratchpad}"],
]);
// Agent configuration
const agent = createToolCallingAgent({ llm, tools, prompt });
// Execute agent query
const agentExecutor = new AgentExecutor({ agent, tools });
const query = "What is the value of magic_function(3)?";
await agentExecutor.invoke({ input: query });

Enhanced Error Handling for Langchain.js Agent

Solution 2: Error handling with unit tests to validate the custom tool's output in Langchain.js

import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { Ollama } from "@langchain/ollama";
import { createToolCallingAgent } from "langchain/agents";
import { AgentExecutor } from "langchain/agents";
// Initialize LLM with Ollama
const llm = new Ollama({ model: "llama3", temperature: 0.7 });
// Custom tool with added error handling
const magicTool = tool(
    async (input) => {
        try {
            if (typeof input !== "number") throw new Error("Invalid input type!");
            return input + 2;
        } catch (err) {
            return err.message;
        }
    },
    {
        name: "magic_function",
        description: "Adds 2 to input and handles errors",
        schema: z.object({ input: z.number() }),
    }
);
const tools = [magicTool];
// Agent and execution
const agent = createToolCallingAgent({ llm, tools });
const agentExecutor = new AgentExecutor({ agent, tools });
const query = "magic_function('abc')"; // Test with invalid input
await agentExecutor.invoke({ input: query });
// Unit test example
import { expect } from "chai";
it("should return 5 when input is 3", async () => {
    const result = await magicTool(3);
    expect(result).to.equal(5);
});

Exploring the Role of Agents in Langchain.js and Ollama LLM Integration

When working with Langchain.js, integrating agents with tools and language models like Ollama is a critical aspect of building dynamic applications. An agent allows you to connect a custom tool, which performs specific tasks, to a language model, which handles more conversational or generative tasks. By using agents, developers can automate workflows where a model not only generates responses but also invokes tools to perform calculations or data processing.

The key component in this integration is the createToolCallingAgent function. This function lets the agent trigger specific tools when necessary, ensuring that tasks are completed accurately and efficiently. While the primary focus is often on creating the tool itself, understanding how to manage the agent's workflow and avoid parsing errors is equally important. Errors like "parseResult on ToolCallingAgentOutputParser only works on ChatGeneration output" usually occur when the agent's output isn't compatible with the parsing system, highlighting the need for proper alignment between the agent’s output and the expected format.

The use of prompt templates, such as ChatPromptTemplate, further enriches the interaction by allowing dynamic messages and context placeholders. This allows the agent to adjust its responses based on the chat history or the agent’s scratchpad. Optimizing the prompt templates and ensuring the agent's outputs are correctly parsed can prevent many common errors, making your Langchain.js applications more reliable and efficient.

Frequently Asked Questions About Langchain.js, Agents, and Tools

  1. What is an agent in Langchain.js?
  2. An agent is a component that interacts with tools and language models to perform specific tasks based on a user query. It uses the createToolCallingAgent function to trigger tools.
  3. How do you resolve the "parseResult on ToolCallingAgentOutputParser" error?
  4. This error occurs when the agent's output is incompatible with the parser. Ensure the output matches what the parser expects and use a ChatGeneration output format.
  5. What is the purpose of the AgentExecutor?
  6. The AgentExecutor manages the execution of the agent and its tools, allowing you to run complex workflows in Langchain.js applications.
  7. How does ChatPromptTemplate work?
  8. ChatPromptTemplate organizes chat messages in a structured format, allowing for dynamic content such as chat history and agent scratchpad to be inserted into the conversation flow.
  9. Why is Zod used in the tool?
  10. Zod is used for input validation, ensuring that the input to the custom tool is of the correct type (e.g., a number), which reduces the chances of errors.

Final Thoughts on Error Handling in Langchain.js

Solving the "parseResult on ToolCallingAgentOutputParser only works on ChatGeneration output" error requires careful alignment between the output of your agent and its parsing expectations. With the right approach, this error can be avoided.

By using appropriate tools like Zod for validation and ensuring that agents, such as those built with Ollama, handle inputs and outputs correctly, you can create robust solutions in Langchain.js without encountering parsing issues.

Sources and References for Langchain.js Error Resolution
  1. Elaborates on the official Langchain documentation, which provides insights into tool creation and agent configurations. Langchain Documentation Inside.
  2. Further explains the use of Zod for input validation and its application in Langchain.js. Zod Documentation Inside.
  3. Describes the Ollama language model and its implementation within custom agents. Ollama LLM Inside.