Files
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

6.1 KiB

name, description, version
name description version
ax-signature This skill helps an LLM generate correct DSPy signature code using @ax-llm/ax. Use when the user asks about signatures, s(), f(), field types, string syntax, fluent builder API, validation constraints, or type-safe inputs/outputs. 19.0.33

Ax Signature Reference

Signature Syntax

[description] input1:type, input2:type -> output1:type, output2:type

Field Types

Type Syntax TypeScript Example
String :string string userName:string
Number :number number score:number
Boolean :boolean boolean isValid:boolean
JSON :json any metadata:json
Date :date Date birthDate:date
DateTime :datetime Date timestamp:datetime
Image :image {mimeType, data} photo:image (input only)
Audio :audio {format?, data} recording:audio (input only)
File :file {mimeType, data} document:file (input only)
URL :url string website:url
Code :code string pythonScript:code
Class :class "a, b, c" "a" | "b" | "c" mood:class "happy, sad"

Arrays, Optional, and Internal Fields

'tags:string[] -> processedTags:string[]'  // arrays
'query:string, context?:string -> response:string'  // optional with ?
'problem:string -> reasoning!:string, solution:string'  // internal with !

Three Ways to Create Signatures

import { ax, s } from '@ax-llm/ax';
const gen = ax('input:string -> output:string');
const sig = s('query:string -> response:string');

2. Pure Fluent Builder API

import { f } from '@ax-llm/ax';
const sig = f()
  .input('userMessage', f.string('User input'))
  .input('contextData', f.string('Additional context').optional())
  .input('tags', f.string('Keywords').array())
  .output('responseText', f.string('AI response'))
  .output('confidenceScore', f.number('Confidence 0-1'))
  .output('debugInfo', f.string('Debug info').internal())
  .build();

3. Hybrid

import { s, f } from '@ax-llm/ax';
const sig = s('base:string -> result:string')
  .appendInputField('extra', f.json('Metadata').optional())
  .appendOutputField('score', f.number('Quality score'));

Fluent API Reference

Type creators:

  • f.string(desc), f.number(desc), f.boolean(desc), f.json(desc)
  • f.image(desc), f.audio(desc), f.file(desc), f.url(desc)
  • f.email(desc), f.date(desc), f.datetime(desc)
  • f.class(['a','b','c'], desc), f.code(desc)
  • f.object({ field: f.string() }, desc)

Chainable modifiers (method chaining only, no nesting):

  • .optional() - make field optional
  • .array() / .array('list description') - make field an array
  • .internal() - output only, hidden from final output
  • .cache() - input only, mark for prompt caching
// Correct: pure fluent chaining
f.string('description').optional().array()
f.string('context').cache().optional()
f.object({ field: f.string() }, 'item desc').array('list desc')

// Wrong: nested function calls (removed)
f.array(f.string('description'))      // REMOVED
f.optional(f.string('description'))   // REMOVED
f.internal(f.string('description'))   // REMOVED

Validation Constraints

String Constraints

f.string('username').min(3).max(20)
f.string('email').email()
f.string('website').url()
f.string('birthDate').date()
f.string('timestamp').datetime()
f.string('pattern').regex('^[A-Z0-9]')

Number Constraints

f.number('age').min(18).max(120)
f.number('score').min(0).max(100)

Complete Validation Example

const sig = f()
  .input('formData', f.string('Raw form data'))
  .output('user', f.object({
    username: f.string('Username').min(3).max(20),
    email: f.string('Email').email(),
    age: f.number('Age').min(18).max(120),
    bio: f.string('Bio').max(500).optional(),
    website: f.string('Website').url().optional(),
    tags: f.string('Tag').min(2).max(30).array()
  }, 'User profile'))
  .build();

Cached Input Fields

const sig = f()
  .input('staticContext', f.string('Context').cache())
  .input('userQuery', f.string('Dynamic query'))
  .output('answer', f.string('Response'))
  .build();

Field Naming Rules

Good: userQuestion, customerEmail, analysisResult, confidenceScore Bad: text, data, input, output, a, x, val (too generic), 1field (starts with number)

Media Type Restrictions

  • Media types (image, audio, file) are top-level input fields only
  • Cannot be nested in objects
  • Cannot be output fields

Common Patterns

// Chain of Thought
'problem:string -> reasoning!:string, solution:string'

// Classification
'email:string -> priority:class "urgent, normal, low"'

// Multi-modal
'imageData:image, question?:string -> description:string, objects:string[]'

// Data Extraction
'invoiceText:string -> invoiceNumber:string, totalAmount:number, lineItems:json[]'

// With description
'"Answer TypeScript questions" question:string -> answer:string, confidence:number'

Critical Rules

  • Use f() fluent builder, NOT nested f.array(f.string()) -- those are removed.
  • Field names must be descriptive (not generic like text, data, input).
  • Media types are input-only, top-level only.
  • .internal() is output-only (for chain-of-thought reasoning).
  • .cache() is input-only (for prompt caching).
  • Validation errors trigger auto-retry with correction feedback.
  • f.email(), f.url(), f.date(), f.datetime() are shorthand for f.string().email() etc.

Examples

Fetch these for full working code: