\n\n\n\n Building Agent Plugins: A Practical Quick Start Guide - AgntKit \n

Building Agent Plugins: A Practical Quick Start Guide

📖 12 min read2,203 wordsUpdated Mar 26, 2026

Introduction: The Power of Agent Plugins

In the rapidly evolving space of artificial intelligence, large language models (LLMs) are becoming increasingly sophisticated. However, even the most advanced LLMs have inherent limitations: they operate on their training data, lack real-time information access, and cannot directly interact with external systems or perform specific actions. This is where agent plugins come into play. Agent plugins enable LLMs to extend their capabilities, acting as bridges to the external world. They allow an AI agent to perform tasks it wasn’t explicitly trained for, access proprietary data, interact with APIs, and execute real-world actions.

Think of an LLM as a brilliant mind with vast knowledge but no hands or eyes beyond its internal data. A plugin gives it those hands and eyes. It transforms a conversational AI into an actionable AI, capable of not just understanding but also doing. In this article, we’ll explore the practical aspects of building agent plugins, focusing on a quick start approach with concrete examples to get you up and running.

Understanding the Core Concept: LLM, Agent, and Plugin

Before we start coding, let’s solidify our understanding of the key components:

  • Large Language Model (LLM): The foundational AI that understands and generates human language. It’s the brain of our agent. Examples: GPT-4, Claude, Llama 2.
  • Agent: An intelligent entity that utilizes an LLM to reason, plan, and execute tasks. The agent’s role is to decide when and how to use the available tools (plugins) to achieve a user’s goal. It often involves a reflection and reasoning loop.
  • Plugin (or Tool/Function): A piece of code that the agent can call to perform a specific action or retrieve specific information. Each plugin has a well-defined purpose, input parameters, and expected output.

The interaction flow typically looks like this: User asks a question → Agent interprets the request → Agent decides if a plugin is needed → Agent calls the plugin with appropriate parameters → Plugin executes and returns results → Agent processes results and responds to the user.

The Anatomy of an Agent Plugin

While specific frameworks and platforms might have their own conventions, the fundamental components of an agent plugin are remarkably similar:

  1. Name: A unique, descriptive identifier for the plugin (e.g., getCurrentWeather, searchWikipedia, sendEmail).
  2. Description: A clear, concise explanation of what the plugin does and when it should be used. This is crucial for the LLM to understand its purpose and decide whether to invoke it.
  3. Parameters (Schema): A definition of the inputs the plugin expects. This is often described using a JSON schema, specifying parameter names, types, descriptions, and whether they are required.
  4. Implementation (Code): The actual code that performs the desired action when the plugin is invoked. This could be calling an external API, querying a database, performing a local computation, or interacting with a user interface.
  5. Output: The data returned by the plugin after execution.

Quick Start: Building a Simple Weather Plugin

Let’s explore a practical example. We’ll build a plugin that fetches the current weather for a given city. For simplicity, we’ll use a mock API, but the principles extend directly to real-world APIs.

Step 1: Define the Plugin’s Purpose and Interface

Name: get_current_weather
Description: “Gets the current weather conditions for a specified city. Useful for answering questions about temperature, humidity, and general weather outlook in a specific location.”
Parameters: We need the city. Let’s assume it’s a string and required.

Step 2: Implement the Plugin Function

We’ll use Python for our examples, as it’s widely adopted in the AI community. You can use any language, but the concepts remain the same.


import json

def get_current_weather(city: str) -> dict:
 """
 Gets the current weather conditions for a specified city.
 
 Args:
 city (str): The name of the city to get weather for.
 
 Returns:
 dict: A dictionary containing weather information (e.g., temperature, conditions, humidity).
 """
 # In a real-world scenario, you would make an API call here,
 # e.g., using requests.get('https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q={city}')
 
 # For this example, we'll return mock data
 mock_weather_data = {
 "London": {"temperature": 15, "conditions": "Cloudy", "humidity": 80},
 "New York": {"temperature": 22, "conditions": "Sunny", "humidity": 60},
 "Tokyo": {"temperature": 28, "conditions": "Rainy", "humidity": 90},
 "Paris": {"temperature": 18, "conditions": "Partly Cloudy", "humidity": 70},
 }
 
 weather = mock_weather_data.get(city, {"temperature": "N/A", "conditions": "Unknown", "humidity": "N/A"})
 
 return {"city": city, **weather}

Step 3: Describe the Plugin for the LLM (Function Calling Schema)

This is arguably the most critical step. The LLM doesn’t execute Python code directly; it needs a structured description of the plugin so it can generate the correct function call. Most LLM providers (OpenAI, Google, Anthropic, etc.) offer a ‘function calling’ or ‘tool use’ capability, where you provide a JSON schema describing your functions. Here’s how our weather plugin would be described:


{
 "type": "function",
 "function": {
 "name": "get_current_weather",
 "description": "Gets the current weather conditions for a specified city. Useful for answering questions about temperature, humidity, and general weather outlook in a specific location.",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {
 "type": "string",
 "description": "The name of the city (e.g., London, New York, Tokyo)"
 }
 },
 "required": ["city"]
 }
 }
}

Key elements in the schema:

  • type: "function": Indicates this is a function definition.
  • function.name: Matches our Python function name exactly.
  • function.description: This is what the LLM reads! Make it clear and thorough. Include use cases and examples if helpful.
  • function.parameters: A standard JSON Schema object defining the inputs.
  • properties: Defines each parameter (city in our case).
  • required: Lists parameters that must be provided.

Integrating with an LLM (OpenAI Example)

Now, let’s see how an LLM agent would use this plugin. We’ll use OpenAI’s function calling API as an example, but the concepts are transferable to other providers.


import openai
import os

# Assuming OPENAI_API_KEY is set in your environment variables
# openai.api_key = os.getenv("OPENAI_API_KEY") 

# Our defined tool schema
tools = [
 {
 "type": "function",
 "function": {
 "name": "get_current_weather",
 "description": "Gets the current weather conditions for a specified city. Useful for answering questions about temperature, humidity, and general weather outlook in a specific location.",
 "parameters": {
 "type": "object",
 "properties": {
 "city": {
 "type": "string",
 "description": "The name of the city (e.g., London, New York, Tokyo)"
 }
 },
 "required": ["city"]
 }
 }
 }
]

# The actual Python function we defined earlier
def get_current_weather(city: str) -> dict:
 # ... (same implementation as above) ...
 mock_weather_data = {
 "London": {"temperature": 15, "conditions": "Cloudy", "humidity": 80},
 "New York": {"temperature": 22, "conditions": "Sunny", "humidity": 60},
 "Tokyo": {"temperature": 28, "conditions": "Rainy", "humidity": 90},
 "Paris": {"temperature": 18, "conditions": "Partly Cloudy", "humidity": 70},
 }
 weather = mock_weather_data.get(city, {"temperature": "N/A", "conditions": "Unknown", "humidity": "N/A"})
 return {"city": city, **weather}

# A simple agent loop
def run_agent_with_tools(user_query: str):
 messages = [{
 "role": "user", 
 "content": user_query
 }]

 # First call to the LLM with the user's query and available tools
 response = openai.chat.completions.create(
 model="gpt-4o", # Or gpt-3.5-turbo, etc.
 messages=messages,
 tools=tools,
 tool_choice="auto" # Allows the LLM to decide if it wants to call a tool
 )

 response_message = response.choices[0].message
 messages.append(response_message)

 # Check if the LLM decided to call a tool
 if response_message.tool_calls:
 for tool_call in response_message.tool_calls:
 function_name = tool_call.function.name
 function_args = json.loads(tool_call.function.arguments)
 
 if function_name == "get_current_weather":
 # Execute the tool and get the result
 tool_output = get_current_weather(city=function_args.get("city"))
 
 # Add the tool output to the conversation history
 messages.append({
 "tool_call_id": tool_call.id,
 "role": "tool",
 "name": function_name,
 "content": json.dumps(tool_output)
 })
 
 # Second call to the LLM with the tool output
 final_response = openai.chat.completions.create(
 model="gpt-4o",
 messages=messages
 )
 print(final_response.choices[0].message.content)
 else:
 print(f"Error: Unknown tool called: {function_name}")
 else:
 # No tool call, just direct response from LLM
 print(response_message.content)

# Test cases
print("--- Query 1: Weather in London ---")
run_agent_with_tools("What's the weather like in London?")

print("\n--- Query 2: Weather in New York ---")
run_agent_with_tools("Tell me the current temperature in New York.")

print("\n--- Query 3: General question ---")
run_agent_with_tools("What is the capital of France?")

print("\n--- Query 4: Weather in an unknown city ---")
run_agent_with_tools("What's the weather in Atlantis?")

Explanation of the Agent Loop:

  1. User Query: The user asks a question (e.g., “What’s the weather like in London?”).
  2. First LLM Call: The user’s query and the list of available tools (our get_current_weather schema) are sent to the LLM. The LLM analyzes the query and the tool descriptions.
  3. LLM Decision: The LLM, based on its understanding, decides whether to call a tool.
    • If it decides to call a tool, it will generate a tool_calls object specifying the tool’s name and the parameters it wants to pass (e.g., {"name": "get_current_weather", "arguments": {"city": "London"}}).
    • If no tool is relevant, it will generate a direct text response.
  4. Tool Execution: If the LLM generates a tool call, our agent code intercepts this, extracts the function name and arguments, and then executes the actual Python function (get_current_weather("London")).
  5. Second LLM Call (with Tool Output): The result from the tool execution is then sent back to the LLM, along with the entire conversation history. The LLM now has the user’s original query, its own decision to call a tool, and the concrete result from that tool.
  6. Final Response: The LLM uses this information to formulate a natural language response to the user, incorporating the tool’s output.

Advanced Plugin Concepts and Best Practices

Error Handling and solidness

Real-world APIs fail. Your plugins should gracefully handle errors (network issues, invalid inputs, API rate limits, etc.). Return informative error messages from your plugin, and the LLM can often use these to inform the user or even attempt a retry with corrected parameters.


def get_current_weather_solid(city: str) -> dict:
 try:
 # Simulate API call with potential errors
 if city == "Error City":
 raise ValueError("API call failed for Error City: Service unavailable.")
 # ... rest of the successful mock data logic ...
 return {"city": city, **weather}
 except Exception as e:
 return {"error": str(e), "city": city}

Multiple Plugins and Tool Orchestration

An agent’s true power comes from using multiple plugins. Imagine a “travel planner” agent with plugins for:

  • search_flights(origin, destination, date)
  • book_hotel(city, check_in, check_out)
  • get_attractions(city)

The LLM, through its reasoning, can chain these tools. For example, if a user asks, “Plan a trip to Paris next month and find me some things to do,” the LLM might first call search_flights, then book_hotel (if confirmed by the user), and finally get_attractions.

When providing multiple tools, simply add more JSON schemas to the tools list in your LLM call.

Agent Reasoning and Reflection

Sophisticated agents don’t just execute tools; they reason about their actions. Frameworks like LangChain and LlamaIndex provide abstractions for this, often involving:

  • Planning: Breaking down complex goals into sub-tasks.
  • Tool Selection: Choosing the most appropriate tool for each sub-task.
  • Parameter Generation: Extracting necessary arguments from the conversation context.
  • Execution: Running the tool.
  • Observation: Interpreting the tool’s output.
  • Reflection: Assessing if the goal was met or if further actions/corrections are needed.

The LLM’s description of your plugin is central to this reasoning. A vague description leads to poor tool selection.

Security Considerations

  • Input Validation: Always validate inputs received by your plugin, even if the LLM generated them. Malicious or unexpected inputs can lead to vulnerabilities.
  • Least Privilege: Ensure your plugin only has access to the resources it absolutely needs.
  • Sensitive Data: Be extremely careful when handling sensitive information. Avoid exposing secrets directly in plugin descriptions or logs.
  • Rate Limiting/Access Control: Protect your backend systems from abuse by implementing appropriate rate limits and authentication for your plugin’s underlying APIs.

Asynchronous Operations

Many real-world plugin actions (e.g., sending emails, long-running database queries) are asynchronous. Your agent might need to handle this by returning a job ID and having another plugin to check job status, or by using webhooks.

Conclusion

Building agent plugins is a transformative skill for anyone working with LLMs. It moves beyond mere conversation, enabling AI systems to become truly interactive and actionable. By following the quick start guide, you’ve learned the fundamental components: defining the plugin’s purpose, implementing its logic, and, critically, describing it effectively using a JSON schema for the LLM. The power of these descriptions cannot be overstated – they are the bridge between an LLM’s linguistic understanding and its ability to interact with the real world.

As you venture further, remember to focus on clear descriptions, solid error handling, and thoughtful orchestration of multiple tools. The future of AI agents lies in their ability to smoothly integrate with the vast ecosystem of software and data, and plugins are the key to unlocking that potential. Start experimenting, build your own custom tools, and watch your AI agents come to life!

🕒 Last updated:  ·  Originally published: December 19, 2025

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: comparisons | libraries | open-source | reviews | toolkits
Scroll to Top