Introduction
As API-first platforms, we strive to create interfaces that are not only user-friendly but also machine-understandable. With the rise of Large Language Models (LLMs), it's essential to design APIs that can seamlessly interact with both humans and machines. In this article, we'll explore the principles and best practices for designing LLM-ready APIs.
Types as Documentation
One of the key aspects of LLM-friendly API design is using types as documentation. This means that every API endpoint should have a clear, machine-readable description of its input and output parameters. We can achieve this by using OpenAPI specifications, which provide a standardized way to document APIs.
Here's an example of an OpenAPI specification for a simple API:
openapi: 3.0.2
info:
title: Sample API
version: 1.0.0
paths:
/users:
get:
summary: Get all users
parameters:
- name: limit
in: query
schema:
type: integer
required: true
responses:
200:
description: List of users
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
In this example, the summary field provides a human-readable description of the endpoint, while the parameters and responses sections provide machine-readable information about the input and output parameters.
LLM-Friendly API Endpoints
When designing API endpoints for LLM interaction, we should follow these guidelines:
- Use clear, descriptive names for APIs and their parameters.
- Provide explicit documentation of expected input formats (e.g., JSON, XML).
- Specify the expected response format and any error handling mechanisms.
- Consider using standard HTTP methods (GET, POST, PUT, DELETE) for common operations.
Here's an example of an LLM-friendly API endpoint:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
def get_user(user_id: int):
# Return a JSON response with user data
return {"id": user_id, "name": "John Doe"}
In this example, the get_user endpoint expects an integer user_id parameter and returns a JSON response with user data.
Handling LLM-Generated Input
When dealing with LLM-generated input, we should be prepared to handle potential errors or inconsistencies. Here's an example of how you can validate user input using Python's marshmallow library:
from marshmallow import Schema, fields, ValidationError
class UserSchema(Schema):
id = fields.Int(required=True)
name = fields.Str(required=True)
try:
data = await request.json()
schema = UserSchema()
result = schema.load(data)
except ValidationError as err:
return {"error": str(err)}
In this example, we define a UserSchema to validate the input data. If the validation fails, we return an error response with the specific error message.
Conclusion
Designing LLM-friendly APIs requires attention to detail and a clear understanding of how humans and machines interact with our interfaces. By following these guidelines and using tools like OpenAPI specifications and type-based documentation, we can create APIs that are not only user-friendly but also machine-understandable.
Related:
Sources: