{"id":12037,"date":"2025-10-09T17:12:53","date_gmt":"2025-10-09T08:12:53","guid":{"rendered":"https:\/\/sreake.com\/?p=12037"},"modified":"2026-02-10T16:15:09","modified_gmt":"2026-02-10T07:15:09","slug":"typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2","status":"publish","type":"post","link":"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/","title":{"rendered":"Type-Safe AI Integration Patterns with the Instructor Library and Clean Architecture"},"content":{"rendered":"\n<p><em><em>This blog post is a translation of\u00a0<a href=\"https:\/\/sreake.com\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture\/\" title=\"\">a Japanese article<\/a>\u00a0posted on September 29th, 2025.<\/em><\/em><\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_75 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Introduction\" >Introduction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Technology_Stack_and_Overall_Design\" >Technology Stack and Overall Design<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Technologies_Used\" >Technologies Used<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Architecture_Overview\" >Architecture Overview<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Core_Design_Patterns\" >Core Design Patterns<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#1_Encapsulating_AI_Processing_within_Domain_Entities\" >1. Encapsulating AI Processing within Domain Entities<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#2_Standardization_through_a_Unified_Interface\" >2. Standardization through a Unified Interface<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Detailed_Type_Definitions\" >Detailed Type Definitions<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#3_Implementation_Example_Business_Analysis_Entity\" >3. Implementation Example: Business Analysis Entity<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#4_Type-Safe_AI_Service_Layer\" >4. Type-Safe AI Service Layer<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Benefits_of_Implementation\" >Benefits of Implementation<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#1_Achieving_Type_Safety\" >1. Achieving Type Safety<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#2_Flexible_Processing_Based_on_Context\" >2. Flexible Processing Based on Context<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#3_Improved_Testability\" >3. Improved Testability<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#4_Scalability_and_Maintainability\" >4. Scalability and Maintainability<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Error_Handling_and_Retry_Functionality\" >Error Handling and Retry Functionality<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/sreake.com\/en\/blog\/typesafe-ai-integration-pattern-with-instructor-library-and-clean-architecture-2\/#Reference_Links\" >Reference Links<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In recent years, the integration of AI functionalities into business applications has been rapidly increasing. However, since the output of AI is inherently uncertain, maintaining the type safety and maintainability valued in traditional web application development has become a challenge.<\/p>\n\n\n\n<p>This article introduces a method for achieving a type-safe and highly maintainable AI integration pattern by combining the <strong>Instructor library<\/strong> with <strong>Clean Architecture<\/strong>. We will focus on best practices I&#8217;ve devised for utilizing AI in applications with complex business logic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Technology_Stack_and_Overall_Design\"><\/span>Technology Stack and Overall Design<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Technologies_Used\"><\/span>Technologies Used<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>@instructor-ai\/instructor<\/strong>: For handling structured AI outputs in a type-safe manner.<\/li><li><strong>OpenAI API<\/strong>: Using LLMs like GPT-4 or Gemini.<\/li><li><strong>Zod<\/strong>: For schema definition and validation.<\/li><li><strong>TypeScript<\/strong>: To ensure type safety.<\/li><li><strong>Clean Architecture<\/strong>: For layer separation and domain-centric design.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Architecture_Overview\"><\/span>Architecture Overview<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sreake.com\/wp-content\/uploads\/2025\/10\/Architecture_TypeSafeAIIntegration-PatternsWithTheInstructorLibraryAndCleanArchitecture-1-938x1024.png\" alt=\"\" class=\"wp-image-12044\" width=\"469\" height=\"512\"\/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Core_Design_Patterns\"><\/span>Core Design Patterns<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Encapsulating_AI_Processing_within_Domain_Entities\"><\/span>1. Encapsulating AI Processing within Domain Entities<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>By concentrating all responsibility for AI processing within domain entities, we increase the cohesion between business logic and AI processing, minimizing external dependencies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Standardization_through_a_Unified_Interface\"><\/span>2. Standardization through a Unified Interface<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Detailed_Type_Definitions\"><\/span>Detailed Type Definitions<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>\/\/ Type definition for the AI execution context\nexport interface AIExecutionContext {\n  userInput: string;\n  attachedFileUrls?: string&#91;];\n  previousResults?: Record&lt;string, any>;\n  sessionContext?: Record&lt;string, any>;\n}\n\n\/\/ Type definition for AI configuration\nexport interface AIConfig {\n  model: string;         \/\/ Model name to use\n  temperature: number;   \/\/ Creativity of generation (0-1)\n  max_retries: number;   \/\/ Maximum number of retries\n  timeout: number;       \/\/ Timeout (in milliseconds)\n}\n\n\/\/ Unified interface for AI-processable entities\nexport interface AIProcessableEntity {\n  \/**\n   * Gets the Zod schema that defines the structure of the AI output.\n   * @returns A Zod schema for validating the AI output.\n   *\/\n  getZodSchema(): z.ZodSchema&lt;any>;\n\n  \/**\n   * Generates the prompt for AI processing.\n   * @param context The AI execution context.\n   * @returns The generated prompt string.\n   *\/\n  generatePrompt(context: AIExecutionContext): string;\n\n  \/**\n   * Gets the configuration for AI processing.\n   * @returns The configuration object for AI processing.\n   *\/\n  getAIConfig(): AIConfig;\n\n  \/**\n   * Builds the context string for the AI.\n   * @param context The AI execution context.\n   * @returns The context string to be used for AI processing.\n   *\/\n  getContextForAI(context: AIExecutionContext): string;\n\n  \/**\n   * Parses the AI output and updates the entity's state.\n   * @param aiResponse The response from the AI API.\n   * @param userInput The input from the user.\n   * @param attachedFileUrls An array of attached file URLs.\n   *\/\n  parseFromAIResponse(\n    aiResponse: any,\n    userInput: string,\n    attachedFileUrls?: string&#91;]\n  ): void;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Implementation_Example_Business_Analysis_Entity\"><\/span>3. Implementation Example: Business Analysis Entity<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>\/\/ Output type definition for business recommendations\nexport interface BusinessAnalysisResponse {\n  recommendations: Array&lt;{\n    id: string;\n    title: string;\n    description: string;\n    priority: number;\n    reasoning: string;\n  }>;\n  metadata: {\n    analysisApproach: string;\n    keyInsights: string&#91;];\n    confidence: number;\n  };\n}\n\n\/\/ Business analysis entity implementing the unified interface\nexport class BusinessAnalysisEntity implements AIProcessableEntity {\n  private recommendations: BusinessAnalysisResponse&#91;'recommendations'] = &#91;];\n  private metadata?: BusinessAnalysisResponse&#91;'metadata'];\n  private userInput = '';\n  private attachedFiles: string&#91;] = &#91;];\n\n  getZodSchema(): z.ZodSchema&lt;BusinessAnalysisResponse> {\n    return z.object({\n      recommendations: z.array(\n        z.object({\n          id: z.string().describe(\"Recommendation ID\"),\n          title: z.string().min(5).max(100).describe(\"Recommendation title\"),\n          description: z.string().min(50).max(300).describe(\"Detailed description\"),\n          priority: z.number().min(1).max(5).describe(\"Priority\"),\n          reasoning: z.string().min(20).max(200).describe(\"Reason for recommendation\")\n        })\n      ).min(3).max(8).describe(\"Business recommendations\"),\n      metadata: z.object({\n        analysisApproach: z.string().describe(\"Analysis approach\"),\n        keyInsights: z.array(z.string()).describe(\"Key insights\"),\n        confidence: z.number().min(0).max(1).describe(\"Confidence score\")\n      }).describe(\"Metadata\")\n    });\n  }\n\n  generatePrompt(context: AIExecutionContext): string {\n    return `\nYou are a business analysis expert.\n\n## Context\nUser Input: ${context.userInput}\nAttached Files: ${context.attachedFileUrls?.join(', ') || 'None'}\nPrevious Results: ${JSON.stringify(context.previousResults) || 'None'}\n\n## Instructions\nProvide structured recommendations based on the following requirements.\n\n## Output Requirements\n- Provide actionable and specific recommendations.\n- Show clear reasoning for each recommendation.\n- Prioritize the recommendations to clarify implementation order.\n    `;\n  }\n\n  getAIConfig(): AIConfig {\n    return {\n      model: \"gpt-4\",\n      temperature: 0.1,\n      max_retries: 3,\n      timeout: 30000\n    };\n  }\n\n  getContextForAI(context: AIExecutionContext): string {\n    return `\nUser Input: ${context.userInput}\nAttached Files: ${context.attachedFileUrls?.join(', ') || 'None'}\nPrevious Results: ${JSON.stringify(context.previousResults) || 'None'}\n    `;\n  }\n\n  parseFromAIResponse(\n    aiResponse: BusinessAnalysisResponse,\n    userInput: string,\n    attachedFileUrls?: string&#91;]\n  ): void {\n    \/\/ Validate the AI response\n    const schema = this.getZodSchema();\n    const validated = schema.parse(aiResponse);\n\n    \/\/ Update the entity's state\n    this.recommendations = validated.recommendations;\n    this.metadata = validated.metadata;\n    this.userInput = userInput;\n    this.attachedFiles = attachedFileUrls || &#91;];\n  }\n\n  \/\/ Additional domain methods\n  getPublicResult() {\n    return {\n      recommendations: this.recommendations,\n      metadata: this.metadata\n    };\n  }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"4_Type-Safe_AI_Service_Layer\"><\/span>4. Type-Safe AI Service Layer<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Let\u2019s Implement an integration service layer that acts as a bridge between the domain entities and the Instructor client<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>export class UnifiedAIService {\n  constructor(\n    private instructorClient: InstructorClient,\n    private logger: Logger\n  ) {}\n\n  async processWithEntity&lt;T>(\n    entity: AIProcessableEntity,\n    context: AIExecutionContext\n  ): Promise&lt;T> {\n    try {\n      const prompt = entity.generatePrompt(context);\n      const schema = entity.getZodSchema();\n      const config = entity.getAIConfig();\n\n      const result = await this.instructorClient.chat.completions.create({\n        messages: &#91;{ role: \"user\", content: prompt }],\n        model: config.model,\n        temperature: config.temperature,\n        max_retries: config.max_retries,\n        response_model: {\n          schema: schema,\n          name: `${entity.constructor.name}Response`\n        }\n      });\n\n      \/\/ Update the entity's state\n      entity.parseFromAIResponse(\n        result,\n        context.userInput,\n        context.attachedFileUrls\n      );\n\n      return result as T;\n    } catch (error) {\n      this.logger.error('AI processing failed', {\n        error,\n        entity: entity.constructor.name\n      });\n      throw new AIProcessingError('Failed to process AI request', error);\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Benefits_of_Implementation\"><\/span>Benefits of Implementation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Achieving_Type_Safety\"><\/span>1. Achieving Type Safety<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The combination of Zod schemas and TypeScript type definitions enables consistent type safety from the AI output to its use within the application.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>\/\/ The result of AI processing is completely type-safe\nconst result: BusinessAnalysisResponse = await aiService.processWithEntity(\n  entity,\n  context\n);\n\n\/\/ IDE autocompletion works\nconsole.log(result.recommendations&#91;0].title); \/\/ \u2705 Type-safe\nconsole.log(result.invalidProperty); \/\/ \u274c Compile error<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Flexible_Processing_Based_on_Context\"><\/span>2. Flexible Processing Based on Context<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Prompts can be dynamically adjusted based on the information in the execution context (user input, attached files, previous results, etc.).<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>const context: AIExecutionContext = {\n  userInput: \"How can we improve sales?\",\n  attachedFileUrls: &#91;\"&lt;https:\/\/example.com\/sales-data.xlsx>\"],\n  previousResults: { lastAnalysis: \"marketing focus needed\" }\n};\n\n\/\/ Context information is automatically reflected in the prompt\nconst prompt = entity.generatePrompt(context);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Improved_Testability\"><\/span>3. Improved Testability<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Since each domain entity manages its AI processing in a self-contained manner, unit testing with mocks becomes easier.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>describe('BusinessAnalysisEntity', () => {\n  it('should generate appropriate schema', () => {\n    const entity = new BusinessAnalysisEntity();\n    const schema = entity.getZodSchema();\n\n    expect(schema.shape.recommendations).toBeDefined();\n    expect(schema.shape.metadata).toBeDefined();\n  });\n\n  it('should parse AI response correctly', () => {\n    const entity = new BusinessAnalysisEntity();\n    const mockResponse: BusinessAnalysisResponse = {\n      recommendations: &#91;\n        {\n          id: \"1\",\n          title: \"Test Recommendation\",\n          description: \"This is a test recommendation with a detailed description.\",\n          priority: 3,\n          reasoning: \"For testing purposes\"\n        }\n      ],\n      metadata: {\n        analysisApproach: \"Test Analysis\",\n        keyInsights: &#91;\"Insight 1\"],\n        confidence: 0.8\n      }\n    };\n\n    entity.parseFromAIResponse(mockResponse, \"Test input\");\n    const result = entity.getPublicResult();\n\n    expect(result.recommendations).toHaveLength(1);\n    expect(result.metadata?.confidence).toBe(0.8);\n  });\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"4_Scalability_and_Maintainability\"><\/span>4. Scalability and Maintainability<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>When new AI processing is required, you can respond simply by adding a new domain entity without impacting existing code.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>\/\/ Output type definition for new business requirements\nexport interface RiskAnalysisResponse {\n  analysis: {\n    summary: string;\n    riskLevel: 'low' | 'medium' | 'high';\n    recommendations: string&#91;];\n  };\n  actionItems: Array&lt;{\n    id: string;\n    action: string;\n    deadline: string;\n    assignee?: string;\n  }>;\n}\n\n\/\/ Entity for the new business requirement\nexport class RiskAnalysisEntity implements AIProcessableEntity {\n  getZodSchema(): z.ZodSchema&lt;RiskAnalysisResponse> {\n    return z.object({\n      analysis: z.object({\n        summary: z.string().min(50).max(500).describe(\"Analysis summary\"),\n        riskLevel: z.enum(&#91;'low', 'medium', 'high']).describe(\"Risk level\"),\n        recommendations: z.array(z.string()).min(1).max(10).describe(\"Recommendations\")\n      }).describe(\"Analysis results\"),\n      actionItems: z.array(\n        z.object({\n          id: z.string().describe(\"Action item ID\"),\n          action: z.string().min(10).max(200).describe(\"Action to be taken\"),\n          deadline: z.string().describe(\"Deadline\"),\n          assignee: z.string().optional().describe(\"Assignee\")\n        })\n      ).min(1).max(20).describe(\"Action items\")\n    });\n  }\n\n  generatePrompt(context: AIExecutionContext): string {\n    return `\nYou are a business strategy advisor.\n\n## Subject of Analysis\n${context.userInput}\n\n## Output Requirements\n- Appropriately assess the risk level.\n- Propose specific and actionable items.\n- Set realistic deadlines.\n    `;\n  }\n\n  getAIConfig(): AIConfig {\n    return {\n      model: \"gpt-4-turbo\",\n      temperature: 0.2,\n      max_retries: 5,\n      timeout: 45000\n    };\n  }\n\n  getContextForAI(context: AIExecutionContext): string {\n    return `\nUser Input: ${context.userInput}\nAttached Files: ${context.attachedFileUrls?.join(', ') || 'None'}\nSession Info: ${JSON.stringify(context.sessionContext) || 'None'}\n    `;\n  }\n\n  parseFromAIResponse(\n    aiResponse: RiskAnalysisResponse,\n    userInput: string,\n    attachedFileUrls?: string&#91;]\n  ): void {\n    const schema = this.getZodSchema();\n    const validated = schema.parse(aiResponse);\n\n    \/\/ Entity-specific state update logic\n    \/\/ ... implementation details\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Error_Handling_and_Retry_Functionality\"><\/span>Error Handling and Retry Functionality<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let\u2019s Implement robust error handling by combining it with the self-correction feature of the Instructor library.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>export class AIErrorHandler {\n  async handleAIProcessing&lt;T>(\n    processingFn: () => Promise&lt;T>,\n    entity: AIProcessableEntity,\n    context: AIExecutionContext\n  ): Promise&lt;T> {\n    try {\n      return await processingFn();\n    } catch (error) {\n      if (error instanceof ValidationError) {\n        \/\/ For schema validation errors\n        this.logger.warn('Schema validation failed, retrying with adjusted prompt', {\n          entity: entity.constructor.name,\n          error: error.message\n        });\n\n        throw new AIValidationError('Invalid AI output format', error);\n      } else if (error instanceof RateLimitError) {\n        \/\/ For rate limit errors\n        await this.waitForRateLimit();\n        throw new AIRateLimitError('API rate limit reached', error);\n      } else {\n        \/\/ For other errors\n        throw new AIProcessingError('An error occurred during AI processing', error);\n      }\n    }\n  }\n\n  private async waitForRateLimit(): Promise&lt;void> {\n    const waitTime = Math.random() * 5000 + 1000; \/\/ Random wait between 1-6 seconds\n    await new Promise(resolve => setTimeout(resolve, waitTime));\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Adopting the architecture introduced in this article rewards you with:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>Type Safety<\/strong>: Consistent type safety from AI output throughout the application.<\/li><li><strong>Maintainability<\/strong>: Clear separation of responsibilities through domain entities.<\/li><li><strong>Scalability<\/strong>: Ease of adding new features via a unified interface.<\/li><li><strong>Testability<\/strong>: Simplified testing due to component independence.<\/li><li><strong>Reusability<\/strong>: Application of standardized patterns to other projects.<\/li><li><strong>Flexibility<\/strong>: Dynamic prompt generation based on context.<\/li><\/ol>\n\n\n\n<p>When integrating AI into complex business applications, it is crucial to carefully consider the architecture-level design, rather than simply calling an API. The combination of the Instructor library and appropriate architectural patterns enables an AI integration that balances maintainability and scalability.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Reference_Links\"><\/span>Reference Links<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/567-labs\/instructor\">Instructor GitHub<\/a><\/li><li><a href=\"https:\/\/blog.cleancoder.com\/uncle-bob\/2012\/08\/13\/the-clean-architecture.html\">Clean Archeticture<\/a><\/li><li><a href=\"https:\/\/zod.dev\/\">Zod Documentation<\/a><\/li><li><a href=\"https:\/\/platform.openai.com\/docs\">OpenAI API Documentation<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hi from the Sreake team! Learn how to use Instructor and integrate it into Clean Architecture projects to ensure type-safe AI responses<\/p>\n","protected":false},"author":45,"featured_media":12875,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_locale":"en_US","_original_post":"https:\/\/sreake.com\/?p=11880","footnotes":""},"categories":[17],"tags":[23],"class_list":["post-12037","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-enginner-blog","en-US"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12037","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/users\/45"}],"replies":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/comments?post=12037"}],"version-history":[{"count":1,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12037\/revisions"}],"predecessor-version":[{"id":12876,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12037\/revisions\/12876"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media\/12875"}],"wp:attachment":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media?parent=12037"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/categories?post=12037"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/tags?post=12037"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}