{"slug": "built-in-tools-vs-custom-tools-in-llm-agents", "title": "Built-In Tools vs. Custom Tools in LLM Agents", "summary": "A technical comparison of built-in versus custom tools in LLM agents finds that provider-run tools such as OpenAI's and Anthropic's hosted web search execute the entire tool loop inside a single API request, while custom tools require the developer to run the code on their own infrastructure. OpenAI's function-calling documentation describes a five-step flow for custom tools — send tools, get tool call, execute on the application side, send tool output back, get the final answer — whereas Anthropic's web-search flow lets Claude decide when to search and return results multiple times within one request. The distinction matters because providers including DeepSeek support tool calls but offer no hosted web-search tool, forcing developers to bring and run their own search tool.", "body_md": "### My First Week With GPT-6 Astra\n\nGPT-6 Astra was my main Codex driver for the last week, and I am back on GPT-5.5. That sounds harsher than my…\n\nWhen building AI agents, a tool can be anything that the model can ask to use such as a search engine, a database lookup, a shell command, etc. The model doesn’t directly operate those tools, but rather decides what tool would be helpful, requests a tool use with parameters, gets the result back, and then continues it's work.\n\nA custom tool is a tool that you define and run on your own infrastructure. You provide a schema such as `search_web` or `get_customer_balance` to the model, the model requests it, and your application runs the actual code on your infrastructure.\n\nA built-in tool is different. The provider runs it in its own runtime. In practice this mostly means hosted web search. [OpenAI](https://developers.openai.com/api/docs/guides/tools-web-search) and [Anthropic](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) both offer provider-run web search in their APIs. That means if you use ChatGPT or Claude (or Codex CLI or Claude Code), they can just search the web and access websites, which internally means they use their built-in web search tool. Other providers like [DeepSeek](https://api-docs.deepseek.com/guides/tool_calls) also support tool calls (any llm does so more or less) but don’t offer a hosted web-search tool themselves, so you’ll have to bring and run the search tool yourself.\n\nSo a built-in tool feels more “native” mostly because it happens \"magically\" under the hood. The question I'm interested in here is, what's the difference between using built-in tools vs your own custom tools that you give the LLM. In other words, what's the difference between using ChatGPT/Codex with its integrated web search vs. using DeepSeek while providing my own custom made web search tool.\n\nThe architecture for a normal tool you provide is roughly like this:\n\nThe key boundary here is that the model doesn’t execute your function. It returns a structured request that says, effectively:\n\n```\n{\n  \"tool\": \"search_web\",\n  \"arguments\": {\n    \"query\": \"latest Nvidia earnings\"\n  }\n}\n```\n\nYour program sees that, executes something, and sends the result back.\n\nThe current [function-calling documentation](https://developers.openai.com/api/docs/guides/function-calling) from OpenAI describes this five-step flow pretty much exactly: send tools, get tool call, execute on your application side, send tool output back, get continuation/final answer.\n\nNow move the orchestrator inside the provider.\n\nThe entire loop can happen **in one API request from your end.**\n\nAnthropic’s current [web-search flow](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) works like this: Claude decides when to search, the API searches and returns results to Claude, and this can happen multiple times in the request before Claude returns the final answer.\n\nOpenAI also refers to the use of a reasoning model for web search as **agentic search**, where the model manages the search process, analyzes the results, and can choose to continue searching. The search events are exposed in their Responses API as [`web_search_call` items](https://developers.openai.com/api/docs/guides/tools-web-search).\n\nSo that distinction you're noticing is real.\n\nThis is where terminology gets tricky.\n\nConceptually, yes:\n\nOpenAI documentation currently describes agentic web search as being able to do searches “as part of its chain of thought.”\n\nBut do not interpret that as an HTTP request that somehow occurs between transformer layer 63 and transformer layer 64. That’s almost certainly not the right mental model.\n\nA better abstraction would be the generated text hitting a tool boundary, where the external runtime does the tool work and the model continues from the returned observation.\n\nThe generation is effectively interrupted/suspended at a tool boundary, where an external system gets an observation and generation proceeds with that observation available.\n\nThe exact internal implementation (KV cache handling, worker scheduling, separate inference passes, etc.) is a provider-private implementation detail. Do not assume that the tool is literally implemented within one transformer forward pass.\n\nAt the abstract level:\n\n```\nLLM → action → environment → observation → LLM\n```\n\nSo, **no new cognitive operation is magically available only with provider tools.**\n\nThis distinction is important.\n\nThis is where the practical difference becomes significant.\n\nThere are several advantages a provider can have.\n\nThis is potentially the biggest difference.\n\nImagine these two tool schemas.\n\nYour tool:\n\n```\ninternet_lookup(\n    query,\n    search_depth,\n    domains,\n    freshness\n)\n```\n\nProvider tool:\n\n```\nweb_search(...)\n```\n\nThe provider may have trained the model on millions of trajectories like the following during post-training:\n\n```\nquestion\n→ reason\n→ web_search\n→ inspect\n→ reason\n→ web_search\n→ inspect\n→ answer with citation\n```\n\nThey can optimize things like:\n\n```\nShould I search?\nWhat query should I issue?\nShould I search again?\nWhich result should I open?\nWhich information is relevant?\nShould I trust it?\nWhen do I have enough evidence?\nHow do I cite it?\n```\n\nThat is much more than learning JSON syntax.\n\nIt is **tool-use policy learning**.\n\nFor example, Anthropic discusses [interleaved thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) for supported tool-use modes. In this case, the model can reason between tool calls to decide what to do next.\n\nSo, if you plug in your own unfamiliar search tool, the model might generalize very well, but it might not have exactly the same amount of post-training on *your particular interface*.\n\nThis is another important point.\n\nSuppose your implementation is:\n\n```\nresults = bing.search(query)\nreturn results[:10]\n```\n\nThe model receives 10 chunks.\n\nA provider's `web_search` might conceptually be closer to:\n\n```\nquery generation\n       ↓\nmultiple search backends\n       ↓\nranking\n       ↓\nfetch pages\n       ↓\nextract readable content\n       ↓\ndeduplicate\n       ↓\nspam/quality filtering\n       ↓\nreranking\n       ↓\ntoken-budget optimization\n       ↓\ncitation metadata\n       ↓\nmodel context\n```\n\nAnd there can be additional loops around it.\n\nAnthropic’s current web search is a good concrete example. Newer versions can get Claude to run code to **filter search results before they get into the model context**, so irrelevant content takes up fewer context tokens.\n\nOpenAI also allows controls over search context and returned-token budgets, and its search in reasoning mode can perform search, page opening, and find-in-page tasks.\n\nSo when comparing:\n\n```\nprovider web_search\n```\n\nversus\n\n```\nmySearchTool()\n```\n\nyou may actually be comparing two very different retrieval systems.\n\nYour loop may involve model inference, an API round trip to your application, your own process, a search API call, another process step, another API round trip, and then model inference again. Perhaps repeated 5 times.\n\nA hosted loop may look more like a model worker that calls an internal tool service and then continues on the model worker.\n\nThe provider has opportunities to optimize for scheduling, networking, result serialization, caching, streaming, etc.\n\nThat can make multi-step research materially faster.\n\nI would not, though, assume things like “they definitely preserve the exact KV cache across searches” unless the provider explicitly documents it. That is implementation-specific.\n\nWith a client tool, suppose you return this:\n\n```\n{\n  \"results\": [\n    { \"title\": \"...\", \"content\": \"8,000 tokens...\" },\n    { \"title\": \"...\", \"content\": \"10,000 tokens...\" },\n    ...\n  ]\n}\n```\n\nYou've now dumped a mountain of text into the model context.\n\nA tool integrated with a provider can tightly control search corpus, filtering, extraction, reranking, selection, compression and model context. And metadata can potentially be kept separately.\n\nThat often gives you a better:\n\n```\nuseful-information / context-token\n```\n\nratio.\n\nThis can have a surprisingly large effect on agent quality.\n\nProvider-hosted doesn't inherently mean superior.\n\nImagine you're building a programming agent.\n\nInstead of generic web search, you give it:\n\n```\nsearch_github_code()\nsearch_stackoverflow()\nsearch_npm()\nfetch_package_docs()\nsearch_internal_docs()\nlookup_symbol()\n```\n\nplus carefully optimized schemas and result formatting.\n\nThat system may dramatically outperform generic web search for your application.\n\nOr for a financial agent:\n\n```\nget_sec_filing()\nget_realtime_price()\nget_earnings_transcript()\nquery_bloomberg()\n```\n\nis probably preferable to blindly searching the internet.\n\nSo provider tools tend to win on:\n\n```\ngeneral-purpose integration\nzero setup\nlatency\ncitations\nmodel/tool co-optimization\n```\n\nwhile your own tools win on:\n\n```\ncontrol\ndomain specificity\nprivate data\ndeterministic APIs\ncustom ranking\nobservability\nsecurity boundaries\ncost control\nprovider independence\n```\n\nModern agent architectures actually have something like four levels.\n\nLevel 1: A client function. Level 2: A remote tool or MCP server. Level 3: A tool hosted by a provider. Level 4: A full product-level agent environment with shell, filesystem, browser, search, git, task state, etc.\n\nAt this point you're not really comparing models anymore.\n\nYou're comparing **agent systems**.\n\nAnd that's becoming increasingly important.\n\nSuppose you have:\n\n```\nModel A\n- excellent reasoning\n- excellent function calling\n- no web-search feature\n```\n\nand:\n\n```\nModel B\n- excellent reasoning\n- native web search\n```\n\nYou can absolutely build this around Model A:\n\n```\nwhile True:\n    response = model(messages, tools=tools)\n\n    if response.tool_call:\n        result = run_tool(response.tool_call)\n        messages += [response.tool_call, result]\n        continue\n\n    return response.text\n```\n\nArchitecturally, you've recreated the same agent loop.\n\nThere's no fundamental reason Model A couldn't do excellent web research.\n\nThe main variables become:\n\n```\nreasoning ability\n×\ntool-use training\n×\nquality of your search stack\n×\ncontext management\n×\nagent-loop design\n```\n\nnot simply:\n\n```\nnative web search: yes/no\n```\n\nThere is a more fundamental distinction here.\n\nConsider three models:\n\n```\nModel A\nExcellent reasoning\nExcellent native/function tool use\n\nModel B\nExcellent reasoning\nTool calling supported but mediocre\n\nModel C\nPlain text model, no meaningful tool-use training\n```\n\nYou can bolt tools onto all three.\n\nFor C you could say:\n\n```\nWhen you want to search, output:\n\n<search>\nquery\n</search>\n```\n\nand parse it.\n\nTechnically it works.\n\nHowever, agent quality may be much worse if the model hasn’t learned a robust policy for:\n\n```\nwhen to act\nwhich action\nargument construction\nresult interpretation\nerror recovery\nmulti-step exploration\nstopping\n```\n\nThat’s one reason that modern “agentic models” feel qualitatively different from older LLMs, even if they can both emit JSON on paper.\n\nI'd model an agentic LLM as approximately implementing a policy:\n\n```\n\\pi(a_t \\mid s_t)\n```\n\nwhere its current state is something like:\n\n```\ns_t =\n\\{\n\\text{prompt},\n\\text{conversation},\n\\text{reasoning state},\n\\text{previous observations},\n\\text{available tools}\n\\}\n```\n\nand the next action might be:\n\n```\na_t \\in\n\\{\n\\text{text},\n\\text{web_search},\n\\text{shell},\n\\text{read_file},\n\\text{write_file},\n...\n\\}\n```\n\nA tool execution changes the environment:\n\n```\no_{t+1} = Tool(a_t)\n```\n\nand that observation is fed back:\n\n```\ns_{t+1} = s_t + a_t + o_{t+1}\n```\n\nThen the model chooses again.\n\nFrom this perspective, **provider search and your custom search are mathematically the same kind of operation**.\n\nWhat differs is who implements:\n\n```\nTool(a_t)\n```\n\nand who implements the surrounding control loop.\n\nThis is a particularly important consequence.\n\nSuppose the naked model has capability `M`.\n\nYou might think:\n\n```\nAgentCapability = M\n```\n\nBut it's more like:\n\n```\nAgentCapability =\nf(\nM,\ntools,\ntool\\ policy,\nretrieval,\ncontext\\ management,\norchestration\n)\n```\n\nA good search-enabled model may seem much smarter because it can repeatedly turn uncertainty into information:\n\nThat's qualitatively different from classic one-shot RAG.\n\nThe **model controls retrieval dynamically**.\n\nThat's a huge part of the power.\n\nTraditional RAG works by retrieving before inference. Agentic retrieval allows the model to retrieve, see, continue, and then retrieve again.\n\nThe information-gathering policy itself becomes part of the reasoning process.\n\nThis architecture is particularly easy and efficient with provider-hosted search, since the provider owns that entire inner loop.\n\nBut you can implement precisely this pattern yourself.\n\n|  | Provider web search | Your own web-search tool | \n|---|---|---|\n| Execution | Provider infrastructure | Your infrastructure | \n| Agent loop | Usually provider-side | Usually your orchestrator | \n| Extra API round trips | Fewer/exposed less | Usually yes | \n| Model specialization | Often highly optimized | Depends on model | \n| Retrieval pipeline | Provider-controlled | Fully yours | \n| Search ranking | Provider-controlled | Fully yours | \n| Context optimization | Often built in | You implement it | \n| Citations | Usually first-class | You implement them | \n| Observability | Limited | Excellent | \n| Customization | Limited/moderate | Unlimited | \n| Private sources | Limited to integrations | Excellent | \n| Vendor lock-in | Higher | Lower | \n| Domain-specific quality | General purpose | Can be much better | \n\nIf I were designing agents, I'd think of it like this:\n\n```\nMODEL\n  ↓ action\nORCHESTRATOR\n  ↓ execute\nTOOLS\n  ↑ observation\n```\n\nThe **conceptual algorithm is the same**.\n\nThe differences are in integration, post-training, latency, retrieval quality, context management, and operational control.\n\nAnd so I would **not choose an LLM provider purely because it has native web search**. If a model has good reasoning and good generic tool-use capabilities, you can build a great (or for specialized use cases, better) search agent on top of it. The native tool is much more important if you want strong general-purpose research with minimal engineering.\n\nThe most interesting next layer here is **how reasoning models are actually trained to decide *when* to call tools** -- i.e. how tool use appears in SFT/RL trajectories and why that produces better agents than merely teaching a model a JSON function-calling grammar. That's where the architecture starts connecting directly to the model training itself.\n\nGive Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.\n\nTake a look at vroni.com", "url": "https://wpnews.pro/news/built-in-tools-vs-custom-tools-in-llm-agents", "canonical_source": "https://www.vincentschmalbach.com/built-in-tools-vs-custom-tools-llm-agents/", "published_at": "2026-09-15 13:25:42+00:00", "updated_at": "2026-09-15 13:44:49.241713+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "large-language-models", "ai-products", "developer-tools"], "entities": ["OpenAI", "Anthropic", "DeepSeek", "ChatGPT", "Claude", "Codex CLI", "Claude Code", "GPT-6 Astra"], "alternates": {"html": "https://wpnews.pro/news/built-in-tools-vs-custom-tools-in-llm-agents", "markdown": "https://wpnews.pro/news/built-in-tools-vs-custom-tools-in-llm-agents.md", "text": "https://wpnews.pro/news/built-in-tools-vs-custom-tools-in-llm-agents.txt", "jsonld": "https://wpnews.pro/news/built-in-tools-vs-custom-tools-in-llm-agents.jsonld"}}