Darmowy szablon automatyzacji

Skalowalny czat wieloagentowy z wykorzystaniem @wzmianek

3451
25 dni temu
18
bloków


Przegląd

Ten szablon automatyzacji pozwala na jednoczesną interakcję z wieloma agentami AI, każdy skonfigurowany z unikalnymi ustawieniami poprzez OpenRouter. Możesz wywoływać konkretnych agentów za pomocą @wzmianek lub pozwolić odpowiedzieć wszystkim naraz. Konfiguracja jest prosta i skalowalna dzięki edycji pliku JSON.

Kluczowe funkcje

  • Interakcja wieloagentowa: Rozmawiaj z wieloma osobowościami AI jednocześnie.
  • Indywidualna konfiguracja agentów: Dostosuj nazwę, instrukcje systemowe i model LLM dla każdego agenta.
  • Integracja z OpenRouter: Dostęp do szerokiej gamy modeli LLM kompatybilnych z OpenRouter.
  • Wywoływanie przez wzmianki: Wysyłaj wiadomości do konkretnych agentów używając @NazwaAgenta.
  • Odpowiedź wszystkich agentów: Jeśli nie użyjesz wzmianki, wszyscy zdefiniowani agenci odpowiedzą w losowej kolejności.
  • Skalowalność: Konfiguracja agentów jest scentralizowana w jednym węźle Code (jako JSON).
  • Pamięć konwersacji: Zachowuje historię poprzednich interakcji w ramach sesji.

Jak skonfigurować

  1. Konfiguracja ustawień (węzły Code):
    • Otwórz węzeł Define Global Settings: Edytuj JSON, aby ustawić dane użytkownika (nazwa, lokalizacja, notatki) i dodaj instrukcje systemowe, które mają obowiązywać wszystkich agentów.
    • Otwórz węzeł Define Agent Settings: Edytuj JSON, aby zdefiniować swoich agentów. Dodaj lub usuń obiekty agentów według potrzeb. Dla każdego agenta określ:
      • "name": Unikalna nazwa agenta (używana do @wzmianek).
      • "model": Identyfikator modelu OpenRouter (np. "openai/gpt-4o", "anthropic/claude-3.7-sonnet").
      • "systemMessage": Konkretne instrukcje lub persona dla tego agenta.
  2. Dodaj dane uwierzytelniające OpenRouter:
    • Zlokalizuj węzeł AI Agent.
    • Kliknij węzeł OpenRouter Chat Model podłączony poniżej przez wejście Language Model.
    • W polu 'Credential for OpenRouter API' wybierz lub utwórz swoje dane uwierzytelniające API OpenRouter.

Jak używać

  • Rozpocznij konwersację używając wejścia Chat Trigger.
  • Aby zwrócić się do konkretnych agentów, dodaj @NazwaAgenta w swojej wiadomości. Agenci odpowiedzą sekwencyjnie w kolejności, w której zostali wymienieni.
    • Przykład: "@Gemma @Claude, proszę kontynuujcie liczenie: 1" wywoła najpierw Gemmę, a następnie Claude'a.
  • Jeśli Twoja wiadomość nie zawiera żadnych @wzmianek, wszyscy zdefiniowani agenci odpowiedzą w losowej kolejności.
    • Przykład: "Co sądzicie o przyszłości AI?" wywoła Chada, Claude'a i Gemmę (na podstawie domyślnych ustawień) w losowej sekwencji.
  • Workflow zbierze odpowiedzi od wszystkich wywołanych agentów i zwróci je jako jedną sformatowaną wiadomość.

Przykłady zastosowań

Ten szablon automatyzacji może być wykorzystany w wielu scenariuszach, gdzie potrzebna jest współpraca lub różnorodne perspektywy wielu agentów AI. Oto kilka potencjalnych zastosowań:

  • Burze mózgów: Generuj różnorodne pomysły i rozwiązania poprzez interakcję z wieloma agentami jednocześnie.
  • Analiza porównawcza: Porównaj odpowiedzi różnych modeli AI na te same pytania lub problemy.
  • Scenariusze role-play: Stwórz interaktywne historie lub dialogi z wieloma postaciami AI.
  • Testowanie modeli: Oceń wydajność i jakość różnych modeli LLM w czasie rzeczywistym.
  • Wsparcie decyzyjne: Uzyskaj różne perspektywy i rekomendacje od specjalistycznych agentów przed podjęciem decyzji.
  • Edukacja: Ucz się od wielu "nauczycieli" AI, każdy z innym stylem nauczania lub specjalizacją.
  • Generowanie treści: Twórz bogatsze i bardziej zróżnicowane treści poprzez współpracę wielu agentów.

Jak to działa (szczegóły techniczne)

  • Węzły ustawień: Define Global Settings i Define Agent Settings ładują Twoje konfiguracje.
  • Ekstrakcja wzmianek: Węzeł Extract mentions analizuje dane wejściowe użytkownika (chatInput) z triggera When chat message received. Wyszukuje wzorce @NazwaAgenta pasujące do nazw zdefiniowanych w Define Agent Settings.
  • Wybór agentów:
    • Jeśli znaleziono wzmianki, tworzy listę odpowiednich konfiguracji agentów w kolejności, w której zostały wymienione.
    • Jeśli nie znaleziono wzmianek, tworzy listę wszystkich zdefiniowanych konfiguracji agentów i losowo je tasuje.
  • Pętla: Węzeł Loop Over Items iteruje przez wybraną listę agentów.
  • Dynamiczne wykonanie agenta: Wewnątrz pętli:
    • Węzeł If (First loop?) sprawdza, czy to pierwsza odpowiedź agenta. Jeśli tak (ścieżka true -> Set user message as input), przekazuje oryginalną wiadomość użytkownika do Agenta. Jeśli nie (ścieżka false -> Set last Assistant message as input), przekazuje sformatowane wyjście poprzedniego agenta (lastAssistantMessage) do następnego agenta, tworząc sekwencyjny łańcuch.
    • Węzeł AI Agent otrzymuje wiadomość wejściową. Jego System Message i Model w podłączonym węźle OpenRouter Chat Model są dynamicznie wypełniane przy użyciu wyrażeń odwołujących się do danych bieżącego agenta z pętli ({{ $('Loop Over Items').item.json.* }}).
    • Węzeł Simple Memory dostarcza historię konwersacji do AI Agent.
    • Odpowiedź agenta jest formatowana (np. NazwaAgenta:\n\nOdpowiedź) w węźle Set lastAssistantMessage.
  • <

   Skopiuj kod szablonu   
{"id":"0QQxgdQABUbbDJ0G","meta":{"instanceId":"c98909b50b05c4069bd93ee5a4753d07322c9680e81da8568e96de2c713adb5c"},"name":"Multi-Agent Conversation","tags":[],"nodes":[{"id":"218308e2-dc68-43ee-ae84-d931ad7a4ac5","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-1880,-3280],"webhookId":"a74752f3-419a-4510-856f-3efeaceec019","parameters":{"options":{}},"typeVersion":1.1},{"id":"a519fe1e-8739-46e0-9770-deb256ab96cf","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-340,-3280],"parameters":{"text":"={{ $json.chatInput }}","options":{"systemMessage":"=Current date is {{ $now.format('yyyy-MM-dd') }}. The current time is {{ $now.format('HH:MM:ss') }}.nnThe user is {{ $('Define Global Settings').item.json.user.name }}, based in {{ $('Define Global Settings').item.json.user.location }}. {{ $('Define Global Settings').item.json.user.notes }}nnYou are part of a conversation with a user and multiple AI Assistants: {{ $('Define Agent Settings').item.json.keys() }}nnYou are {{ $('First loop?').item.json.name }}.nn{{ $('Loop Over Items').item.json.systemMessage }}nn{{ $('Define Global Settings').item.json.global.systemMessage }}"},"promptType":"define"},"typeVersion":1.8},{"id":"2e00f0ff-e7af-45d5-99bc-23031b5d7892","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[-1000,-3280],"parameters":{"options":{}},"typeVersion":3},{"id":"1c979a20-46a5-4591-92da-82c1c96277c6","name":"Extract mentions","type":"n8n-nodes-base.code","position":[-1220,-3280],"parameters":{"jsCode":"// Analyzes the user message and extracts @mentions in the order they appear. If there are none, all Assistants will be called in random order.n// --- Configuration: Adjust these lines ---nconst chatMessageNodeName = 'When chat message received'; // <-- Replace with your Chat Message node namenconst agentSetupNodeName = 'Define Agent Settings'; // <-- Replace with your Agent Setup node namenconst chatTextPath = 'json.chatInput'; // <-- Replace with path to text in Chat node output (e.g., 'json.message')n// --- End Configuration ---nn// Helper function for safe nested property access (alternative to _.get)nfunction getSafe(obj, path, defaultValue = undefined) {n const pathParts = path.split('.');n let current = obj;n for (const part of pathParts) {n if (current === null || current === undefined || typeof current !== 'object' || !Object.prototype.hasOwnProperty.call(current, part)) {n return defaultValue;n }n current = current[part];n }n return current ?? defaultValue;n}nn// 1. Get Chat Textnconst chatMessageNode = $(chatMessageNodeName);nconst chatText = getSafe(chatMessageNode.item, chatTextPath, '');nn// 2. Get Agent Data and Namesnconst agentSetupNode = $(agentSetupNodeName);nconst agentData = getSafe(agentSetupNode.item, 'json', {}); // e.g., { Chad: {...}, Gemma: {...}, Claude: {...} }nconst agentNames = Object.keys(agentData);nn// 3. Find all mentions, their names, and their positions in the textnconst foundMentions = [];nif (chatText && agentNames.length > 0) {n const escapeRegex = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');n const agentPatternPart = agentNames.map(escapeRegex).join('|');nn if (agentPatternPart) {n const mentionPattern = new RegExp(`\\B@(${agentPatternPart})\\b`, 'gi');n const matches = chatText.matchAll(mentionPattern);nn for (const match of matches) {n const matchedNameCaseInsensitive = match[1];n const matchIndex = match.index;n const canonicalName = agentNames.find(name => name.toLowerCase() === matchedNameCaseInsensitive.toLowerCase());n if (canonicalName) {n foundMentions.push({ name: canonicalName, index: matchIndex });n }n }n }n}nn// 4. Sort the found mentions by their index (order of appearance)nfoundMentions.sort((a, b) => a.index - b.index);nn// 5. Map the sorted mentions to the desired output format (array of agent detail objects)nlet outputArray = foundMentions.map(mention => {n const agentDetails = agentData[mention.name];n if (!agentDetails) {n console.warn(`Could not find details for agent: ${mention.name}`);n return null;n }n return {n name: agentDetails.name,n model: agentDetails.model,n systemMessage: agentDetails.systemMessagen };n}).filter(item => item !== null);nn// 6. Check if any mentions were specifically found. If not, populate outputArray with ALL agents in RANDOM order.nif (outputArray.length === 0 && foundMentions.length === 0) { // Check if NO mentions were found initiallyn // --- NO MENTIONS FOUND ---n // Populate outputArray with ALL agents from agentDatan const allAgentDetailsArray = Object.values(agentData);nn // --- Simple Randomization ---n // Shuffle the array in place using sort with a random comparatorn allAgentDetailsArray.sort(() => 0.5 - Math.random());n // --- End Randomization ---nn // Map all agents (now in random order) to the output structuren outputArray = allAgentDetailsArray.map(agentObject => ({n name: agentObject.name,n model: agentObject.model,n systemMessage: agentObject.systemMessagen }));n} // Intentionally no 'else' here, if outputArray already had items from mentions, we use that.nn// 7. Final Output Formatting (Handles both cases: specific mentions OR all agents)n// Check if, after everything, the outputArray is *still* empty (e.g., if agentData was empty initially)nif (outputArray.length === 0) {n // If still empty, return a status or error as a fallbackn return [{ json: { status: "no_agents_available", message: "No mentions found and no agents defined." } }];n} else {n // Return the array of agent objects formatted for n8n (multiple items)n return outputArray.map(agentObject => ({ json: agentObject }));n}"},"typeVersion":2},{"id":"45f635ca-f4fa-4f6c-a32a-9722906255fd","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-192,-3060],"parameters":{"sessionKey":"={{ $('When chat message received').first().json.sessionId }}","sessionIdType":"customKey","contextWindowLength":99},"typeVersion":1.3},{"id":"5c903044-bce2-4aa8-b168-a460a4999c54","name":"Set last Assistant message as input","type":"n8n-nodes-base.set","position":[-560,-3180],"parameters":{"options":{},"assignments":{"assignments":[{"id":"38aa959a-e1e5-4c84-a7bd-ff5e0f61b62d","name":"=chatInput","type":"string","value":"={{ $('Set lastAssistantMessage').first().json.lastAssistantMessage }}"}]}},"typeVersion":3.4},{"id":"7b389b9f-1751-4bc1-9c6f-bf6a04a1e09f","name":"Set user message as input","type":"n8n-nodes-base.set","position":[-560,-3380],"parameters":{"options":{},"assignments":{"assignments":[{"id":"75b61275-7526-4431-b624-f8e098aa812d","name":"chatInput","type":"string","value":"={{ $('When chat message received').item.json.chatInput }}"}]}},"typeVersion":3.4},{"id":"a238817f-0d10-4cd4-9760-53f69bb179f7","name":"First loop?","type":"n8n-nodes-base.if","position":[-780,-3280],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"51c41fdf-f4d3-4c7a-ac18-06815a59a958","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $runIndex}}","rightValue":0}]}},"typeVersion":2.2},{"id":"415927d7-b1a4-42b2-9607-c6ff707a528b","name":"Set lastAssistantMessage","type":"n8n-nodes-base.set","position":[36,-3155],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b93025b2-f5a7-476b-bd09-b5b4af050e73","name":"lastAssistantMessage","type":"string","value":"=**{{ $('Loop Over Items').item.json.name }}**:nn{{ $json.output }}"}]}},"typeVersion":3.4},{"id":"77861e4b-a1d2-4c35-bf50-15914602a8b5","name":"Combine and format responses","type":"n8n-nodes-base.code","position":[-780,-3480],"parameters":{"jsCode":"// Get the array of items from the input (output of the loop)nconst inputItems = items;nn// Extract the 'lastAssistantMessage' from each item's JSON data.n// If the field is missing or not a string, use an empty string to avoid errors.nconst messages = inputItems.map(item => {n const message = item.json.lastAssistantMessage;n return typeof message === 'string' ? message : '';n});nn// Join the extracted messages together with a horizontal rule separatornconst combinedText = messages.join('\n\n---\n\n');nn// Return a new single item containing the combined text.n// You can rename 'output' if you like.nreturn [{ json: { output: combinedText } }];"},"typeVersion":2},{"id":"4da2f95d-bce4-4844-a23c-63ca777efbfd","name":"Define Global Settings","type":"n8n-nodes-base.code","position":[-1660,-3280],"parameters":{"jsCode":"// Configure Global settings. This includes information about you - the user - and a section of the System Message that all Assistants will see. (Assistant-specific System Message sections can be set in the 'Define Agent Settings' node.)nreturn [n {n json: {n "user": {n "name": "Jon",n "location": "Melbourne, Australia",n "notes": "Jon likes a casual, informal conversation style."n },n "global": {n "systemMessage": "Don't overdo the helpful, agreeable approach."n }n }n }n];n"},"typeVersion":2},{"id":"6639a554-9e5f-40ac-b68e-b8eaa777252d","name":"Define Agent Settings","type":"n8n-nodes-base.code","position":[-1440,-3280],"parameters":{"jsCode":"// Configure Assistants. The number of Assistants can be changed by adding or removing JSON objects. Use the OpenRouter model naming convention.nreturn [n {n json: {n "Chad": {n "name": "Chad",n "model": "openai/gpt-4o",n "systemMessage": "You are a helpful Assistant. You are eccentric and creative, and try to take discussions into unexpected territory."n },n "Claude": {n "name": "Claude",n "model": "anthropic/claude-3.7-sonnet",n "systemMessage": "You are logical and practical."n },n "Gemma": {n "name": "Gemma",n "model": "google/gemini-2.0-flash-lite-001",n "systemMessage": "You are super friendly and love to debate."n }n }n }n];n"},"typeVersion":2},{"id":"d55a7e02-3574-4d78-a141-db8d3657857b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1750,-3620],"parameters":{"color":4,"width":500,"height":500,"content":"## Step 1: Configure Settings NodesnnEdit the JSON in these nodes to:nn- Configure details about you (the user)n- Define content that will appear in all system messagesn- Define Agents.nnFor Agents, you can configure:n- How many you createn- Their namesn- The LLM model they use (choose any that are available via OpenRouter)n- Agent-specific system prompt content"},"typeVersion":1},{"id":"d3eb2797-4008-4bdb-a588-b2412ed5ffa7","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-400,-3620],"parameters":{"color":4,"width":360,"height":720,"content":"## Step 2: Connect Agent to OpenRouternnSet your OpenRouter credentials, and all other parameters including system messages and model selection are dynamically populated."},"typeVersion":1},{"id":"a6085a55-db36-42d8-8c57-c9123490581f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1940,-3900],"parameters":{"color":5,"width":2180,"height":1100,"content":"# Scalable Multi-Agent Conversationsnn"},"typeVersion":1},{"id":"d2ee6317-3a9c-4df8-8fce-87daa3530233","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1200,-3860],"parameters":{"width":380,"height":360,"content":"## About this workflownn**What does this workflow do?**nEnables you to initiate a conversation with multiple AI agents at once. Each agent can be configured with a unique name, system instructions, a different model.nn**How do I use it?**n1. Configure the settings nodes to create the Agents you need.n2. Call one or more individual agents using @Name mentions in your messages. If your message does not have @mentions, all agents will be called, in random order."},"typeVersion":1},{"id":"a190a268-7f90-4c4e-aceb-482545d0b72b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-820,-3860],"parameters":{"width":380,"height":360,"content":"**How does it work?**nSettings are configured in the first two nodes after the chat trigger. Then @mentions in your message are extracted and fed into a loop. With each loop, the agent's system message and model are dynamically populated, avoiding the need to create multiple agent nodes and complex routing logic.nnWhen all agents have had their say, their responses are combined and formatted. The use of a shared memory node enables multi-round conversations.nn**What are the limitations?**nAgents cannot call each other or respond in parallel. Agents' responses are not visible to the user until all agents have responded.nn"},"typeVersion":1},{"id":"30d8c207-9a7a-46c5-be89-0deafc6c183f","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-312,-3060],"parameters":{"model":"={{ $('Extract mentions').item.json.model }}","options":{}},"credentials":{"openRouterApi":{"id":"jB56IT6KRdHSBbkw","name":"OpenRouter account"}},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"6c0312e7-7a81-41cd-9403-8ad947100b80","connections":{"AI Agent":{"main":[[{"node":"Set lastAssistantMessage","type":"main","index":0}]]},"First loop?":{"main":[[{"node":"Set user message as input","type":"main","index":0}],[{"node":"Set last Assistant message as input","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Loop Over Items":{"main":[[{"node":"Combine and format responses","type":"main","index":0}],[{"node":"First loop?","type":"main","index":0}]]},"Extract mentions":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Define Agent Settings":{"main":[[{"node":"Extract mentions","type":"main","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Define Global Settings":{"main":[[{"node":"Define Agent Settings","type":"main","index":0}]]},"Set lastAssistantMessage":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Set user message as input":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Define Global Settings","type":"main","index":0}]]},"Combine and format responses":{"main":[[]]},"Set last Assistant message as input":{"main":[[{"node":"AI Agent","type":"main","index":0}]]}}}
  • cpde
  • Javascript
  • JS
  • Python
  • Script
  • Custom Code
  • Function
  • LangChain
  • Chat
  • Conversational
  • Plan and Execute
  • ReAct
  • Tools
Planeta AI 2025 
magic-wandmenu linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram