EngineeringCategory

Building AI Agents at GoDaddy – An Agent’s Toolkit

11 min read
Karthik IyerRamji Chandrasekaran

Key takeaways

  • AI agents need standardized, task-agnostic tools that work across any use case, not just custom tools for specific tasks. These universal tools reduce development overhead and create consistency.
  • Treating every agent action as a tool call—including talking to users and ending conversations—keeps agents in control and maintains context throughout interactions.
  • Four essential tools should be in every agent's toolkit: MemoryTool, CompletionTool, UserInteractionTool, and DelegationTool. Together they enable agents to remember context, end conversations naturally, communicate effectively, and hand off to humans or other agents.

What's the difference between a bad workman and a bad agent? A bad workman blames his tools but a bad agent blames itself. Amid the rush to operationalize AI Agents, developers frequently neglect how crucial it is to thoughtfully equip agents with the right tools to achieve their objectives. Our last article on AI Agents presented our focus on first-principles thinking in building AI Agents and made the case for well designed tools. In this continuation post, we propose four tools that are not only good exemplars of these principles but also should be in every agent's toolkit.

The case for default tools

Every AI agent is different by virtue of its system prompt and tools. Increasingly, we see agents equipped with two categories of tools: task-specific (custom tasks) and task-agnostic (universal tasks). Task-specific tools will always be dependent on the agent and the task it is trying to automate. There will likely be less standardization here; and if standardization occurs at all, it will be in the protocol layer (like MCP). In contrast, task-agnostic tools are better suited for standardization given their universality of usage. For example, web search and file explorer are generic tools that are task-agnostic but still help the agent in progressing towards the goal. They provide an abstraction over standard, well-established tasks and hide away underlying complexities. By being available out-of-the-box, they reduce implementation overhead for developers. As the understanding and implementation of AI agents matures, we expect the set of task-agnostic tools to expand and get standardized rapidly in the coming months.

The expanded toolkit

From our learned experience of building AI agents at GoDaddy, we propose the addition the following tools to the default toolkit of all agents:

ToolPurpose
MemoryToolAutomatically saves and retrieves contextual information during interactions as instructed in the system prompt.
CompletionToolEmpowers AI agents to naturally determine end of a conversation.
UserInteractionToolFacilitates clarifying questions, confirmations, or request additional input from the user to resolve ambiguity or gather missing information.
DelegationToolSmoothly transitions to a user or another agent when the interaction goes out of scope.

MemoryTool

Arguably, the most useful tool in the list is the MemoryTool, which an agent can use to save or retrieve any information to and from an associated memory service. This allows AI agents to use their independent judgement to determine what to remember in interactions with a customer over multiple sessions and timelines. Based on the goals it is asked to achieve, it can remember contextual information about a user, domain, product or any other dimension of interest. This allows an agent to not only maintain continuity over long term interactions with the customer, but also allow for adaptation to emerging customer preferences. The nice thing about the MemoryTool is that saving to memory is almost always a parallel operation alongside other tool calls. For example, a domain search agent would make two parallel tool calls: one to perform the domain search itself using the inferred content and another to save some information to memory, as illustrated in the following snippet:

{
  "context": {
    "memory": {
      "business_focus": {
        "updated_at": "2025-09-24T14:46:24.099Z",
        "value": "AI consulting for SMB manufacturing (US); target 100-5,000 employees or $10M-$500M revenue; pilot-based ROI-driven engagements"
      },
      "domain_style": {
        "updated_at": "2025-09-24T14:50:09.550Z",
        "value": ".com preferred; short; no hyphens; manufacturing; ROI-focused; brandable"
      }
    }
  }
}

Functionally, this is similar to a span recognition task in natural language processing, but with the added generative capabilities of LLMs. By asking the agent to use this tool, we get a direct insight into what the underlying LLM found important and use that information to debug the behavior of the agent.

CompletionTool

The CompletionTool emerged from our search for an elegant solution to a fundamental problem: how should an agent exit its reasoning loop? Earlier in the year, the common practice was to check for specific exit conditions: either the LLM returned a text response instead of a tool call, or the user typed magic incantations like 'exit' or 'quit'. Both felt like hacks we desperately wanted to avoid. This imperative approach failed to leverage the power of modern LLMs to naturally recognize when a conversation has reached its conclusion. For example, a simple phrase like "Ok thanks, for the help." clearly signals that the current objective has been completed.

The goal was to encode the notion of an end state through a tool and empower the agent to determine when a conversation reaches its natural conclusion. The following schema for this tool is quite simple:

{
  type: 'object',
  properties: {
    action: {
      type: 'string',
      enum: ['terminate', 'giveup'],
      description: 'The action to take: terminate (successful completion) or giveup (unable to complete objective)',
    },
    reason: {
      type: 'string',
      description: 'A verbose reason for calling this tool',
    },
  },
  required: ['action', 'reason'],
  additionalProperties: false,
}

With appropriate tool instructions, the LLM can recognize conversation endings naturally, eliminating hardcoded exit conditions and accommodating diverse user expressions — no magic words required. The LLM reliably distinguishes between successful completion and giving up after repeated failures, conveying this through the action parameter. The accompanying reason provides valuable insight into why the agent terminated.

In practice, we supplement CompletionTool with a max_turns parameter as an outer perimeter guardrail to catch and contain errant LLM behavior. As a testament to the rapid progress and standardization of Agentic AI, the OpenAI Agent SDK provides a StopAtToolNames argument to terminate the agent's loop. Naturally, in our implementations, we set StopAtToolNames: [CompletionTool].

UserInteractionTool

The UserInteractionTool is an application of the tool-centricity principle at the limits. It arose from a simple question: "If every action an agent could take is facilitated through a tool, why would communication alone be an exception?". This tool is perhaps the most counterintuitive on the list. As agent developers, we are conditioned to separate tool calls from text response. It is odd to think of user interaction as a tool, but in hindsight it makes total sense. The following is an example of a possible simplified schema for this tool:

{
  type: 'object',
  properties: {
    action: {
      type: 'string',
      enum: ['inform', 'confirm', 'respond', 'approve'],
      description: 'The type of interaction: inform (notify user), confirm (request confirmation), respond (answer user query), or approve (await approval)',
    },
    message: {
      type: 'string',
      description: 'The actual contents to be delivered to the user',
    },
  },
  required: ['action', 'message'],
  additionalProperties: false,
}

Two key benefits to this approach are:

  • It keeps the agent in control throughout the conversation. Traditional approaches force the agent to exit its reasoning loop when communicating with users, losing context and requiring complex state management to resume. By treating user interaction as a tool call, the agent can naturally inform users of progress, request clarifications, or seek confirmations — all while remaining in its loop, maintaining its context, and seamlessly incorporating responses to continue toward its goal.
  • It decouples the delivery mechanism from the message content. The LLM decides what to communicate and why (inform, confirm, approve), while the tool implementation handles how to deliver it. For example, an inform action might display non-blocking text, while a confirm action could render a form requesting the user's shipping address with proper fields for street, city, and zip code. An approve action might trigger a modal popup that blocks interaction until the user responds. The user's response feeds back as a tool result, allowing the agent to continue its reasoning with structured, validated data.

DelegationTool

The DelegationTool addresses a critical gap in current agent architectures: the assumption that there is only one human in a conversation and handoffs occur between agents. Most existing delegation mechanisms focus solely on agent-to-agent handoffs, but real-world applications often require more complex, multi-participant conversations involving agent-to-agent and agent-to-human handoffs.

Consider a customer support scenario where an AI agent is helping a customer with a domain transfer issue. The agent might need to escalate to a human support specialist for complex billing questions, or delegate to a specialized DNS configuration agent for technical tasks. Current handoff patterns treat these as fundamentally different operations, requiring separate implementation logic.

The DelegationTool provides a unified abstraction for all types of handoffs:

{
  type: 'object',
  properties: {
    target_type: {
      type: 'string',
      enum: ['human', 'agent', 'system'],
      description: 'The type of entity to delegate to',
    },
    target_id: {
      type: 'string',
      description: 'Identifier for the delegation target',
    },
    context: {
      type: 'object',
      description: 'Relevant information to transfer during handoff',
    },
    reason: {
      type: 'string',
      description: 'Explanation for the delegation',
    },
    urgency: {
      type: 'string',
      enum: ['low', 'medium', 'high'],
      description: 'Priority level of the delegation',
    },
  },
  required: ['target_type', 'target_id', 'context', 'reason'],
  additionalProperties: false,
}

By standardizing delegation through a single tool, we achieve the following benefits:

  • Unified Interface: The agent doesn't need to distinguish between human and agent targets - it simply delegates based on capability requirements.
  • Context Preservation: Critical information is explicitly transferred during the handoff.
  • Routing Flexibility: The underlying system can route to available humans or agents based on load, expertise, or availability.
  • Audit Trail: All delegations are logged consistently, enabling better workflow analysis.

For instance, in our customer support agent, a single delegation call can route a complex billing inquiry to either a human specialist or a specialized billing agent, based on availability and the customer's service tier. The agent simply recognizes when it needs help; the tool handles all orchestration complexity. This pattern naturally enables multiagent collaboration for complex problem spaces, and we're pleased to see the industry converging on similar approaches — the OpenAI Agent SDK, for example, uses comparable delegation behavior to power its handoffs feature.

Conclusion

As AI agents transition from experimental prototypes to production systems, thoughtful tool design becomes paramount. The four tools presented here — MemoryToolCompletionToolUserInteractionTool, and DelegationTool — represent more than utilities; they embody fundamental principles of robust agent architecture.

These tools share common characteristics that make them universally applicable: they decouple decision-making from execution, provide clean abstractions over complex operations, and maintain consistency across different agent implementations. By standardizing these capabilities, we reduce cognitive load on both agents and developers, enabling focus on higher-level problem solving rather than implementation details.

At GoDaddy, these tools have proven their value across diverse use cases—both internal and external. They've enabled our agents to handle complex, multi-turn conversations while maintaining context, gracefully managing failures, and seamlessly coordinating with human colleagues when needed.

As the AI agent ecosystem rapidly evolves and the community converges on common patterns, we expect these task-agnostic tools to become essential to agent development. The future of AI agents lies not just in more sophisticated models, but in the thoughtful engineering of the systems that surround them. In the next post of this series, we'll take a deep dive into specific tool implementations, analyze performance, and share production lessons learned.