Skip to Content

AI Function Calling

undefined

@autobe/interface
import { AutoBePrisma } from "./AutoBePrisma"; /** * Union type representing the result of Prisma schema validation. * * This type encapsulates the outcome of validating an AutoBePrisma.IApplication * structure against Prisma schema rules and business constraints. The * validation process checks for structural integrity, referential consistency, * naming conventions, and compliance with the established schema generation * rules. * * The validation can result in either complete success (all rules satisfied) or * failure with detailed error information for precise error resolution. * * @author Samchon */ export type IAutoBePrismaValidation = | IAutoBePrismaValidation.ISuccess | IAutoBePrismaValidation.IFailure; /** * Namespace containing all interfaces for Prisma schema validation results. * * This namespace defines the structure for validation responses from the schema * validation system, providing detailed feedback about schema correctness and * specific error locations when validation fails. */ export namespace IAutoBePrismaValidation { /** * Interface representing a successful validation result. * * This interface is returned when the AutoBePrisma.IApplication structure * passes all validation rules including: * * - No duplicate model names across all files * - No duplicate field names within any model * - No duplicate relation names within any model * - All foreign key references point to existing models * - All field types are valid and properly configured * - All indexes follow the established rules (no single foreign key indexes) * - All naming conventions are properly applied (plural models, snake_case * fields) * - All business constraints are satisfied */ export interface ISuccess { /** * Validation success indicator. * * Always true for successful validation results. This discriminator * property allows TypeScript to properly narrow the union type and provides * runtime type checking for validation result processing. */ success: true; /** * The validated and approved AutoBePrisma application structure. * * This contains the complete, validation-passed schema definition that can * be safely passed to the code generator for Prisma schema file creation. * All models, fields, relationships, and indexes in this structure have * been verified for correctness and compliance with schema rules. * * Important: This may not be identical to the original input application. * The validation process can apply automatic corrections to resolve * validation issues such as removing duplicates or fixing structural * problems. These corrections preserve the original business intent while * ensuring schema consistency and data integrity. */ data: AutoBePrisma.IApplication; } /** * Interface representing a failed validation result with detailed error * information. * * This interface is returned when the AutoBePrisma.IApplication structure * contains one or more validation errors. It provides both the original * (potentially flawed) application structure and a comprehensive list of * specific errors that need to be resolved. * * The error information is structured to enable precise error location * identification and targeted fixes without affecting unrelated parts of the * schema. */ export interface IFailure { /** * Validation failure indicator. * * Always false for failed validation results. This discriminator property * allows TypeScript to properly narrow the union type and indicates that * the errors array contains specific validation issues that must be * resolved. */ success: false; /** * The original AutoBePrisma application structure that failed validation. * * This contains the complete schema definition as it was submitted for * validation, including all the elements that caused validation errors. * This structure serves as the baseline for error analysis and correction, * allowing error-fixing systems to understand the full context of the * schema while addressing specific validation issues. */ data: AutoBePrisma.IApplication; /** * Array of specific validation errors found in the application structure. * * Each error provides precise location information (file path, model name, * field name) and detailed error descriptions to enable targeted fixes. * Errors are ordered by severity and location to facilitate systematic * resolution. The array will never be empty when success is false. * * Common error categories include: * * - Duplication errors (duplicate models, fields, relations) * - Reference errors (invalid foreign key targets, missing models) * - Type validation errors (invalid field types, constraint violations) * - Index configuration errors (invalid field references, forbidden single FK * indexes) * - Naming convention violations (non-plural models, invalid field names) */ errors: IError[]; } /** * Interface representing a specific validation error with precise location * information. * * This interface provides detailed information about individual validation * errors, including exact location within the schema structure and * comprehensive error descriptions. The location information enables * error-fixing systems to pinpoint exactly where problems occur without * manual search or guesswork. * * Each error represents a specific violation of schema rules that must be * resolved for successful validation. */ export interface IError { /** * File path where the validation error occurs. * * Specifies the exact schema file within the * AutoBePrisma.IApplication.files array where this error was detected. This * corresponds to the filename property of the IFile interface and enables * targeted file-level error resolution. * * Examples: "schema-01-articles.prisma", "schema-03-actors.prisma" * * This path information allows error-fixing systems to: * * - Navigate directly to the problematic file * - Understand cross-file reference issues * - Apply fixes within the correct file context * - Maintain proper file organization during error resolution */ path: string; /** * Name of the model (database table) where the validation error occurs. * * Specifies the exact model within the identified file that contains the * validation error. This corresponds to the name property of the IModel * interface and enables targeted model-level error resolution. * * Examples: "shopping_customers", "bbs_articles", * "mv_shopping_sale_last_snapshots" * * When null, indicates file-level errors such as: * * - Duplicated file names * - Invalid file names * * This model information allows error-fixing systems to: * * - Navigate directly to the problematic model definition * - Understand model-specific constraint violations * - Apply fixes within the correct model context * - Resolve cross-model relationship issues */ table: string | null; /** * Name of the specific field (column) where the validation error occurs. * * Specifies the exact field within the identified model that contains the * validation error, or null for model-level errors that don't relate to a * specific field. This corresponds to field names in primaryField, * foreignFields, or plainFields arrays of the IModel interface. * * Examples: "shopping_customer_id", "created_at", "name", null * * When null, indicates model-level errors such as: * * - Duplicate model names across files * - Missing primary key definitions * - Invalid model naming conventions * - Model-level constraint violations * * When string, indicates field-level errors such as: * * - Duplicate field names within the model * - Invalid field types or constraints * - Invalid foreign key configurations * - Field naming convention violations * * This field information allows error-fixing systems to: * * - Navigate directly to the problematic field definition * - Distinguish between model-level and field-level issues * - Apply targeted fixes without affecting other fields * - Resolve field-specific constraint violations */ field: string | null; /** * Detailed human-readable description of the validation error. * * Provides comprehensive information about what validation rule was * violated, why it's problematic, and often hints at how to resolve the * issue. The message is designed to be informative enough for both * automated error-fixing systems and human developers to understand and * address the problem. * * Message format typically includes: * * - Clear description of what rule was violated * - Specific details about the problematic element * - Context about why this causes validation failure * - Sometimes suggestions for resolution approaches * * This message information allows error-fixing systems to: * * - Understand the exact nature of the validation failure * - Implement appropriate resolution strategies * - Provide meaningful feedback to developers * - Log detailed error information for debugging * - Make informed decisions about fix approaches */ message: string; } }

@autobe fundamentally prefers AI function calling to generate AST (Abstract Syntax Tree) data over having AI write raw programming code as text. The system validates the AST data generated through AI function calling, provides feedback to the AI for correction when errors are detected, and finally converts the validated AST data into actual programming code.

Therefore, the success of @autobe depends on three critical factors. First, how precisely and efficiently we can create AI function calling schemas. Second, how detailed and accurate validation feedback we can provide to the AI when it generates incorrect AST data. Finally, how clearly we can communicate the coding rules that @autobe must follow while constructing code (composing AST data) to the AI.

To address these challenges, @autobe adopts typia to generate AI function calling schemas at the compiler level. The compiler integrated with typia not only creates AI function calling schemas but also generates validation functions for each type. Moreover, the coding rules that @autobe must follow are embedded as comments in each AST type. These comments are recorded as type descriptions when typia converts TypeScript types into AI function calling schemas.

This approach creates a comprehensive development story that ensures both type safety and rule compliance through compiler-driven automation.

Schema Made by Compiler

import { AutoBeOpenApi, AutoBePrisma } from "@autobe/prisma"; import { ILlmApplication } from "@samchon/openapi"; import typia from "typia"; const app: ILlmApplication<"chatgpt"> = typia.llm.application< ICodeGenerator, "chatgpt", { reference: true } >(); console.log(app); interface ICodeGenerator { /** * Generate Prisma AST application for database schema design. */ generatePrismaSchema(app: AutoBePrisma.IApplication): void; /** * Generate OpenAPI document for RESTful API design. */ generateOpenApiDocument(app: AutoBeOpenApi.IDocument): void; }

💻 Typia Playground Link

AST (Abstract Syntax Tree) structures are inherently recursive with infinite depth and countless union types. Therefore, creating AI function calling schemas for AST should never be done manually. It must be automatically generated by a compiler to ensure both stability and productivity.

The typia.llm.application<App, Model, Options>() function serves as the cornerstone of this approach. This powerful utility automatically generates comprehensive AI function calling schemas from TypeScript type definitions. By leveraging compile-time type analysis, it creates schemas that are not only type-safe but also include rich metadata and validation rules embedded directly in the type system.

The function supports multiple AI models through its generic parameters, allowing for model-specific optimizations and feature support. The options parameter enables fine-tuning of schema generation, including reference handling, description enrichment, and validation strictness. This compiler-driven approach eliminates the manual effort and potential errors associated with hand-crafted schemas while providing superior type safety and maintainability.

Comments over Prompts

@autobe/interface
export namespace AutoBePrisma { /** * Interface representing a single Prisma schema file within the application. * * Each file focuses on a specific business domain and contains related * models. File organization follows domain-driven design principles as seen * in the uploaded schemas. */ export interface IFile { /** * Name of the schema file to be generated. * * Should follow the naming convention: "schema-{number}-{domain}.prisma" * Examples: "schema-02-systematic.prisma", "schema-03-actors.prisma" The * number indicates the dependency order for schema generation. */ filename: string & tags.Pattern<"^[a-zA-Z0-9._-]+\\.prisma$">; /** * Business domain namespace that groups related models. * * Used in Prisma documentation comments as "@\namespace directive". * Examples from uploaded schemas: "Systematic", "Actors", "Sales", "Carts", * "Orders", "Coupons", "Coins", "Inquiries", "Favorites", "Articles" */ namespace: string; /** * Array of Prisma models (database tables) within this domain. * * Each model represents a business entity or concept within the namespace. * Models can reference each other through foreign key relationships. */ models: IModel[]; } /** * Interface representing a single Prisma model (database table). * * Based on the uploaded schemas, models follow specific patterns: * * - Main business entities (e.g., shopping_sales, shopping_customers) * - Snapshot/versioning entities for audit trails (e.g., * shopping_sale_snapshots) * - Junction tables for M:N relationships (e.g., * shopping_cart_commodity_stocks) * - Materialized views for performance (prefixed with mv_) */ export interface IModel { /** * Name of the Prisma model (database table name). * * Should follow snake_case convention with domain prefix. Examples: * "shopping_customers", "shopping_sale_snapshots", "bbs_articles" * Materialized views use "mv_" prefix: "mv_shopping_sale_last_snapshots" */ name: string & tags.Pattern<"^[a-z][a-z0-9_]*$">; /** * Detailed description explaining the business purpose and usage of the * model. * * Should include: * * - Business context and purpose * - Key relationships with other models * - Important behavioral notes or constraints * - References to related entities using "{@\link ModelName}" syntax Example: * "Customer information, but not a person but a **connection** basis..." */ description: string; /** * Indicates whether this model represents a materialized view for * performance optimization. * * Materialized views are read-only computed tables that cache complex query * results. They're marked as "@\hidden" in documentation and prefixed with * "mv_" in naming. Examples: mv_shopping_sale_last_snapshots, * mv_shopping_cart_commodity_prices */ material: boolean; //---- // FIELDS //---- /** * The primary key field of the model. * * In all uploaded schemas, primary keys are always UUID type with "@\id" * directive. Usually named "id" and marked with "@\db.Uuid" for PostgreSQL * mapping. */ primaryField: IPrimaryField; /** * Array of foreign key fields that reference other models. * * These establish relationships between models and include Prisma relation * directives. Can be nullable (optional relationships) or required * (mandatory relationships). May have unique constraints for 1:1 * relationships. */ foreignFields: IForeignField[]; /** * Array of regular data fields that don't reference other models. * * Include business data like names, descriptions, timestamps, flags, * amounts, etc. Common patterns: created_at, updated_at, deleted_at for * soft deletion and auditing. */ plainFields: IPlainField[]; //---- // INDEXES //---- /** * Array of unique indexes for enforcing data integrity constraints. * * Ensure uniqueness across single or multiple columns. Examples: unique * email addresses, unique codes within a channel, unique combinations like * (channel_id, nickname). */ uniqueIndexes: IUniqueIndex[]; /** * Array of regular indexes for query performance optimization. * * Speed up common query patterns like filtering by foreign keys, date * ranges, or frequently searched fields. Examples: indexes on created_at, * foreign key fields, search fields. */ plainIndexes: IPlainIndex[]; /** * Array of GIN (Generalized Inverted Index) indexes for full-text search. * * Used specifically for PostgreSQL text search capabilities using trigram * operations. Applied to text fields that need fuzzy matching or partial * text search. Examples: searching names, nicknames, titles, content * bodies. */ ginIndexes: IGinIndex[]; } }

@autobe invests significantly more effort in embedding coding rules as comments within the types used for AI function calling rather than relying on system prompts to enforce these rules.

This approach stems from a critical observation: AI models often fail to consistently follow system prompt rules, and these rules are frequently ignored entirely when context grows large. In contrast, description information written in function calling schemas is reliably followed by AI models. When AI generates information for a type specified through function calling, it references the type’s description information again, making type-level comments far more effective than system prompts in coding agents.

The AutoBePrisma.IFile and AutoBePrisma.IModel types exemplify this approach by meticulously documenting the rules that must be followed for each interface and property type. For example, the filename property must follow the schema-{number}-{domain}.prisma format, and when defining database models, the name property must use snake_case convention with domain prefixes like shopping_customers or bbs_articles. Each comment provides concrete examples and specific constraints that guide the AI toward generating compliant code structures.

This comment-driven approach ensures that coding rules are embedded directly where the AI encounters them during code generation, creating a more reliable and maintainable system than traditional prompt-based instruction methods.

Validation Feedback

@samchon/openapi
import { ILlmSchema } from "./ILlmSchema"; import { IValidation } from "./IValidation"; /** * LLM function metadata. * * `ILlmFunction` is an interface representing a function metadata, which has * been used for the LLM (Language Large Model) function calling. Also, it's a * function structure containing the function {@link name}, {@link parameters} and * {@link output return type}. * * If you provide this `ILlmFunction` data to the LLM provider like "OpenAI", * the "OpenAI" will compose a function arguments by analyzing conversations * with the user. With the LLM composed arguments, you can execute the function * and get the result. * * By the way, do not ensure that LLM will always provide the correct arguments. * The LLM of present age is not perfect, so that you would better to validate * the arguments before executing the function. I recommend you to validate the * arguments before execution by using * [`typia`](https://github.com/samchon/typia) library. * * @author Jeongho Nam - https://github.com/samchon * @template Model Type of the LLM model * @reference https://platform.openai.com/docs/guides/function-calling */ export interface ILlmFunction<Model extends ILlmSchema.Model> { /** * Representative name of the function. * * @maxLength 64 */ name: string; /** List of parameter types. */ parameters: ILlmSchema.ModelParameters[Model]; /** * Collection of separated parameters. * * Filled only when {@link ILlmApplication.IOptions.separate} is configured. */ separated?: ILlmFunction.ISeparated<Model>; /** * Expected return type. * * If the function returns nothing (`void`), the `output` value would be * `undefined`. */ output?: ILlmSchema.ModelSchema[Model]; /** * Description of the function. * * For reference, the `description` is very important property to teach the * purpose of the function to the LLM (Language Large Model), and LLM actually * determines which function to call by the description. * * Also, when the LLM conversates with the user, the `description` is used to * explain the function to the user. Therefore, the `description` property has * the highest priority, and you have to consider it. */ description?: string | undefined; /** * Whether the function is deprecated or not. * * If the `deprecated` is `true`, the function is not recommended to use. * * LLM (Large Language Model) may not use the deprecated function. */ deprecated?: boolean | undefined; /** * Category tags for the function. * * You can fill this property by the `@tag ${name}` comment tag. */ tags?: string[] | undefined; /** * Validate function of the arguments. * * You know what? LLM (Large Language Model) like OpenAI takes a lot of * mistakes when composing arguments in function calling. Even though `number` * like simple type is defined in the {@link parameters} schema, LLM often * fills it just by a `string` typed value. * * In that case, you have to give a validation feedback to the LLM by using * this `validate` function. The `validate` function will return detailed * information about every type errors about the arguments. * * And in my experience, OpenAI's `gpt-4o-mini` model tends to construct an * invalid function calling arguments at the first trial about 50% of the * time. However, if correct it through this `validate` function, the success * rate soars to 99% at the second trial, and I've never failed at the third * trial. * * > If you've {@link separated} parameters, use the * > {@link ILlmFunction.ISeparated.validate} function instead when validating * > the LLM composed arguments. * * > In that case, This `validate` function would be meaningful only when you've * > merged the LLM and human composed arguments by * > {@link HttpLlm.mergeParameters} function. * * @param args Arguments to validate * @returns Validation result */ validate: (args: unknown) => IValidation<unknown>; } export namespace ILlmFunction { /** Collection of separated parameters. */ export interface ISeparated<Model extends ILlmSchema.Model> { /** * Parameters that would be composed by the LLM. * * Even though no property exists in the LLM side, the `llm` property would * have at least empty object type. */ llm: ILlmSchema.ModelParameters[Model]; /** Parameters that would be composed by the human. */ human: ILlmSchema.ModelParameters[Model] | null; /** * Validate function of the separated arguments. * * If LLM part of separated parameters has some properties, this `validate` * function will be filled for the {@link llm} type validation. * * > You know what? LLM (Large Language Model) like OpenAI takes a lot of * > mistakes when composing arguments in function calling. Even though * > `number` like simple type is defined in the {@link parameters} schema, LLM * > often fills it just by a `string` typed value. * * > In that case, you have to give a validation feedback to the LLM by using * > this `validate` function. The `validate` function will return detailed * > information about every type errors about the arguments. * * > And in my experience, OpenAI's `gpt-4o-mini` model tends to construct an * > invalid function calling arguments at the first trial about 50% of the * > time. However, if correct it through this `validate` function, the * > success rate soars to 99% at the second trial, and I've never failed at * > the third trial. * * @param args Arguments to validate * @returns Validate result */ validate?: ((args: unknown) => IValidation<unknown>) | undefined; } }

Does AI function calling always produce type-valid AST data? The answer is no. AI frequently experiences hallucinations even during function calling, generating AST data that is not type-valid. To correct these AI errors, validation feedback must be provided back to the AI.

The typia.llm.application<App, Model, Options>() function used by @autobe to create AI function calling schemas for AST data includes a built-in runtime type checker specialized for AI validation feedback. This validator doesn’t just identify type violations; it generates detailed, AI-friendly error messages that help the model understand exactly what went wrong and how to fix it.

Even when AI function calling produces AST data that is type-correct, there are cases where the data fails to follow @autobe’s coding rules or contains contradictions that make conversion to programming code impossible. In these scenarios, @autobe’s custom-developed compiler’s built-in compilation feedback feature activates to assist in AI correction.

This dual-layer validation system ensures that both type safety and business rule compliance are maintained throughout the code generation process. The compiler-level feedback provides semantic validation beyond simple type checking, catching logical inconsistencies and rule violations that could lead to non-functional generated code.

By combining runtime type validation with semantic rule validation, @autobe creates a robust feedback loop that continuously improves AI output quality while maintaining the integrity of the generated codebase. This approach transforms potential AI hallucinations from fatal errors into learning opportunities, allowing the system to iteratively refine its output until it meets all requirements.

Last updated on