Skip to main content 홈 크리에이터 inugamidev ultrathink-oss ai-function-calling
ai-function-calling AI function calling / tool use patterns — schema definition, tool dispatch, streaming tool calls, and error handling.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/InugamiDev/ultrathink-oss --skill ai-function-calling명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Unified design foundations — design system architecture, tokens, component specs, visual principles, creative vision, figma integration, plus brand design system loader (66 real brands via DESIGN.md). Absorbs design, design-system, design-systems, design-principles, design-router, creative-vision, figma, design-md.
Render, summarize, and present markdown documents and structured content in multiple output modes
Ultra UI skill - combines Google's DESIGN.md spec (machine-readable design tokens) with the ui-ux-pro-max knowledge base (91 styles, 161 palettes, 73 font pairings, 161 products, 104 UX guidelines, 25 chart types). Generates lint-clean DESIGN.md files, validates token references and WCAG contrast, exports Tailwind/DTCG tokens, and diffs design systems version-over-version.
name ai-function-calling description AI function calling / tool use patterns — schema definition, tool dispatch, streaming tool calls, and error handling. layer utility category ai-ml triggers ["function calling","tool use","tool call","ai tools","function schema","tool dispatch"] inputs ["Tool schema definitions or requirements","Function calling integration questions","Streaming tool call patterns","Error handling for tool dispatch"] outputs ["Type-safe tool schemas with validation","Tool dispatch implementations","Streaming tool call handlers","Error recovery patterns for failed tool calls"] linksTo ["ai-agents","claude-api","openai","ai-sdk"] linkedFrom [] riskLevel medium memoryReadPolicy selective memoryWritePolicy none sideEffects []
AI Function Calling & Tool Use Patterns
Purpose
Provide expert guidance on designing, implementing, and managing AI function calling (tool use) across major LLM providers. Covers schema definition, runtime dispatch, streaming tool calls, parallel execution, error handling, and security considerations.
Key Patterns
Tool Schema Definition
Zod-based schemas — Define tools with runtime validation and TypeScript inference:
import { z } from 'zod' ;
const getWeatherParams = z.object ({
location : z.string ().describe ('City name or coordinates' ),
units : z.enum (['celsius' , 'fahrenheit' ]).default ('celsius' ),
});
interface ToolDefinition <T extends z.ZodType > {
name : string ;
description : string ;
parameters : T;
execute : (args : z.infer<T> ) => Promise <unknown >;
}
const weatherTool : ToolDefinition <typeof getWeatherParams> = {
name : 'get_weather' ,
description : 'Get the current weather for a location' ,
: getWeatherParams,
: (args) => {
{ location, units } = args;
{ : , units, location };
},
};
parameters
execute
async
const
return
temperature
22
JSON Schema generation — Convert Zod schemas to JSON Schema for API calls:
import { zodToJsonSchema } from 'zod-to-json-schema' ;
function toolToApiFormat (tool : ToolDefinition <z.ZodType > ) {
return {
type : 'function' as const ,
function : {
name : tool.name ,
description : tool.description ,
parameters : zodToJsonSchema (tool.parameters , {
$refStrategy : 'none' ,
target : 'openAI' ,
}),
},
};
}
Anthropic Claude Tool Use import Anthropic from '@anthropic-ai/sdk' ;
const client = new Anthropic ();
const tools : Anthropic .Messages .Tool [] = [
{
name : 'get_weather' ,
description : 'Get the current weather for a location' ,
input_schema : {
type : 'object' ,
properties : {
location : { type : 'string' , description : 'City name' },
units : { type : 'string' , enum : ['celsius' , 'fahrenheit' ] },
},
required : ['location' ],
},
},
];
async function agentLoop (userMessage : string ) {
const messages : Anthropic .Messages .MessageParam [] = [
{ role : 'user' , content : userMessage },
];
while (true ) {
const response = await client.messages .create ({
model : 'claude-sonnet-4-20250514' ,
max_tokens : 4096 ,
tools,
messages,
});
messages.push ({ role : 'assistant' , content : response.content });
const toolUseBlocks = response.content .filter (
(block): block is Anthropic .Messages .ToolUseBlock =>
block.type === 'tool_use'
);
if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn' ) {
return response;
}
const toolResults : Anthropic .Messages .ToolResultBlockParam [] =
await Promise .all (
toolUseBlocks.map (async (block) => {
try {
const result = await dispatch (block.name , block.input );
return {
type : 'tool_result' as const ,
tool_use_id : block.id ,
content : JSON .stringify (result),
};
} catch (error) {
return {
type : 'tool_result' as const ,
tool_use_id : block.id ,
content : `Error: ${(error as Error ).message} ` ,
is_error : true ,
};
}
})
);
messages.push ({ role : 'user' , content : toolResults });
}
}
Tool Dispatch Pattern Registry-based dispatch — Type-safe, extensible tool routing:
type ToolRegistry = Map <string , ToolDefinition <z.ZodType >>;
class ToolDispatcher {
private registry : ToolRegistry = new Map ();
register (tool : ToolDefinition <z.ZodType > ) {
this .registry .set (tool.name , tool);
}
async dispatch (name : string , rawArgs : unknown ): Promise <unknown > {
const tool = this .registry .get (name);
if (!tool) {
throw new Error (`Unknown tool: ${name} ` );
}
const parsed = tool.parameters .safeParse (rawArgs);
if (!parsed.success ) {
throw new Error (
`Invalid args for ${name} : ${parsed.error.issues.map((i) => i.message).join(', ' )} `
);
}
return tool.execute (parsed.data );
}
getToolDefinitions ( ) {
return Array .from (this .registry .values ()).map (toolToApiFormat);
}
}
Streaming Tool Calls Anthropic streaming — Handle tool use blocks as they arrive:
async function streamWithTools (messages : Anthropic .Messages .MessageParam [] ) {
const stream = client.messages .stream ({
model : 'claude-sonnet-4-20250514' ,
max_tokens : 4096 ,
tools,
messages,
});
const response = await stream.finalMessage ();
const toolBlocks = response.content .filter (
(b): b is Anthropic .Messages .ToolUseBlock => b.type === 'tool_use'
);
for await (const event of stream) {
if (
event.type === 'content_block_delta' &&
event.delta .type === 'text_delta'
) {
process.stdout .write (event.delta .text );
}
}
return { response, toolBlocks };
}
Vercel AI SDK Tool Calling import { generateText, tool } from 'ai' ;
import { anthropic } from '@ai-sdk/anthropic' ;
import { z } from 'zod' ;
const result = await generateText ({
model : anthropic ('claude-sonnet-4-20250514' ),
tools : {
getWeather : tool ({
description : 'Get weather for a location' ,
parameters : z.object ({
location : z.string (),
}),
execute : async ({ location }) => {
return { temperature : 22 , location };
},
}),
},
maxSteps : 5 ,
prompt : 'What is the weather in Tokyo?' ,
});
Parallel Tool Execution
async function executeToolsParallel (
toolBlocks : Anthropic .Messages .ToolUseBlock [],
dispatcher : ToolDispatcher
) {
const results = await Promise .allSettled (
toolBlocks.map (async (block) => ({
tool_use_id : block.id ,
result : await dispatcher.dispatch (block.name , block.input ),
}))
);
return results.map ((r, i ) => {
if (r.status === 'fulfilled' ) {
return {
type : 'tool_result' as const ,
tool_use_id : r.value .tool_use_id ,
content : JSON .stringify (r.value .result ),
};
}
return {
type : 'tool_result' as const ,
tool_use_id : toolBlocks[i].id ,
content : `Error: ${r.reason?.message ?? 'Unknown error' } ` ,
is_error : true ,
};
});
}
Security: Tool Sandboxing
interface ToolPermission {
allowedTools : string [];
maxCallsPerTurn : number ;
timeout : number ;
}
function createSandboxedDispatcher (
dispatcher : ToolDispatcher ,
permissions : ToolPermission
) {
let callCount = 0 ;
return async (name : string , args : unknown ) => {
if (!permissions.allowedTools .includes (name)) {
throw new Error (`Tool ${name} is not permitted` );
}
if (++callCount > permissions.maxCallsPerTurn ) {
throw new Error ('Tool call limit exceeded' );
}
const controller = new AbortController ();
const timeout = setTimeout (
() => controller.abort (),
permissions.timeout
);
try {
return await dispatcher.dispatch (name, args);
} finally {
clearTimeout (timeout);
}
};
}
Best Practices
Always validate tool inputs — Never trust model-generated arguments; parse with Zod or equivalent before execution.
Return structured errors — Use is_error: true (Anthropic) or structured error objects so the model can self-correct.
Set a max step/loop limit — Prevent infinite tool calling loops with a configurable maximum (5-10 steps is typical).
Use descriptive tool names and descriptions — The model selects tools based on name + description; vague names cause misrouting.
Keep parameter schemas simple — Flat objects with clear descriptions outperform deeply nested schemas.
Implement timeouts — All tool executions should have a timeout to prevent hanging.
Log all tool calls — Record tool name, input, output, and latency for debugging and cost tracking.
Prefer enum over free-text — Constrain parameters to known values where possible to reduce hallucination.
Handle partial tool calls in streaming — Accumulate JSON chunks before parsing; do not parse incomplete JSON.
Test with adversarial inputs — Models may generate unexpected argument combinations; fuzz your tool handlers.
Common Pitfalls Pitfall Problem Fix Missing tool_use_id in results API rejects the response Always map result back to the original tool_use_id No error handling in dispatch Unhandled rejection crashes the loop Wrap every tool execution in try/catch Infinite tool loops Model keeps calling tools forever Set maxSteps or a manual iteration limit Over-complex schemas Model struggles with deeply nested params Flatten schemas; use separate tools for complex operations Forgetting is_error flag Model treats error text as success data Always set is_error: true on failures Not validating tool output Downstream code crashes on unexpected shape Validate tool return values before serializing