<?php
require 'examples/boot.php';
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Schema\Attributes\Description;
class Response { public string $code; }
class Feedback {
#[Description('Actions to improve the code')]
public array $feedback;
public bool $done;
}
class Timestep {
public string $response;
public array $feedback;
public string $refined_response;
}
class History {
/** @var Timestep[] */
public array $history = [];
public function add(string $code, array $feedback, string $refined) : void {
$t = new Timestep();
$t->response = $code;
$t->feedback = $feedback;
$t->refined_response = $refined;
$this->history[] = $t;
}
}
class SelfRefinePipeline {
public function generateInitial(string $prompt) : Response {
return (new StructuredOutput)->with(
model: 'gpt-4o',
responseModel: Response::class,
messages: [ ['role' => 'user', 'content' => $prompt] ],
)->get();
}
public function generateFeedback(Response $response) : Feedback {
$msg = <<<MSG
You are an expert Python coder.
Provide feedback on this code. How can we make it (1) faster and (2) more readable?
<code>
{$response->code}
</code>
If the code does not need improvement, set done = True.
MSG;
return (new StructuredOutput)->with(
model: 'gpt-4o',
responseModel: Feedback::class,
messages: [ ['role' => 'user', 'content' => $msg] ],
)->get();
}
public function refine(Response $response, Feedback $feedback) : Response {
$msg = <<<MSG
You are an expert Python coder.
<response>
{$response->code}
</response>
<feedback>
" . implode("\n", $feedback->feedback) . "
</feedback>
Refine your response.
MSG;
return (new StructuredOutput)->with(
model: 'gpt-4o',
responseModel: Response::class,
messages: [ ['role' => 'user', 'content' => $msg] ],
)->get();
}
public function stop(Feedback $feedback, History $history) : bool {
if ($feedback->done) { return true; }
return count($history->history) >= 3;
}
}
$pipeline = new SelfRefinePipeline();
$response = $pipeline->generateInitial('Write Python code to calculate the Fibonacci sequence.');
$history = new History();
while (true) {
$fb = $pipeline->generateFeedback($response);
if ($pipeline->stop($fb, $history)) { break; }
$refined = $pipeline->refine($response, $fb);
$history->add($response->code, $fb->feedback, $refined->code);
$response = $refined;
}
dump($history, $response);
?>