or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdchat-completion.mdgrammar.mdindex.mdllama-model.mdlow-level.mdserver.mdtokenization.mdvision.md

grammar.mddocs/

0

# Grammar and Structured Generation

1

2

Constrained text generation using formal grammars (GBNF), JSON Schema validation, and built-in templates for structured outputs like JSON, code, and domain-specific formats.

3

4

## Capabilities

5

6

### Grammar-Based Generation

7

8

Control model output using formal grammar rules in GBNF (GGML BNF) format.

9

10

```python { .api }

11

class LlamaGrammar:

12

def __init__(self, grammar_str: str, verbose: bool = True):

13

"""

14

Initialize grammar from GBNF string.

15

16

Args:

17

grammar_str: Grammar rules in GBNF format

18

verbose: Enable verbose logging

19

"""

20

21

@classmethod

22

def from_string(

23

cls,

24

grammar_str: str,

25

verbose: bool = True

26

) -> "LlamaGrammar":

27

"""

28

Create grammar from GBNF string.

29

30

Args:

31

grammar_str: Grammar rules in GBNF format

32

verbose: Enable verbose logging

33

34

Returns:

35

LlamaGrammar instance

36

"""

37

38

@classmethod

39

def from_file(

40

cls,

41

file_path: str,

42

verbose: bool = True

43

) -> "LlamaGrammar":

44

"""

45

Create grammar from GBNF file.

46

47

Args:

48

file_path: Path to GBNF grammar file

49

verbose: Enable verbose logging

50

51

Returns:

52

LlamaGrammar instance

53

"""

54

55

@classmethod

56

def from_json_schema(

57

cls,

58

json_schema: str,

59

verbose: bool = True

60

) -> "LlamaGrammar":

61

"""

62

Create grammar from JSON Schema string.

63

64

Args:

65

json_schema: JSON Schema as string (use json.dumps() to convert dict)

66

verbose: Enable verbose logging

67

68

Returns:

69

LlamaGrammar instance with schema constraints

70

"""

71

```

72

73

### JSON Schema Conversion

74

75

Convert JSON Schema specifications to GBNF grammar format for structured JSON generation.

76

77

```python { .api }

78

def json_schema_to_gbnf(

79

schema: dict,

80

prop_order: Optional[List[str]] = None,

81

allow_fetch: bool = True,

82

dotall: bool = False,

83

raw_pattern: bool = False

84

) -> str:

85

"""

86

Convert JSON Schema to GBNF grammar format.

87

88

Args:

89

schema: JSON Schema dictionary

90

prop_order: Property ordering for object serialization

91

allow_fetch: Allow fetching external schema references

92

dotall: Enable dotall mode for regex patterns

93

raw_pattern: Use raw pattern matching

94

95

Returns:

96

GBNF grammar string

97

"""

98

99

class SchemaConverter:

100

def __init__(

101

self,

102

prop_order: Optional[List[str]] = None,

103

allow_fetch: bool = True,

104

dotall: bool = False,

105

raw_pattern: bool = False

106

):

107

"""

108

Initialize schema converter.

109

110

Args:

111

prop_order: Default property ordering

112

allow_fetch: Allow external references

113

dotall: Dotall mode for patterns

114

raw_pattern: Raw pattern mode

115

"""

116

117

def convert(self, schema: dict) -> str:

118

"""

119

Convert schema to GBNF format.

120

121

Args:

122

schema: JSON Schema dictionary

123

124

Returns:

125

GBNF grammar string

126

"""

127

```

128

129

### Built-in Grammar Rules

130

131

Pre-defined grammar building blocks for common patterns.

132

133

```python { .api }

134

class BuiltinRule:

135

def __init__(self, rule_name: str, content: str):

136

"""

137

Built-in grammar rule definition.

138

139

Args:

140

rule_name: Name of the rule

141

content: Rule content in GBNF format

142

"""

143

self.rule_name = rule_name

144

self.content = content

145

```

146

147

## Pre-defined Grammar Templates

148

149

```python { .api }

150

# Arithmetic expressions

151

ARITHMETIC_GBNF: str

152

153

# C-like programming language syntax

154

C_GBNF: str

155

156

# Chess notation (algebraic notation)

157

CHESS_GBNF: str

158

159

# Japanese text patterns

160

JAPANESE_GBNF: str

161

162

# JSON array format

163

JSON_ARR_GBNF: str

164

165

# JSON object format

166

JSON_GBNF: str

167

168

# List structures

169

LIST_GBNF: str

170

171

# Default grammar root rule

172

LLAMA_GRAMMAR_DEFAULT_ROOT: str

173

```

174

175

## Usage Examples

176

177

### Basic Grammar Usage

178

179

```python

180

from llama_cpp import Llama, LlamaGrammar

181

182

# Initialize model

183

llm = Llama(model_path="./models/llama-2-7b.gguf")

184

185

# Create simple grammar for yes/no responses

186

yes_no_grammar = """

187

root ::= response

188

response ::= "yes" | "no" | "Yes" | "No" | "YES" | "NO"

189

"""

190

191

grammar = LlamaGrammar.from_string(yes_no_grammar)

192

193

# Generate constrained response

194

response = llm.create_completion(

195

prompt="Do you like pizza? Answer with yes or no:",

196

max_tokens=10,

197

grammar=grammar,

198

)

199

200

print(response['choices'][0]['text']) # Will be "yes", "no", etc.

201

```

202

203

### JSON Schema Generation

204

205

```python

206

from llama_cpp import Llama, LlamaGrammar

207

208

llm = Llama(model_path="./models/llama-2-7b.gguf")

209

210

# Define JSON schema for person data

211

person_schema = {

212

"type": "object",

213

"properties": {

214

"name": {"type": "string"},

215

"age": {"type": "integer", "minimum": 0, "maximum": 150},

216

"email": {"type": "string", "format": "email"},

217

"hobbies": {

218

"type": "array",

219

"items": {"type": "string"},

220

"maxItems": 5

221

}

222

},

223

"required": ["name", "age"],

224

"additionalProperties": False

225

}

226

227

# Create grammar from schema (convert dict to string first)

228

import json

229

grammar = LlamaGrammar.from_json_schema(json.dumps(json.dumps(person_schema)))

230

231

# Generate valid JSON

232

response = llm.create_completion(

233

prompt="Generate a person's information in JSON format:",

234

max_tokens=200,

235

grammar=grammar,

236

temperature=0.7,

237

)

238

239

import json

240

generated_json = json.loads(response['choices'][0]['text'])

241

print(json.dumps(generated_json, indent=2))

242

```

243

244

### Pre-defined Grammar Templates

245

246

```python

247

from llama_cpp import Llama, LlamaGrammar

248

from llama_cpp.llama_grammar import JSON_GBNF, ARITHMETIC_GBNF

249

250

llm = Llama(model_path="./models/model.gguf")

251

252

# Use built-in JSON grammar

253

json_grammar = LlamaGrammar.from_string(JSON_GBNF)

254

255

response = llm.create_completion(

256

prompt="Create a JSON object describing a book:",

257

max_tokens=150,

258

grammar=json_grammar,

259

)

260

261

print("JSON output:", response['choices'][0]['text'])

262

263

# Use arithmetic grammar

264

math_grammar = LlamaGrammar.from_string(ARITHMETIC_GBNF)

265

266

math_response = llm.create_completion(

267

prompt="Write a mathematical expression:",

268

max_tokens=50,

269

grammar=math_grammar,

270

)

271

272

print("Math expression:", math_response['choices'][0]['text'])

273

```

274

275

### Complex Grammar Rules

276

277

```python

278

# Create grammar for structured code generation

279

code_grammar = """

280

root ::= program

281

program ::= statement+

282

statement ::= assignment | function_call | comment

283

assignment ::= variable " = " expression "\\n"

284

function_call ::= function_name "(" arguments? ")" "\\n"

285

comment ::= "# " [^\\n]* "\\n"

286

variable ::= [a-zA-Z_][a-zA-Z0-9_]*

287

function_name ::= [a-zA-Z_][a-zA-Z0-9_]*

288

expression ::= number | string | variable

289

arguments ::= expression ("," " " expression)*

290

number ::= [0-9]+

291

string ::= "\\"" [^"]* "\\""

292

"""

293

294

grammar = LlamaGrammar.from_string(code_grammar)

295

296

response = llm.create_completion(

297

prompt="Write a Python program that processes data:",

298

max_tokens=200,

299

grammar=grammar,

300

)

301

302

print("Generated code:")

303

print(response['choices'][0]['text'])

304

```

305

306

### Multi-step Structured Generation

307

308

```python

309

# Generate structured conversation data

310

conversation_schema = {

311

"type": "object",

312

"properties": {

313

"conversation_id": {"type": "string"},

314

"participants": {

315

"type": "array",

316

"items": {"type": "string"},

317

"minItems": 2,

318

"maxItems": 4

319

},

320

"messages": {

321

"type": "array",

322

"items": {

323

"type": "object",

324

"properties": {

325

"speaker": {"type": "string"},

326

"message": {"type": "string"},

327

"timestamp": {"type": "string", "format": "time"}

328

},

329

"required": ["speaker", "message"]

330

},

331

"minItems": 1

332

},

333

"topic": {"type": "string"},

334

"sentiment": {"enum": ["positive", "negative", "neutral"]}

335

},

336

"required": ["conversation_id", "participants", "messages", "topic"]

337

}

338

339

conversation_grammar = LlamaGrammar.from_json_schema(json.dumps(conversation_schema))

340

341

# Generate structured conversation

342

response = llm.create_completion(

343

prompt="Create a conversation between friends about technology:",

344

max_tokens=300,

345

grammar=conversation_grammar,

346

temperature=0.8,

347

)

348

349

conversation_data = json.loads(response['choices'][0]['text'])

350

print("Generated conversation:")

351

print(json.dumps(conversation_data, indent=2))

352

```

353

354

### Grammar File Usage

355

356

```python

357

# Save grammar to file

358

weather_grammar = """

359

root ::= weather_report

360

weather_report ::= location " weather: " condition " " temperature " " humidity

361

location ::= [A-Z][a-z]+ ("," " " [A-Z][a-z]+)?

362

condition ::= "sunny" | "cloudy" | "rainy" | "snowy" | "overcast"

363

temperature ::= [0-9]+ "°" ("C" | "F")

364

humidity ::= [0-9]+ "%"

365

"""

366

367

# Write to file

368

with open("weather_grammar.gbnf", "w") as f:

369

f.write(weather_grammar)

370

371

# Load from file

372

grammar = LlamaGrammar.from_file("weather_grammar.gbnf")

373

374

response = llm.create_completion(

375

prompt="Give me a weather report for New York:",

376

max_tokens=50,

377

grammar=grammar,

378

)

379

380

print("Weather report:", response['choices'][0]['text'])

381

```

382

383

### Advanced Schema Patterns

384

385

```python

386

# Complex nested schema with arrays and objects

387

api_response_schema = {

388

"type": "object",

389

"properties": {

390

"status": {"enum": ["success", "error"]},

391

"data": {

392

"oneOf": [

393

{

394

"type": "object",

395

"properties": {

396

"users": {

397

"type": "array",

398

"items": {

399

"type": "object",

400

"properties": {

401

"id": {"type": "integer"},

402

"username": {"type": "string"},

403

"active": {"type": "boolean"}

404

},

405

"required": ["id", "username"]

406

}

407

},

408

"total_count": {"type": "integer"}

409

}

410

},

411

{

412

"type": "null"

413

}

414

]

415

},

416

"error": {

417

"type": "object",

418

"properties": {

419

"code": {"type": "integer"},

420

"message": {"type": "string"}

421

}

422

}

423

},

424

"required": ["status"]

425

}

426

427

api_grammar = LlamaGrammar.from_json_schema(json.dumps(api_response_schema))

428

429

# Generate API response

430

response = llm.create_completion(

431

prompt="Generate a successful API response with user data:",

432

max_tokens=250,

433

grammar=api_grammar,

434

)

435

436

api_data = json.loads(response['choices'][0]['text'])

437

print("API Response:")

438

print(json.dumps(api_data, indent=2))

439

```

440

441

### Grammar Debugging

442

443

```python

444

# Enable verbose mode for grammar debugging

445

debug_grammar = """

446

root ::= greeting

447

greeting ::= salutation " " name punctuation

448

salutation ::= "Hello" | "Hi" | "Hey"

449

name ::= [A-Z][a-z]+

450

punctuation ::= "!" | "."

451

"""

452

453

grammar = LlamaGrammar.from_string(debug_grammar, verbose=True)

454

455

# This will show grammar parsing information

456

response = llm.create_completion(

457

prompt="Say hello to someone:",

458

max_tokens=20,

459

grammar=grammar,

460

)

461

462

print("Greeting:", response['choices'][0]['text'])

463

```

464

465

### Schema Validation Integration

466

467

```python

468

import jsonschema

469

470

# Create schema and corresponding grammar

471

product_schema = {

472

"type": "object",

473

"properties": {

474

"product_name": {"type": "string"},

475

"price": {"type": "number", "minimum": 0},

476

"in_stock": {"type": "boolean"},

477

"categories": {

478

"type": "array",

479

"items": {"type": "string"},

480

"uniqueItems": True

481

}

482

},

483

"required": ["product_name", "price", "in_stock"]

484

}

485

486

grammar = LlamaGrammar.from_json_schema(json.dumps(product_schema))

487

488

# Generate product data

489

response = llm.create_completion(

490

prompt="Create product information for an electronic device:",

491

max_tokens=150,

492

grammar=grammar,

493

)

494

495

# Validate against original schema

496

try:

497

product_data = json.loads(response['choices'][0]['text'])

498

jsonschema.validate(product_data, product_schema))

499

print("Generated valid product data:")

500

print(json.dumps(product_data, indent=2))

501

except jsonschema.ValidationError as e:

502

print(f"Validation error: {e}")

503

except json.JSONDecodeError as e:

504

print(f"JSON parsing error: {e}")

505

```