inspector-apm/neuron-ai
Neuron is a PHP framework for building agentic AI apps: define and orchestrate AI agents, connect to LLM providers, load data, use tools, coordinate multiple agents, and monitor/debug runs. Works with Laravel or Symfony and supports end-to-end agent workflows.
## Getting Started
### First Steps
1. **Installation**:
```bash
composer require neuron-core/neuron-ai
Ensure PHP 8.1+ is used.
Generate a basic agent:
vendor/bin/neuron make:agent MyFirstAgent
This creates a scaffold in app/Neuron/MyFirstAgent.php.
Configure your agent:
Anthropic, OpenAI) in the provider() method.instructions() using SystemPrompt.MySQLToolkit) in tools() if needed.Run a simple chat:
$response = MyFirstAgent::make()->chat(new UserMessage("Hello!"))
->getMessage();
echo $response->getContent();
Route::post('/chat', function (Request $request) {
$response = MyFirstAgent::make()->chat(new UserMessage($request->input('message')))
->getMessage();
return response()->json(['response' => $response->getContent()]);
});
curl or Postman.MyAgent::make() for singleton-like behavior (Laravel service container integration).// Chat mode
$agent->chat(new UserMessage("Analyze this data: ..."));
// Stream mode (for UI)
$stream = $agent->stream(new UserMessage("..."));
foreach ($stream->events() as $chunk) {
if ($chunk instanceof TextChunk) {
echo $chunk->content;
}
}
// Structured output
$data = $agent->structured(new UserMessage("..."), MyClass::class);
protected function tools(): array {
return [
MySQLToolkit::make(\DB::connection()->getPdo()),
CalculatorToolkit::make(),
];
}
class MyTool extends Tool {
public function __invoke(string $input) {
return "Processed: " . $input;
}
}
Register in tools() array.vendor/bin/neuron make:rag MyRagAgent
class MyRagAgent extends RAG {
protected function embeddings(): EmbeddingsProviderInterface {
return new VoyageEmbeddingProvider(key: '...');
}
protected function vectorStore(): VectorStoreInterface {
return new PineconeVectorStore(key: '...');
}
}
$response = MyRagAgent::make()->chat(new UserMessage("Query about docs..."));
// app/Providers/NeuronServiceProvider.php
public function register() {
$this->app->singleton(MyAgent::class, fn() => new MyAgent());
}
public function __construct(private MyAgent $agent) {}
use NeuronAI\Chat\Messages\Stream\Adapters\VercelAIAdapter;
Route::post('/stream', function (Request $request) {
$stream = MyAgent::make()->stream(new UserMessage($request->input('message')))
->events(new VercelAIAdapter());
return response()->stream(fn() => yield from $stream);
});
class UserProfile {
#[SchemaProperty(description: "User's full name")]
public string $name;
}
$profile = $agent->structured(new UserMessage("..."), UserProfile::class);
protected function chatHistory(): ChatHistoryInterface {
return new FileChatHistory(storage_path('app/agent_memory.json'));
}
InMemory, File, SQL, Eloquent.Tool Execution Errors:
json_encode()-able).__invoke() to avoid LLM hallucinations.ToolProperty annotations for strict typing.Prompt Engineering:
SystemPrompt backgrounds. Use steps for clarity:
new SystemPrompt(
steps: ["Step 1: Analyze", "Step 2: Respond"]
)
chat() first before streaming.Streaming Quirks:
TextChunk::isFinal() to detect completion.RAG Performance:
$embeddings = new VoyageEmbeddingProvider(key: '...', cache: true);
k (nearest neighbors) to reduce latency.Memory Leaks:
InMemoryChatHistory resets on agent restart. Use FileChatHistory for persistence.Inspector APM:
INSPECTOR_INGESTION_KEY in .env to visualize agent execution.Logging:
new Anthropic(key: '...', debug: true)
UserMessage and AIMessage content for auditing.Tool Debugging:
try-catch in __invoke() to log errors:
public function __invoke(string $input) {
try {
return $this->process($input);
} catch (\Exception $e) {
logger()->error("Tool failed: " . $e->getMessage());
throw $e;
}
}
Environment Variables:
env() or Laravel's .env for API keys:
new Anthropic(key: env('ANTHROPIC_API_KEY'))
.env.example with placeholder keys.Provider Switching:
// Swap Anthropic for OpenAI
protected function provider(): AIProviderInterface {
return new OpenAI(key: env('OPENAI_API_KEY'));
}
Laravel Caching:
$agent = Cache::remember('agent_instance', now()->addHours(1), fn() => MyAgent::make());
Custom Workflows:
Workflow for non-agent logic:
use NeuronAI\Workflow\Workflow;
class MyWorkflow extends Workflow {
protected function steps(): array {
return [
new ChatStep($agent, new UserMessage("...")),
new ToolStep(new MyTool()),
];
}
}
Workflow::run() for complex sequences.Human-in-the-Loop:
$workflow->pause("Review this before proceeding");
Evaluation Framework:
vendor/bin/neuron evaluate MyAgent
EvaluationTestCase for unit tests.Service Container:
$this->app->singleton(MyAgent::class, fn() => new MyAgent());
when() for conditional binding.Queue Jobs:
MyAgentJob::dispatch(new UserMessage("..."))->onQueue('ai');
Filament Integration:
How can I help you explore Laravel packages today?