Inference and tool use
Basics
- Basic use
- Basic use via mixin
- Handling errors with `Maybe` helper class
- Modes
- Making some fields optional
- Private vs public object field
- Automatic correction based on validation results
- Using attributes
- Using LLM API connections from config file
- Validation
- Custom validation using Symfony Validator
- Validation across multiple fields
Advanced
- Context caching
- Context caching
- Customize parameters of OpenAI client
- Custom prompts
- Using structured data as an input
- Extracting arguments of function or method
- Streaming partial updates during inference
- Providing example inputs and outputs
- Extracting scalar values
- Extracting sequences of objects
- Streaming
- Structures
Troubleshooting
LLM API Support
Extras
- Extraction of complex objects
- Extraction of complex objects (Anthropic)
- Extraction of complex objects (Cohere)
- Extraction of complex objects (Gemini)
- Embeddings
- Image processing - car damage detection
- Image to data (OpenAI)
- Image to data (Anthropic)
- Image to data (Gemini)
- Working directly with LLMs
- Working directly with LLMs and JSON - JSON mode
- Working directly with LLMs and JSON - JSON Schema mode
- Working directly with LLMs and JSON - MdJSON mode
- Working directly with LLMs and JSON - Tools mode
- Prompts
- Generating JSON Schema from PHP classes
- Generating JSON Schema dynamically
- Simple content summary
- Inference and tool use
- Create tasks from meeting transcription
- Translating UI text fields
- Web page to PHP objects
Inference and tool use
Overview
Example
<?php
use Cognesy\Instructor\Extras\ToolUse\Tools\FunctionTool;
use Cognesy\Instructor\Extras\ToolUse\Tools\UpdateContextVariable;
use Cognesy\Instructor\Extras\ToolUse\ToolUse;
use Cognesy\Instructor\Utils\Debug\Debug;
use Cognesy\Instructor\Utils\Messages\Messages;
use Cognesy\Instructor\Utils\Result\Result;
$loader = require 'vendor/autoload.php';
$loader->add('Cognesy\\Instructor\\', __DIR__ . '../../src/');
Debug::enable();
//function add_numbers(int $a, int $b) : int {
// return $a + $b;
//}
//
//function subtract_numbers(int $a, int $b) : int {
// return $a - $b;
//}
//
//$toolUse = (new ToolUse)
// ->withMessages('Add 2455 and 3558 then subtract 4344 from the result.')
// ->withTools([
// FunctionTool::fromCallable(add_numbers(...)),
// FunctionTool::fromCallable(subtract_numbers(...)),
// ]);
function send_discount_code(string $name, string $email) : Result {
return Result::success(true);
}
function save_to_crm(string $email) : Result {
return Result::success(true);
}
$sequence = [
['role' => 'user', 'content' => 'Can you offer me a discount?'],
['role' => 'user', 'content' => 'My email is john@doe.com'],
];
$messages = Messages::fromArray([
['role' => 'system', 'content' => 'Your objective is to answer user questions. If user shares their email address - store it to the context variable `email` and save it to CRM. Never nag user for their email unless he asks for discount.'],
['role' => 'user', 'content' => 'I\'ve got your invite from nick@acme.com and I like the product, but I need assistance with your pricing'],
]);
echo $messages->toRoleString();
echo "\n";
foreach($sequence as $message) {
$toolUse = (new ToolUse)
->withTools([
new UpdateContextVariable(),
FunctionTool::fromCallable(send_discount_code(...)),
FunctionTool::fromCallable(save_to_crm(...)),
])
->withMessages($messages);
$step = $toolUse->finalStep();
//dump($step);
$messages->appendMessage($step->response());
echo "ASSISTANT: {$messages->last()->content()}\n";
$messages->appendMessage($message);
echo "USER: {$messages->last()->content()}\n";
}
# PATTERN #1 - fine grained control
// iterate until no more steps
while ($toolUse->hasNextStep()) {
$step = $toolUse->nextStep();
}
// do something with final response
print($step->response());
//# PATTERN #2 - use iterator
//foreach ($toolUse->iterator() as $step) {
// dump($step);
//}
//// do something with final response
//dump('final #2', $step);
//
//
//# PATTERN #3 - just get final step (fast forward to it)
//$step = $toolUse->finalStep();
//// do something with final response
//dump('final #3', $step);