Designing the Function Calling Boundary
메뉴

AI Backend

Designing the Function Calling Boundary

The boundary where model suggestions meet internal API side effects.

Designing the Function Calling Boundary hero image

Where to draw the line between LLM and internal API

In this article, we outline what boundaries should be drawn when connecting LLM and internal API using function calling.

function calling allows models to interact with external systems. In addition to answering user questions, you can also query data in the database, create tickets, search documents, and run workflows.

But an important question arises here.

How much should we leave to the model? Which API will be exposed as a tool? Who will do the permission checking? How do you bounce back when you fail?

Analysis base date: 2026-05-12 Practice environment: OpenAI API, FastAPI, PostgreSQL Key references: OpenAI function calling Docs, Structured Outputs Docs, AWS Idempotency

Key takeaways

  • function calling should be understood as a method in which the model structures the call intent and delivers it to the backend, rather than directly executing an internal API.
  • The backend tool executor must have actual execution permission.
  • Read-only tools and mutating tools must be separated.
  • State change tools may require idempotency, audit logs, and human approval.
  • The tool schema should not expose the entire internal API, but only provide the minimum interface required for the model.

1. How to understand function calling

function calling is dangerous when understood as the ability of a model to “directly execute” a function. More precisely, it is a function that suggests in a structured form which function the model should call with which arguments.

The actual execution must be done by the backend.

# This is an example.User request→ LLM decides tool call→ Backend validates tool call→ Permission check→ Execute internal API→ Return tool result to model→ Generate final response

The model is the decision assistant, and the backend is the executor.

2. What is Tool Boundary?

Tool Boundary is the boundary of functions exposed to the model.

Bad example:

# This is an example.execute_sql(query: string)

This tool is so powerful. Models can generate arbitrary SQL, and permissions and safety are difficult to control.

Good example:

# This is an example.search_documents(query: string, scope: enum, limit: integer)get_document_summary(document_id: string)create_support_ticket(title: string, description: string, priority: enum)

The actions required of the model should be limited to small tools.

3. Separation of Read Tool and Write Tool

Tool typeexampleriskprotection device
ReadDocument search, status inquirylow to mediumPermission filter, rate limit
WriteCreate ticket, send emailmedium to highidempotency, approval
DestructiveDelete, refund, change permissionsheightDefault ban or strong approval

For initial function calling, it is safe to start with a read-only tool.

4. Tool schema design

Example document search tool:

// This is an example JSON structure.{  "name": "search_documents",  "description": "Search for relevant content in documents accessible to the user.",  "parameters": {    "type": "object",    "properties": {      "query": {        "type": "string",        "description": "Natural language query to search"      },      "scope": {        "type": "string",        "enum": ["official_docs", "papers", "tech_blogs"]      },      "limit": {        "type": "integer",        "minimum": 1,        "maximum": 10      }    },    "required": ["query", "scope", "limit"],    "additionalProperties": false  }}

The design points are as follows:

# This is an example.[ ] Limit the scope with enum.[ ] limit Sets the maximum value.[ ] Internal ID or permission conditions are determined by the server.[ ] The user's original text input is not passed on to the internal API as is.

5. Authorization and authentication

Permission checking should be done by the server, not the model.

# This is an example.User A asks a questionto model suggests calling search_documentsto server checks user A's document permissionsto Search only authorized scopesto return result

It is not enough to tell the model, “Retrieve only documents accessible to this user.” The actual filter must be enforced on the backend.

6. Pre-execution Verification and Human Approval

State change tools require verification before execution.

# This is an example.Create LLM tool call→ schema validation→ business rule validation→ permission check→ risk classification→ human approval if needed→ execute

For example, sending emails, creating tickets, or changing customer status may require human approval.

// This is an example JSON structure.{  "tool": "create_support_ticket",  "arguments": {    "title": "Redis cache issue",    "description": "Users reported Redis cache miss issues.",    "priority": "medium"  },  "requires_approval": true}

7. Audit logs and reproducibility

function calling must leave an audit log.

log entryreason
user_idwho requested it
tool_nameWhich tool was called
tool_argumentsWhat arguments were used
validation_resultVerification passed or not
execution_resultexecution result
trace_idFailure analysis
prompt_versionReproducibility
modelquality analysis

However, sensitive information must be masked.

8. Failure and rollback

Tool execution may fail.

failure typereact
schema validation failedRetry model or fallback
No permissionrefuse to run tool
Internal API timeoutretry or user guidance
duplicate requestReturn existing results with idempotency key
Invalid state changerollback or compensation transaction

It is safer not to expose state change tools unless there is a rollback plan.

9. Practical checklist

# This is an example.[ ] Are the read tool and write tool separated?[ ] Does the tool schema follow the principle of least privilege?[ ] Are there input restrictions such as enum, max limit, etc.?[ ] Is permission checking enforced on the server?[ ] Does the status change tool have an idempotency key?[ ] Is there human approval for hazardous work?[ ] Are all tool calls left in the audit log?[ ] Is there an explainable response to the user in case of failure?

Failure case: When the internal API is exposed as a tool

A common mistake seen in function calling is exposing an already existing backend API almost as a tool. For example, if the model can call endpoints such asPOST /tickets,PATCH /users/:id, andDELETE /documents/:id, the implementation will be faster. However, these APIs are designed with the assumption that they are explicitly called by a person or server. If you give it to the model as is, the scope of arguments, permissions, approval, and retry implications are too broad.

In particular, the write API is dangerous without idempotency. If the model sees a timeout and tries the same tool call again, but the first request was actually successful, two tickets may be created. For tasks that require confirmation from the user, simply writing “call with caution” in the tool description is not enough. The server must check the approval state before final execution.

Implementation example: Creating a command API for a model

If you have a narrow command surrounding the internal API, the boundary becomes clearer.

type CreateTicketCommand = {  kind: "create_support_ticket";  idempotencyKey: string;  title: string;  summary: string;  priority: "low" | "normal" | "high";  requiresHumanApproval: true;};

This command is intentionally smaller than the internal ticket API. Values ​​such as assignee, internal label, and billing field are filled in by the server, making the model uneven. The model structures the proposal, “I need to create a ticket,” and the backend checks permissions and approval and calls the internal API.

Separate design interpretation from formal facts

What the official documentation provides is that “the model can make structured tool calls.” However, “which internal APIs will be exposed as tools,” “which tasks will be sent after approval,” and “which fields will be calculated by the server” are product design interpretations. If you mix the two, it's easy to mistake tool support for operational safety.

decisionofficial functionProduct Design Responsibility
schemaSpecify tool input formatField minimization and versioning
executionReceive tool callauthority, authorization, idempotency
errorPass failure responseRetry availability and user phrase
auditCall information can be obtainedStore who did what, why, and what

With this separation, function calling can be treated as a backend boundary rather than a model feature.

Practical example: Creating a customer support ticket

Let's say your customer support chatbot needs to view the conversation and create a ticket. A bad design would be to have the model populate every field in the internal ticket API. A good design is for the model to structure only the “ticket creation intent” and the server to populate the user information, organization, SLA, responsible queue, and approval status.

fieldCan the model fill it?reason
titleyesCan be extracted from conversation summary
summaryyesCorresponds to user problem description
prioritylimitedlyEnum and server calibration required
assigneenoOrganizational policies and work status required.
customerTiernoInternal CRM permission required
idempotencyKeyCreate serverAvoid duplicate creation

Failure case is retry after timeout. The model calledcreate_support_ticketand the provider response was delayed. The user makes the request again, and the model calls the same thing one more time. If you do not have an idempotency key, you will have two tickets. If there is no approval status, the user may say "just create a draft" but an actual ticket will be sent.

Therefore, it is safer to divide the write tool into three steps. First, the model creates a command draft, second, the server attaches validation and idempotency keys, and third, the user or policy approves and executes the internal API. In this structure, the result of function calling is not a side effect, but an intermediate product that turns side effect candidates into verifiable commands.

10. Q&A

Q1. Can I expose the internal API as a tool?

Not recommended. Tools for models should have a smaller and more limited interface than the internal API.

Q2. What if I select the wrong tool for the model?

The server must verify and reject the tool call. Model judgments are suggestions only.

Q3. Is function calling the same as Agent?

They can be components of an Agent, but they are not the same. function calling is an interface that structures external function calls.

11. References and uncertainty

References

uncertainty

  • function calling's detailed API and support model may vary depending on the time.
  • Actual tool approval criteria must be aligned with the organization's security and operational policies.

댓글

GitHub 계정으로 로그인하면 댓글을 남길 수 있습니다. 댓글은 GitHub Discussions를 통해 운영됩니다.

TOP