Neuron 工作链
工作链通过调用Agent::chat()加入多个节点,在第一个节点执行结束时触发工作链,执行下一个节点。
若不想看显示代码的长篇大论,可以看总结的流程图~
构建
从Agent::chat()开始,获取这次对话的工作节点,并组装。
自定义Agent继承NeuronAI\Agent\Agent。
调用$message = $agent->chat($msg3);实际是执行NeuronAI\Agent\Agent::chat()。
NeuronAI\Agent\Agent 类源码
public function chat(Message | array $messages = [], ?InterruptRequest $interrupt = null): Message {……$this->compose( new ChatNode($this->resolveProvider()), ); //获取回调$handler = parent::start($interrupt); //启动工作流$finalState = $handler->getResult();……} protected function compose(array | Node $nodes): void { ……$toolNode = $this->parallelToolCalls() ? new ParallelToolNode($this->toolMaxTries) : new ToolNode($this->toolMaxTries);$this->addNodes([ ...$nodes,$toolNode, ]);}
执行
Agent继承NeuronAI\Workflow\Workflow,chat()方法中调用父类Workflow::start($interrupt)获取对应Handler。
Handler中调用NeuronAI\Workflow\Workflow::run(), 使用NeuronAI\Workflow\Workflow::bootstrap()反射节点,使用NeuronAI\Workflow\Workflow::resolveStartEvent()调用自定义工具。
NeuronAI\Workflow\Workflow::resolveStartEvent()调用startEvent方法。
NeuronAI\Agent\Agent重写startEvent方法,通过NeuronAI\Workflow\HandleTool::bootstrapTools()方法调用自定义tools()。
反射结果加入NeuronAI\Workflow\Workflow::eventNodeMap数组中,在NeuronAI\Workflow\Workflow::execute()中执行。
NeuronAI\Agent\Agent 类源码
class Agent extends Workflow implements AgentInterface { use HandleTools; ……}
NeuronAI\Workflow\Workflow 类源码
class Workflow implements WorkflowInterface{ …… public function start(?InterruptRequest $resumeRequest = null): WorkflowHandler {$isResume = $resumeRequest instanceof InterruptRequest;return new WorkflowHandler($this, $isResume, $resumeRequest); } …… public function run(): Generator|WorkflowState { EventBus::emit('workflow-start', $this, new WorkflowStart($this->eventNodeMap)); try {$this->bootstrap(); } catch (WorkflowException $exception) { EventBus::emit('error', $this, new AgentError($exception)); throw $exception; }$startEvent = $this->resolveStartEvent(); yield from $this->execute($startEvent, $this->eventNodeMap[$startEvent::class]); EventBus::emit('workflow-end', $this, new WorkflowEnd($this->resolveState()));return$this->resolveState(); } …… protected function resolveStartEvent(): Event {return$this->startEvent ?? $this->startEvent = $this->startEvent(); } …… protected function bootstrap(): void {$this->loadEventNodeMap();$this->validate(); } …… protected function loadEventNodeMap(): void { ……$reflection = new ReflectionClass($node);$method = $reflection->getMethod('__invoke');$parameters = $method->getParameters();$firstParam = $parameters[0];$firstParamType = $firstParam->getType();if ($firstParamType instanceof ReflectionNamedType) {$eventClass = $firstParamType->getName();if (isset($this->eventNodeMap[$eventClass])) { throw new WorkflowException("Node for event {$eventClass} already exists"); }$this->eventNodeMap[$eventClass] = $node; } …… } ……}
NeuronAI\Workflow\WorkflowHandler 类源码
public function getResult(): WorkflowState{if (!isset($this->result)) { foreach ($this->streamEvents() as $event) { } }return$this->result;}public function streamEvents(?StreamAdapterInterface $adapter = null): Generator{ ……$generator = $this->resume ? $this->workflow->resume($this->resumeRequest) : $this->workflow->run();while ($generator->valid()) {$event = $generator->current(); // Transform through adapter or yield raw eventif ($adapter instanceof StreamAdapterInterface) { foreach ($adapter->transform($event) as $output) { yield $output; } } else { yield $event; }$generator->next(); } ……}
NeuronAI\Agent\Agent 类源码
protected function startEvent(): Event {return new AIInferenceEvent($this->resolveInstructions(),$this->bootstrapTools() ); }
NeuronAI\Workflow\HandleTool 类源码
public function bootstrapTools(): array{ …… public function getTools(): array {return array_merge($this->tools, $this->tools()); } …… public function bootstrapTools(): array { …… foreach ($this->getTools() as $tool) { ……$innerTools = $tool->tools(); …… } …… }}
总结