> For the complete documentation index, see [llms.txt](https://docs.neuron-ai.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.neuron-ai.dev/neuron-v3-zh/zhi-neng-ti/agent.md).

# 智能体

### 简介

你可以通过扩展 `NeuronAI\Agent\Agent` 类来继承框架的主要功能并创建完全可用的智能体。

这个类会自动为你管理一些机制，例如记忆、工具和函数调用。我们将在后续章节中更详细地介绍这些方面。

我们强烈建议扩展 Agent 类，而不是使用 [流式定义](#fluent-agent-definition)来创建智能体。这种方式更容易为智能体添加自定义方法和行为，也更有利于可移植性，因为所有相关部分都被封装在一个单一实体中，你可以在应用程序中的任何地方运行它，甚至将其作为一个独立的 composer 包发布。

让我们开始创建一个用于总结 YouTube 视频的 AI Agent。我们先创建 `YouTubeAgent` 类：

{% tabs %}
{% tab title="Unix" %}

```bash
vendor/bin/neuron make:agent App\\Neuron\\YouTubeAgent
```

{% endtab %}

{% tab title="Windows" %}

```powershell
.\vendor\bin\neuron make:agent App\Neuron\YouTubeAgent
```

{% endtab %}
{% endtabs %}

该命令会创建一个这样的类：

```php
<?php

namespace App\Neuron;

use NeuronAI\Agent\Agent;
use NeuronAI\Agent\SystemPrompt;
use NeuronAI\Providers\AIProviderInterface;

class YouTubeAgent extends Agent
{
    protected function provider(): AIProviderInterface
    {
        // 返回 Anthropic、OpenAI、Gemini、Ollama 等的实例...
    }
    
    protected function instructions(): string
    {
        return "你是一个使用 Neuron AI 框架创建的友好 AI Agent。";
    }
    
    /**
     * @return \NeuronAI\Tools\ToolInterface[]
     */
    protected function tools(): array
    {
        return [];
    }
}
```

### 监控与调试

你使用 Neuron 构建的许多应用都会包含多个步骤，以及对 LLM 的多次调用。随着这些应用变得越来越复杂，能够准确查看你的 agentic 系统内部究竟发生了什么就变得至关重要。实现这一点的最佳方式是使用 [检查器](https://inspector.dev/).

{% embed url="<https://docs.inspector.dev/guides/neuron-ai>" %}

### AI 提供商

最小实现需要指定一个 AI Provider，它将成为你的智能体的语言和推理引擎。

唯一需要实现的方法是 `provider()` 它会返回你想使用的提供商实例。假设它是 Anthropic。

```php
<?php

namespace App\Neuron;

use NeuronAI\Agent\Agent;
use NeuronAI\Agent\SystemPrompt;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;

class YouTubeAgent extends Agent
{
    protected function provider(): AIProviderInterface
    {
        // 返回 Anthropic、OpenAI、Gemini、Ollama 等的实例...
        return new Anthropic(
            key: 'ANTHROPIC_API_KEY',
            model: 'ANTHROPIC_MODEL',
        );
    }
    
    protected function instructions(): string
    {
        return "你是一个使用 Neuron AI 框架创建的友好 AI Agent。";
    }
    
    /**
     * @return \NeuronAI\Tools\ToolInterface[]
     */
    protected function tools(): array
    {
        return [];
    }
}
```

如果你愿意，也可以使用其他提供商，比如 OpenAI、Gemini，或者在本地运行模型时使用 Ollama。查看 [受支持的提供商](/neuron-v3-zh/ti-gong-shang/ai-provider.md).

### 系统指令

第二个重要组成部分是系统指令。系统指令提供指导，使 AI 按照我们希望达成的任务来行动。它们是固定指令，会在每次交互时发送给 LLM。

这就是它们通过内部方法定义，并保留在智能体实体内部封装的原因。让我们实现 `instructions()` 方法：

```php
<?php

namespace App\Neuron;

use NeuronAI\Agent\Agent;
use NeuronAI\Agent\SystemPrompt;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;

class YouTubeAgent extends Agent
{
    protected function provider(): AIProviderInterface
    {
        // 返回一个 AI provider 实例（Anthropic、OpenAI、Ollama、Gemini 等）
        return new Anthropic(
            key: 'ANTHROPIC_API_KEY',
            model: 'ANTHROPIC_MODEL',
        );
    }
    
    protected function instructions(): string
    {
        return <<<TEXT
            你是一个专门编写 YouTube 视频摘要的 AI Agent。
            获取一个 YouTube 视频的 URL，或者请用户提供一个。
            使用你可用的工具来获取该视频的转录文本。
            写一段摘要，不要使用列表。只使用流畅的文本。
            在摘要后添加一个包含三句话的列表，作为该视频最重要的三个要点。
        TEXT;
    }
    
    /**
     * @return \NeuronAI\Tools\ToolInterface[]
     */
    protected function tools(): array
    {
        return [];
    }
}
```

### 与 Agent 对话

我们已经准备好测试智能体在新指令下如何响应我们的消息。

```php
use NeuronAI\Chat\Messages\UserMessage;

$message = YouTubeAgent::make()
    ->chat(new UserMessage("你是谁？"))
    ->getMessage();
    
echo $message->getContent();
// 你好，我是一个擅长总结 YouTube 视频的友好 AI agent！
// 你能给我一个你想要快速摘要的 YouTube 视频 URL 吗？
```

### Agent 状态

由于 Agent 是 Workflow 的扩展，因此不再是通过 `getMessage()` 方法获取模型生成的最后一条回复，而是可以直接运行 agent 工作流，并将原始的 agent 状态作为返回值。agent 状态包含额外信息，可帮助你检查 agent 执行过程中发生了什么。

```php
$state = MyAgent::make()
    ->chat(new UserMessage("你是谁？"))
    ->run();

// $state 是 NeuropnAI\Agent\AgentState 类的一个实例
$state->getMessage();
```

#### 步骤

调用 `getMessage()` 该方法时，你只能获取模型为回答你的提示而生成的最后一条消息。但在内部，agent 可能会在得出最终答案之前执行多次工具调用迭代。

agent 状态会存储当前执行周期内 agent 与提供商之间的所有消息列表，而不仅仅是最终答案。因此你可以通过 `getSteps()` 方法访问消息列表：

```php
$state = MyAgent::make()
    ->chat(new UserMessage("你是谁？"))
    ->run();

// 访问执行过程中的步骤列表
foreach($state->getSteps() as $message) {
    echo "- ".$message::class."\n";
}

// 最终答案
echo $state->getMessage()->getContent();
```

#### 工具运行

如果 agent 在执行期间决定使用工具，agent 状态会跟踪工具运行次数，以便在 [maxRuns](/neuron-v3-zh/zhi-neng-ti/tools.md#max-runs) 达到上限时停止执行。你可以访问这个映射：

```php
$state = MyAgent::make()
    ->chat(new UserMessage("你是谁？"))
    ->run();

// 访问工具运行映射
foreach($state->getToolRuns() as $toolName => $runs) {
    echo "- 工具 {$toolName} 已被使用 {$runs} 次\n";
}
```

### 消息

agent 始终接受一个 `消息` 类作为输入，并返回 Message 实例。

正如你在上面的示例中所见，我们向 agent 发送了一个 `UserMessage` 实例，并检索到了回复消息，它将是一个 `AssistantMessage` 实例。助手消息和用户消息的列表构成一个聊天。

我们将会进一步了解 [ChatHistory](/neuron-v3-zh/zhi-neng-ti/chat-history-and-memory.md) 但重要的是要知道，agent 输入和输出的统一接口是 `消息` 对象。

<a href="/pages/c43edf835d021aaf4a99b145fbe60714e93cbfaa" class="button primary" data-icon="arrow-right-long">了解更多关于消息的信息</a>

### 流式 Agent 定义

除了单类封装之外，你也可以使用链式方法以流式方式在行内指示 agent：

```php
$agent = Agent::make()
    ->setAiProvider(
        new Anthropic(
            key: 'ANTHROPIC_API_KEY',
            model: 'ANTHROPIC_MODEL',
        )
    )
    ->setInstructions(
        "新的系统指令..."
    )
    ->addTool([...]);
    
$message = $agent->chat(new UserMessage(...))->getMessage();
echo $message->gentContent();
```
