Back to "LLMApi: OpenAPI Dynamic Mock Generator: Φορτώστε οποιοδήποτε Spec, Mock Any API"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

AI AI-Article API ASP.NET Core LLM LLMApi mockllmapi Nuget SignalR

LLMApi: OpenAPI Dynamic Mock Generator: Φορτώστε οποιοδήποτε Spec, Mock Any API

Wednesday, 05 November 2025

ΣΗΜΕΙΩΣΗ: Αυτό το άρθρο παράγεται κατά κύριο λόγο ως μέρος του πακέτου Nuget μου ως έγγραφα απελευθέρωσης.

Είναι πολύ ενδιαφέρον γι' αυτό το έβαλα εδώ, αλλά αν αυτό είναι πρόβλημα για σένα, σε παρακαλώ, αγνόησέ το.

Εισαγωγή

Χρειαζόσουν ποτέ να δοκιμάσεις ένα API που δεν ήταν έτοιμο ακόμα;

Ή ήθελες να αναπτυχθείς εκτός σύνδεσης χωρίς να χτυπήσεις τα όρια; Η γεννήτρια OpenAPI Dynamic Mock σας επιτρέπει να φορτώσετε οποιαδήποτε προδιαγραφή OpenAPI και δημιουργεί άμεσα ένα πλήρως λειτουργικό mock API με ρεαλιστικά δεδομένα LLM.

Δεν υπάρχουν αρχεία ρυθμίσεων.Δεν υπάρχει χειροκίνητη δημιουργία τελικού σημείου.Απλά δείξε το σε ένα OpenAPI spec και άρχισε να κάνεις αιτήσεις.

NuGetCity name (optional, probably does not need a translation)

NuGetCity name (optional, probably does not need a translation)

Μπορείτε να βρείτε το

graph TD
    A[Your App] --> B{External API}
    B -->|Not Ready| C[Development Blocked]
    B -->|Rate Limited| D[Can't Test Freely]
    B -->|Requires Auth| E[Complex Setup]
    B -->|Expensive| F[Cost Concerns]
    B -->|Unreliable| G[Flaky Tests]

GitHub εδώ

  • για το έργο, όλος ο δημόσιος τομέας κ.λπ...
  • Διευθυντής OpenApi
  • Το πρόβλημα: API Εξαρτήσεις Ανάπτυξη μπλοκ

Οι σύγχρονες εφαρμογές εξαρτώνται από δεκάδες εξωτερικούς APIs.

Κατά τη διάρκεια της ανάπτυξης, αντιμετωπίζετε διάφορες προκλήσεις:

  1. Οι παραδοσιακές λύσεις περιλαμβάνουν:
  2. Γράφοντας χειρωνακτικά παρωδία απαντήσεις (βαρετό, γίνεται ξεπερασμένη)
  3. Καταγραφή/επαναπαραγωγή κυκλοφορίας HTTP (βρώμικο, δύσκολο να διατηρηθεί)
  4. Χρησιμοποιώντας σκληροκωδικοποιημένα εξαρτήματα (μη ρεαλιστικά, δεν καλύπτει θήκες άκρων)
sequenceDiagram
    participant Dev as Developer
    participant System as Mock System
    participant Spec as OpenAPI Spec
    participant LLM as Local LLM

    Dev->>System: Load spec from URL/file
    System->>Spec: Parse OpenAPI document
    Spec-->>System: Endpoints, schemas, descriptions
    System->>System: Register dynamic routes

    Dev->>System: GET /petstore/pet/123
    System->>LLM: Generate data for "Pet" schema
    LLM-->>System: Realistic pet data
    System-->>Dev: {"id": 123, "name": "Max", ...}

Η λύση: Δυναμική OpenAPI Mocking

Σημειώστε το σύστημα σε οποιοδήποτε OpenAPI spec, και αυτόματα:

Χαρακτηρίζει τις προδιαγραφές

graph TB
    A[HTTP Request] --> B{Route Matches?}
    B -->|No| C[404 Not Found]
    B -->|Yes| D[DynamicOpenApiManager]
    D --> E[Find Matching Endpoint]
    E --> F[OpenApiRequestHandler]
    F --> G[Extract Schema from Spec]
    G --> H[Build LLM Prompt]
    H --> I[PromptBuilder]
    I --> J[Include Context?]
    J -->|Yes| K[OpenApiContextManager]
    J -->|No| L[LLM Client]
    K --> L
    L --> M[Get Response]
    M --> N[JsonExtractor]
    N --> O[Return Mock Data]

Ανακαλύπτει όλα τα τελικά σημεία

  1. Δημιουργεί ρεαλιστικά δεδομένα mocking χρησιμοποιώντας ένα LLMΣερβίρει το mock API στην τοπική μηχανή σας
  2. Πώς ΛειτουργείΑρχιτεκτονική επισκόπηση
  3. **Το σύστημα OpenAPI αποτελείται από διάφορα συντονισμένα στοιχεία:**Βασικά συστατικά:
  4. DynamicOpenApiManager- Διαχείριση φορτωμένων προδιαγραφών και ταίριασμα διαδρομής
  5. OpenApiSpecLoader- Βυζιά και παρθένες έγγραφα OpenAPI

OpenApiRequestHandler

  • Δημιουργεί ανταποκρίσεις για τα αντίστοιχα τελικά σημεία

PromptBuilder

POST /api/openapi/specs
Content-Type: application/json

{
  "name": "petstore",
  "source": "https://petstore3.swagger.io/api/v3/openapi.json",
  "basePath": "/petstore"
}

- Δημιουργεί κίνητρα LLM από τα σχήματα OpenAPI

POST /api/openapi/specs
Content-Type: application/json

{
  "name": "my-api",
  "source": "./specs/my-api.yaml",
  "basePath": "/api/v1"
}

OpenApiContextManager

POST /api/openapi/specs
Content-Type: application/json

{
  "name": "inline-api",
  "source": "data:application/json;base64,eyJvcGVuYXBpIjoiMy...",
  "basePath": "/api"
}

- Διατηρεί συνέπεια σε όλες τις κλήσεις (προαιρετικά)

Προδιαγραφές φόρτωσης

public async Task<SpecLoadResult> LoadSpecAsync(
    string name,
    string source,
    string? basePath = null,
    string? contextName = null)
{
    // 1. Use scoped service factory for OpenApiSpecLoader
    using var scope = _scopeFactory.CreateScope();
    var specLoader = scope.ServiceProvider
        .GetRequiredService<OpenApiSpecLoader>();

    // 2. Load the OpenAPI document
    var document = await specLoader.LoadSpecAsync(source);

    // 3. Determine base path from spec or parameter
    var effectiveBasePath = basePath
        ?? document.Servers?.FirstOrDefault()?.Url
        ?? "/api";

    // 4. Store spec with configuration
    var config = new OpenApiSpecConfig
    {
        Name = name,
        Source = source,
        Document = document,
        BasePath = effectiveBasePath,
        ContextName = contextName,
        LoadedAt = DateTimeOffset.UtcNow
    };

    _specs.AddOrUpdate(name, config, (_, __) => config);

    // 5. Notify listeners via SignalR
    await NotifySpecLoaded(name, effectiveBasePath);

    return new SpecLoadResult
    {
        Name = name,
        BasePath = effectiveBasePath,
        EndpointCount = CountEndpoints(document),
        Success = true
    };
}

Τα spec μπορούν να φορτωθούν από τρεις πηγές:

public OpenApiEndpointMatch? FindMatchingEndpoint(string path, string method)
{
    // Try each loaded spec
    foreach (var spec in _specs.Values)
    {
        // Remove base path prefix
        var relativePath = path;
        if (path.StartsWith(spec.BasePath))
        {
            relativePath = path.Substring(spec.BasePath.Length);
        }

        // Find matching path in OpenAPI document
        var (pathTemplate, operation) = FindOperation(
            spec.Document,
            relativePath,
            method);

        if (operation != null)
        {
            return new OpenApiEndpointMatch
            {
                Spec = spec,
                PathTemplate = pathTemplate,
                Operation = operation,
                Method = ParseMethod(method)
            };
        }
    }

    return null;
}

Απομακρυσμένη URLName

public async Task<string> HandleRequestAsync(
    HttpContext context,
    OpenApiDocument document,
    string path,
    OperationType method,
    OpenApiOperation operation,
    string? contextName = null,
    CancellationToken cancellationToken = default)
{
    // 1. Extract request body
    var requestBody = await ReadRequestBodyAsync(context.Request);

    // 2. Get success response schema
    var shape = ExtractResponseSchema(operation);

    // 3. Get context history if using contexts
    var contextHistory = !string.IsNullOrWhiteSpace(contextName)
        ? _contextManager.GetContextForPrompt(contextName)
        : null;

    // 4. Build prompt from OpenAPI metadata
    var description = operation.Summary ?? operation.Description;
    var prompt = _promptBuilder.BuildPrompt(
        method.ToString(),
        path,
        requestBody,
        new ShapeInfo { Shape = shape },
        streaming: false,
        description: description,
        contextHistory: contextHistory);

    // 5. Get response from LLM
    var rawResponse = await _llmClient.GetCompletionAsync(
        prompt,
        cancellationToken);

    // 6. Extract clean JSON
    var jsonResponse = JsonExtractor.ExtractJson(rawResponse);

    // 7. Store in context if configured
    if (!string.IsNullOrWhiteSpace(contextName))
    {
        _contextManager.AddToContext(
            contextName,
            method.ToString(),
            path,
            requestBody,
            jsonResponse);
    }

    return jsonResponse;
}

Τοπικό αρχείο

private string? ExtractResponseSchema(OpenApiOperation operation)
{
    // Look for successful response (2xx)
    var successResponse = operation.Responses
        .FirstOrDefault(r => r.Key.StartsWith("2"))
        .Value;

    if (successResponse == null)
        return null;

    // Get JSON content
    var jsonContent = successResponse.Content
        .FirstOrDefault(c => c.Key.Contains("json"))
        .Value;

    if (jsonContent?.Schema == null)
        return null;

    // Convert OpenAPI schema to JSON Schema
    return ConvertToJsonSchema(jsonContent.Schema);
}

private string ConvertToJsonSchema(OpenApiSchema schema)
{
    // Recursively build JSON Schema representation
    var builder = new StringBuilder();
    builder.Append("{");

    if (schema.Type != null)
    {
        builder.Append($"\"type\":\"{schema.Type}\"");
    }

    if (schema.Properties?.Count > 0)
    {
        builder.Append(",\"properties\":{");
        var props = schema.Properties
            .Select(p => $"\"{p.Key}\":{ConvertToJsonSchema(p.Value)}");
        builder.Append(string.Join(",", props));
        builder.Append("}");
    }

    if (schema.Items != null)
    {
        builder.Append(",\"items\":");
        builder.Append(ConvertToJsonSchema(schema.Items));
    }

    builder.Append("}");
    return builder.ToString();
}

URL δεδομένων (κωδικοποιημένο Base64)

Διαδικασία φόρτωσης Spec

Εδώ είναι τι συμβαίνει όταν φορτώνετε μια προδιαγραφή:

Δυναμική διαδρομή που ταιριάζει

POST /api/openapi/specs
Content-Type: application/json

{
  "name": "petstore",
  "source": "https://petstore3.swagger.io/api/v3/openapi.json",
  "basePath": "/petstore"
}

Όταν ένα αίτημα φτάσει, το σύστημα το ταιριάζει με όλες τις φορτωμένες προδιαγραφές:

{
  "name": "petstore",
  "basePath": "/petstore",
  "endpointCount": 19,
  "endpoints": [
    {"path": "/petstore/pet", "method": "POST"},
    {"path": "/petstore/pet/{petId}", "method": "GET"},
    {"path": "/petstore/pet/findByStatus", "method": "GET"},
    ...
  ],
  "success": true
}

Αίτημα χειρισμού

Μόλις βρεθεί ένα αντίστοιχο τελικό σημείο, ο χειριστής δημιουργεί μια απόκριση:

### Get a pet by ID
GET /petstore/pet/123

### Response (auto-generated):
{
  "id": 123,
  "name": "Max",
  "category": {
    "id": 1,
    "name": "Dogs"
  },
  "photoUrls": [
    "https://example.com/max1.jpg"
  ],
  "tags": [
    {"id": 1, "name": "friendly"},
    {"id": 2, "name": "trained"}
  ],
  "status": "available"
}
### Find pets by status
GET /petstore/pet/findByStatus?status=available

### Response (auto-generated array):
[
  {
    "id": 42,
    "name": "Buddy",
    "status": "available",
    ...
  },
  {
    "id": 43,
    "name": "Luna",
    "status": "available",
    ...
  }
]

Εξαγωγή Schema

GET /api/openapi/specs/petstore

### Shows full details:
### - All endpoints
### - Load time
### - Context configuration
### - Base path

Τα σχήματα απόκρισης του συστήματος αποσπώνται από τους ορισμούς OpenAPI:

POST /api/openapi/specs/petstore/reload

Πραγματική Παγκόσμια Χρήση

DELETE /api/openapi/specs/petstore

Παράδειγμα: Petstore API

Ας περπατήσουμε χλευάζοντας το κλασικό Petstore API:

### Load Petstore at /petstore
POST /api/openapi/specs
{"name": "petstore", "source": "...", "basePath": "/petstore"}

### Load GitHub API at /github
POST /api/openapi/specs
{"name": "github", "source": "...", "basePath": "/github"}

### Load Stripe API at /stripe
POST /api/openapi/specs
{"name": "stripe", "source": "...", "basePath": "/stripe"}

### All three APIs now available simultaneously:
GET /petstore/pet/123
GET /github/users/octocat
GET /stripe/customers/cus_123

Βήμα 1: Φορτώστε το Spec

Απάντηση:

POST /api/openapi/specs
Content-Type: application/json

{
  "name": "petstore",
  "source": "https://petstore3.swagger.io/api/v3/openapi.json",
  "basePath": "/petstore",
  "contextName": "petstore-session"
}

Βήμα 2: Χρησιμοποιήστε τα Endpoints Mock

### Create a pet
POST /petstore/pet
{"name": "Max", "status": "available"}

### Response: {"id": 42, "name": "Max", "status": "available"}

### Get the pet (will reference same ID and name)
GET /petstore/pet/42

### Response: {"id": 42, "name": "Max", "status": "available"}
### Notice: Consistent ID and name from context

Τώρα και τα 19 τελικά σημεία είναι διαθέσιμα:

Βήμα 3: Επιθεωρήστε το Spec

POST /api/openapi/test
Content-Type: application/json

{
  "specName": "petstore",
  "path": "/pet/123",
  "method": "GET"
}

### Returns mock response without affecting routes

Βήμα 4: Ξαναγεμίστε αν αλλάζει Spec

  • Βήμα 5: Αφαίρεση όταν γίνει
  • Πολλαπλά Spec Ταυτόχρονα
  • Μπορείτε να φορτώσετε πολλαπλές προδιαγραφές ταυτόχρονα, το καθένα με τη δική του βασική διαδρομή:

Specs με πλαίσια

Για ακόμα περισσότερο ρεαλισμό, θέστε ένα πλαίσιο σε ένα spec:http://localhost:5116/OpenApi:

graph TD
    A[OpenAPI Manager UI] --> B[Load Spec Section]
    A --> C[Spec List]
    A --> D[Context Viewer]

    B --> E[URL Input]
    B --> F[JSON Input]
    B --> G[Context Configuration]

    C --> H[Spec Card]
    H --> I[Reload Button]
    H --> J[Delete Button]
    H --> K[View Endpoints]

    D --> L[Active Contexts]
    L --> M[Context Details]
    L --> N[Clear Context]

Τώρα όλα τα τελικά σημεία του petstore έχουν το ίδιο πλαίσιο:

  • Σημείο δοκιμήςΤο τελικό σημείο της δοκιμής σας επιτρέπει να δοκιμάσετε ένα τελικό σημείο χωρίς να κάνετε ένα πραγματικό αίτημα:
  • **Αυτό είναι χρήσιμο για:**Προεπισκόπηση των απαντήσεων πριν από την ενσωμάτωση
  • Ειδικά τελικά σημεία δοκιμής σε απομόνωσηΑποσφαλμάτωση προβλημάτων σχεδίασης
  • Διαχείριση UIΓια οπτική διαχείριση, επίσκεψη
  • **Χαρακτηριστικά:**Σύρσιμο και πτώση
  • spec file uploadΑνακάλυψη ζωντανού τελικού σημείου

- Δείτε όλα τα τελικά σημεία αμέσως

Δοκιμή ενός κλικ

  • Δοκιμάστε οποιοδήποτε τελικό σημείο με ένα κουμπί
# OpenAPI Spec
/pet/{petId}:
  get:
    parameters:
      - name: petId
        in: path
        schema:
          type: integer
GET /petstore/pet/123
### LLM receives: "Generate data for Pet with petId=123"
### Response: {"id": 123, ...}

Κοινοποιήσεις σε πραγματικό χρόνο

  • Ενημερώσεις Signer όταν specs φορτίο
/pet/findByStatus:
  get:
    parameters:
      - name: status
        in: query
        schema:
          type: string
          enum: [available, pending, sold]
GET /petstore/pet/findByStatus?status=available
### LLM receives: "Generate array of Pets with status=available"
### Response: [{"status": "available", ...}, ...]

Ανάδειξη σύνταξης@ info: whatsthis

  • Όμορφη οθόνη απόκρισης JSON
/pet:
  post:
    requestBody:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'
POST /petstore/pet
Content-Type: application/json

{"name": "Max", "status": "available"}

### LLM receives: "Generate response for creating Pet with name=Max, status=available"
### Response: {"id": 42, "name": "Max", "status": "available"}

Διαχείριση πλαισίου

  • Προβολή και σαφή πλαίσια
/pet/{petId}:
  get:
    summary: Find pet by ID
    description: Returns a single pet based on the ID provided

Προχωρημένα χαρακτηριστικά

Παράμετρος διαδρομής

Οι παράμετροι διαδρομής εξάγονται αυτόματα:

responses:
  '200':
    description: Successful operation
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/Pet'
  '404':
    description: Pet not found

Παράμετροι ερωτήσεων

Οι παράμετροι ερώτησης επηρεάζουν την απόκριση:

Αίτημα φορέων

public async Task NotifySpecLoaded(string name, string basePath)
{
    await _hubContext.Clients.All.SendAsync("SpecLoaded", new
    {
        name,
        basePath,
        timestamp = DateTimeOffset.UtcNow
    });
}

public async Task NotifySpecDeleted(string name)
{
    await _hubContext.Clients.All.SendAsync("SpecDeleted", new
    {
        name,
        timestamp = DateTimeOffset.UtcNow
    });
}

Τα πτώματα POST/PUT περιλαμβάνονται στην προτροπή:

const connection = new signalR.HubConnectionBuilder()
    .withUrl('/hubs/openapi')
    .build();

connection.on('SpecLoaded', (data) => {
    showNotification(`Spec "${data.name}" loaded at ${data.basePath}`, 'success');
    refreshSpecList();
});

connection.on('SpecDeleted', (data) => {
    showNotification(`Spec "${data.name}" deleted`, 'info');
    refreshSpecList();
});

Περιγραφές και περιλήψεις

OpenAPI περιγραφές καθοδηγούν το LLM:

  • Αυτές περιλαμβάνονται στην προτροπή, βοηθώντας την LLM να κατανοήσει το σκοπό του τελικού σημείου.
  • Κωδικοί κατάστασης απόκρισης
  • Το σύστημα χρησιμοποιεί την πρώτη επιτυχή (2xx) απάντηση:
  • Μόνο τα 200 schema χρησιμοποιούνται για την παραγωγή απομίμησης (404s δεν προσομοιώνονται επί του παρόντος).
  • Ενημερώσεις Signer Real-Time

Όταν οι προδιαγραφές φορτώνονται/διαγράφονται, το UI λαμβάνει ειδοποιήσεις σε πραγματικό χρόνο μέσω του Signer:

JavaScript UI κωδικός:

Υποστήριξη μορφής

 Bad:  {"name": "spec1", ...}
 Good: {"name": "github-v3", ...}

Το σύστημα υποστηρίζει:

OpenAPI 3.0.x

### Good separation
/petstore/...
/github/...
/stripe/...

### Bad (conflicts!)
/api/... (multiple specs)

OpenAPI 3.1.x

Swagger 2.0

POST /api/openapi/specs/my-api/reload

Μορφή JSON

POST /api/openapi/specs
{
  "name": "petstore",
  "source": "...",
  "contextName": "test-session"
}

### Now all petstore calls maintain consistency

Μορφή YAML

Τόσο JSON όσο και YAML specs ανιχνεύονται αυτόματα και αναλύονται.

DELETE /api/openapi/specs/old-spec

Βέλτιστες Πρακτικές

  1. **1.**Χρήση περιγραφικών ονομάτων Spec
  2. **2.**Ορισμός κατάλληλων βασικών διαδρομών
  3. **Αποφύγετε τις συγκρούσεις χρησιμοποιώντας μοναδικά βασικά μονοπάτια:**3.
  4. Επαναφόρτωση όταν αλλάζουν specΕάν το OpenAPI spec σας είναι ενημερωμένο, ξαναγεμίστε το:
  5. **4.**Χρήση πλαισίων για σχετικές κλήσεις

5.

Καθαρισμός μετά τη δοκιμή/api/mockΑφαιρέστε τις προδιαγραφές που δεν χρησιμοποιείτε πλέον:

### OpenAPI-based (from spec)
GET /petstore/pet/123
### Uses Pet schema from OpenAPI spec

### Regular mock (shape-based)
GET /api/mock/custom?shape={"id":0,"name":"string"}
### Uses explicit shape parameter

Περιορισμοί

Κωδικοί κατάστασης απόκρισης

- Μόνο οι επιτυχημένες (2xx) απαντήσεις χλευάζονται

Ταυτοποίηση

private readonly ConcurrentDictionary<string, OpenApiSpecConfig> _specs = new();

- Οι κεφαλίδες είναι αποδεκτές αλλά δεν επικυρώνονται

DynamicOpenApiManagerΕπιβεβαίωση

- Το αίτημα επικύρωσης κατά των σχημάτων δεν επιβάλλεται

Κατάσταση

### Send these simultaneously
POST /api/openapi/specs {"name": "spec1", ...}
POST /api/openapi/specs {"name": "spec2", ...}
POST /api/openapi/specs {"name": "spec3", ...}
  • Δεν υπάρχει πραγματική βάση δεδομένων? τα δεδομένα παράγονται νωπά κάθε φορά (εκτός από τη χρήση των πλαισίων)

Επιδόσεις

- Η γενιά LLM προσθέτει καθυστέρηση (~100-500ms ανά αίτημα)

Ενσωμάτωση με τακτικά σημεία τερματισμού MockΟι προδιαγραφές OpenAPI λειτουργούν παράλληλα με τις τακτικές

τελικά σημεία:

  • Και οι δύο χρησιμοποιούν το ίδιο υποκείμενο LLM αλλά διαφέρουν στον τρόπο με τον οποίο παρέχεται το σχήμα.
  • Βελτιστοποίηση απόδοσης
  • Φύλαξη
  • Οι γεμάτες προδιαγραφές είναι αποθηκευμένες στη μνήμη:

Διάρκεια ζωής υπηρεσίας

**είναι ένα singleton, έτσι οι προδιαγραφές παραμένουν φορτωμένες για τη διάρκεια ζωής της εφαρμογής.**Παράλληλη φόρτωση Spec

Πολλαπλές προδιαγραφές μπορούν να φορτωθούν παράλληλα:

  • Και οι τρεις θα φορτώσουν παράλληλα, όχι διαδοχικά./petstore + /pet/123 = /petstore/pet/123
  • Αντιμετώπιση προβλημάτων
  • Ο Spec δεν θα φορτώσει

Πρόβλημα:

Αποτυχία φόρτωσης SpecΛύσεις:

Ελέγξτε το URL είναι προσβάσιμο

  • Επιβεβαίωση του αρχείου υπάρχει (για τοπικά μονοπάτια)
  • Βεβαιωθείτε ότι η JSON/YAML είναι έγκυρη
  • Αναζητήστε θέματα CORS (για απομακρυσμένα URL)

Δεν βρέθηκε το τελικό σημείο.

Πρόβλημα:

404 στο αναμενόμενο τελικό σημείο

  • **Λύσεις:**Επιβεβαίωσε τη βασική διαδρομή:
  • Ελέγξτε το spec ορίζει πραγματικά ότι η διαδρομήΒεβαιωθείτε ότι η μέθοδος HTTP ταιριάζει (GET vs POST)
  • Η απάντηση δεν ταιριάζει με το SchemaΠρόβλημα:
  • **Τα δεδομένα που παράγονται δεν ταιριάζουν με το αναμενόμενο σχήμα.**Λύσεις:
  • Ελέγξτε αν το σχήμα στην προδιαγραφή είναι σωστόΕπαληθεύστε ότι βλέπετε τη σωστή απάντηση (200 vs 201)

Θυμηθείτε: Η γενιά LLM είναι πιθανοληπτική, όχι αποφασιστική

Συμπέρασμα

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.