Files
2026-07-13 13:31:35 +08:00

28 KiB
Raw Permalink Blame History

Adversariální multiagentní uvažování s MCP

Vzor multiagentního debatu používá dva nebo více agentů s opačnými postoji, aby produkoval spolehlivější a lépe kalibrované výstupy, než jakých by dosáhl jediný agent sám.

Úvod

V této lekci prozkoumáme adversariální multiagentní vzor — techniku, kde jsou dvěma AI agentům přiřazeny opačné postoje k tématu a musejí rozumovat, volat nástroje MCP a zpochybňovat závěry toho druhého. Třetí agent (nebo lidský recenzent) pak hodnotí argumenty a určuje nejlepší výsledek.

Tento vzor je obzvlášť užitečný pro:

  • Detekci halucinací: Druhý agent zpochybňuje neopodstatněná tvrzení prvního agenta.
  • Modelování hrozeb a bezpečnostní audity: Jeden agent tvrdí, že je systém bezpečný; druhý hledá zranitelnosti.
  • Návrh API nebo požadavků: Jeden agent obhajuje navržený design; druhý vznesí námitky.
  • Faktickou kontrolu: Oba agenti nezávisle dotazují stejné nástroje MCP a kontrolují navzájem své závěry.

Sdílením stejné sady nástrojů MCP oba agenti pracují ve stejném informačním prostředí — což znamená, že jakýkoli nesoulad odráží skutečné rozdíly v uvažování, nikoli informační asymetrii.

Výukové cíle

Na konci této lekce budete schopni:

  • Vysvětlit, proč adversariální multiagentní vzory odhalují chyby, které single-agentní pipeline přehlíží.
  • Navrhnout architekturu debaty, kde dva agenti sdílejí společnou sadu nástrojů MCP.
  • Implementovat systémové podněty "pro" a "proti", které vedou každého agenta k argumentaci za jeho přiřazený postoj.
  • Přidat sudího agenta (nebo lidský krok recenze), který syntetizuje debatu do konečného verdiktu.
  • Pochopit, jak funguje sdílení nástrojů MCP napříč souběžnými agenty.

Přehled architektury

Adversariální vzor následuje tento vysokou úrovní průběh:

flowchart TD
    Topic([Téma debaty / Tvrzení]) --> ForAgent
    Topic --> AgainstAgent

    subgraph SharedMCPServer["Sdílený server nástrojů MCP"]
        WebSearch[Nástroj pro vyhledávání na webu]
        CodeExec[Nástroj pro spouštění kódu]
        DocReader[Volitelné: Nástroj pro čtení dokumentů]
    end

    ForAgent["Agent A\n(Argumentuje PRO)"] -->|Volání nástrojů| SharedMCPServer
    AgainstAgent["Agent B\n(Argumentuje PROTI)"] -->|Volání nástrojů| SharedMCPServer

    SharedMCPServer -->|Výsledky| ForAgent
    SharedMCPServer -->|Výsledky| AgainstAgent

    ForAgent -->|Úvodní argument| Debate[(Přepis debaty)]
    AgainstAgent -->|Odpověď na argument| Debate

    ForAgent -->|Protiodpověď| Debate
    AgainstAgent -->|Protiodpověď| Debate

    Debate --> JudgeAgent["Agent rozhodčí\n(Hodnotí argumenty)"]
    JudgeAgent --> Verdict([Konečný verdikt a zdůvodnění])

    style ForAgent fill:#c2f0c2,stroke:#333
    style AgainstAgent fill:#f9d5e5,stroke:#333
    style JudgeAgent fill:#d5e8f9,stroke:#333
    style SharedMCPServer fill:#fff9c4,stroke:#333

Klíčová designová rozhodnutí

Rozhodnutí Odůvodnění
Oba agenti sdílí jeden MCP server Odstraní informační asymetrii — nesouhlas odráží uvažování, ne přístup k datům
Agentům jsou přiřazeny opačné systémové podněty Nutí každý agent prověřovat pozici toho druhého
Sudí agent syntetizuje debatu Produkuje jeden akční výstup bez lidské úzké místa
Více kol debaty Umožňuje každému agentovi reagovat na důkazy podporované nástroji toho druhého

Implementace

Krok 1 — Sdílený MCP nástrojový server

Začněte zpřístupněním nástrojů, které oba agenti budou volat. V tomto příkladu používáme minimální Python MCP server postavený na FastMCP.

Python Sdílený nástrojový server
# shared_tools_server.py
from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("debate-tools")

@mcp.tool()
async def web_search(query: str) -> str:
    """Search the web and return a short summary of the top results."""
    # Nahraďte svou preferovanou vyhledávací API (např. SerpAPI, Brave Search).
    async with httpx.AsyncClient() as client:
        response = await client.get(
            "https://api.search.example.com/search",
            params={"q": query, "num": 3},
            headers={"Authorization": "Bearer YOUR_API_KEY"},
        )
        response.raise_for_status()
        results = response.json().get("results", [])
    snippets = "\n".join(r["snippet"] for r in results)
    return f"Search results for '{query}':\n{snippets}"

@mcp.tool()
async def run_python(code: str) -> str:
    """Execute a Python snippet and return stdout + stderr.

    WARNING: This is an unsafe placeholder that runs code directly on the host.
    In production, replace with a sandboxed execution environment (e.g., a container
    with no network access, strict resource limits, and no access to the host filesystem).
    """
    import subprocess, sys, textwrap
    result = subprocess.run(
        [sys.executable, "-c", textwrap.dedent(code)],
        capture_output=True, text=True, timeout=10
    )
    return result.stdout + result.stderr

if __name__ == "__main__":
    mcp.run(transport="stdio")

Spusťte pomocí:

python shared_tools_server.py
TypeScript Sdílený nástrojový server
// shared-tools-server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { execFile } from "child_process";
import { promisify } from "util";

const execFileAsync = promisify(execFile);

const server = new McpServer({ name: "debate-tools", version: "1.0.0" });

server.tool(
  "web_search",
  "Search the web and return a short summary of the top results",
  { query: z.string() },
  async ({ query }) => {
    // Nahraďte preferovaným vyhledávacím API.
    const url = `https://api.search.example.com/search?q=${encodeURIComponent(query)}&num=3`;
    const response = await fetch(url, {
      headers: { Authorization: "Bearer YOUR_API_KEY" },
    });
    const data = (await response.json()) as { results: { snippet: string }[] };
    const snippets = data.results.map((r) => r.snippet).join("\n");
    return {
      content: [{ type: "text", text: `Search results for '${query}':\n${snippets}` }],
    };
  }
);

server.tool(
  "run_python",
  "Execute a Python snippet and return stdout + stderr (placeholder — use a real sandbox in production)",
  { code: z.string() },
  async ({ code }) => {
    // UPOZORNĚNÍ: Tento kód provádí přímo v procesu hostitele kód řízený LLM.
    // V produkci vždy spusťte uvnitř izolovaného sandboxu (např. kontejner
    // bez přístupu k síti a s přísnými omezeními zdrojů).
    // Další podrobnosti naleznete v části Bezpečnostní opatření.
    try {
      // Předávejte kód přímo jako argument python3 — bez volání shellu,
      // bez interpolace řetězců, senza rizika injekce příkazů.
      const { stdout, stderr } = await execFileAsync("python3", ["-c", code], {
        timeout: 10000,
      });
      return { content: [{ type: "text", text: stdout + stderr }] };
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : String(err);
      return { content: [{ type: "text", text: `Error: ${message}` }] };
    }
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

Spusťte pomocí:

npx ts-node shared-tools-server.ts

Krok 2 — Systémové podněty agentů

Každý agent obdrží systémový podnět, který jej zamkne do přiřazené pozice. Klíčové je, že oba agenti vědí, že jsou v debatě a musí používat nástroje na podporu svých tvrzení.

Python Systémové podněty
# prompts.py

FOR_SYSTEM_PROMPT = """You are Agent A in a structured debate.
Your role is to argue *in favour* of the proposition given to you.
Rules:
- Support your position with evidence gathered from the available MCP tools.
- Call the web_search tool to find real supporting data.
- Call the run_python tool to verify quantitative claims with code.
- When your opponent makes a claim, challenge it specifically and with evidence.
- Do not concede your position unless your opponent provides irrefutable evidence.
- Keep each turn concise (≤ 200 words)."""

AGAINST_SYSTEM_PROMPT = """You are Agent B in a structured debate.
Your role is to argue *against* the proposition given to you.
Rules:
- Challenge the opposing agent's arguments with evidence from the available MCP tools.
- Call the web_search tool to find counter-evidence.
- Call the run_python tool to verify or disprove quantitative claims with code.
- Point out logical fallacies, missing context, or unsupported assertions.
- Do not concede your position unless the evidence is irrefutable.
- Keep each turn concise (≤ 200 words)."""

JUDGE_SYSTEM_PROMPT = """You are an impartial judge evaluating a structured debate.
Your task:
1. Read the full debate transcript.
2. Identify the strongest evidence-backed arguments on each side.
3. Note any claims that were left unchallenged.
4. Deliver a balanced verdict that states:
   - Which side presented the more compelling case and why.
   - Key caveats or nuances that neither side addressed adequately.
   - A confidence score (0100) for the winning position."""

Krok 3 — Orchestrace debaty

Orchestrátor vytvoří oba agenty, spravuje tahy debaty a poté předá kompletní přepis sudímu.

Python Orchestrátor debaty
# debate_orchestrator.py
import asyncio
from anthropic import AsyncAnthropic
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from prompts import FOR_SYSTEM_PROMPT, AGAINST_SYSTEM_PROMPT, JUDGE_SYSTEM_PROMPT

client = AsyncAnthropic()

NUM_ROUNDS = 3  # Počet kol výměny názorů tam a zpět


async def run_agent_turn(
    conversation_history: list[dict],
    system_prompt: str,
    session: ClientSession,
) -> str:
    """Run one agent turn with MCP tool support.

    Lists tools from the shared MCP session, passes them to the LLM, and
    handles tool_use blocks in a loop until the model returns a final text reply.
    """
    # Získej aktuální seznam nástrojů ze sdíleného serveru MCP.
    tools_result = await session.list_tools()
    tools = [
        {
            "name": t.name,
            "description": t.description or "",
            "input_schema": t.inputSchema,
        }
        for t in tools_result.tools
    ]

    messages = list(conversation_history)
    while True:
        response = await client.messages.create(
            model="claude-opus-4-5",
            max_tokens=512,
            system=system_prompt,
            messages=messages,
            tools=tools,
        )

        # Shromáždi veškerý text, který model vytvořil.
        text_blocks = [b for b in response.content if b.type == "text"]

        # Pokud je model hotov (žádné volání nástrojů), vrať jeho textovou odpověď.
        tool_uses = [b for b in response.content if b.type == "tool_use"]
        if not tool_uses:
            return text_blocks[0].text if text_blocks else ""

        # Zaznamenej tah asistenta (může kombinovat bloky text + použití nástroje).
        messages.append({"role": "assistant", "content": response.content})

        # Proveď každé volání nástroje a shromáždi výsledky.
        tool_results = []
        for tool_use in tool_uses:
            result = await session.call_tool(tool_use.name, tool_use.input)
            tool_results.append(
                {
                    "type": "tool_result",
                    "tool_use_id": tool_use.id,
                    "content": result.content[0].text if result.content else "",
                }
            )

        # Zpětně předej modelu výsledky nástrojů.
        messages.append({"role": "user", "content": tool_results})


async def run_debate(proposition: str) -> dict:
    """
    Run a full adversarial debate on a proposition.

    Both agents share a single MCP session so they operate in the same
    tool environment. Returns a dictionary with the transcript and verdict.
    """
    server_params = StdioServerParameters(
        command="python", args=["shared_tools_server.py"]
    )
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            transcript: list[dict] = []

            # Nastartuj debatu návrhem.
            opening_message = {"role": "user", "content": f"Proposition: {proposition}"}

            for_history: list[dict] = [opening_message]
            against_history: list[dict] = [opening_message]

            for round_num in range(1, NUM_ROUNDS + 1):
                print(f"\n--- Round {round_num} ---")

                # Agent A obhajuje PRO.
                for_response = await run_agent_turn(for_history, FOR_SYSTEM_PROMPT, session)
                print(f"Agent A (FOR): {for_response}")
                transcript.append({"round": round_num, "agent": "FOR", "text": for_response})

                # Sdílej argument Agenta A s Agentem B.
                for_history.append({"role": "assistant", "content": for_response})
                against_history.append({"role": "user", "content": f"Opponent argued: {for_response}"})

                # Agent B argumentuje PROTI.
                against_response = await run_agent_turn(
                    against_history, AGAINST_SYSTEM_PROMPT, session
                )
                print(f"Agent B (AGAINST): {against_response}")
                transcript.append({"round": round_num, "agent": "AGAINST", "text": against_response})

                # Sdílej argument Agenta B s Agentem A pro další kolo.
                against_history.append({"role": "assistant", "content": against_response})
                for_history.append({"role": "user", "content": f"Opponent argued: {against_response}"})

            # Vytvoř shrnutí přepisu pro soudce.
            transcript_text = "\n\n".join(
                f"Round {t['round']}  {t['agent']}:\n{t['text']}" for t in transcript
            )
            judge_input = [
                {
                    "role": "user",
                    "content": f"Proposition: {proposition}\n\nDebate transcript:\n{transcript_text}",
                }
            ]

            # Soudce hodnotí debatu.
            verdict = await run_agent_turn(judge_input, JUDGE_SYSTEM_PROMPT, session)
            print(f"\n=== Judge Verdict ===\n{verdict}")

            return {"transcript": transcript, "verdict": verdict}


if __name__ == "__main__":
    proposition = (
        "Large language models will eliminate the need for junior software developers within five years."
    )
    result = asyncio.run(run_debate(proposition))
TypeScript Orchestrátor debaty
// debate-orchestrator.ts
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const FOR_SYSTEM_PROMPT = `You are Agent A in a structured debate.
Your role is to argue *in favour* of the proposition given to you.
Rules:
- Support your position with evidence gathered from the available MCP tools.
- Call the web_search tool to find real supporting data.
- When your opponent makes a claim, challenge it specifically and with evidence.
- Keep each turn concise (≤ 200 words).`;

const AGAINST_SYSTEM_PROMPT = `You are Agent B in a structured debate.
Your role is to argue *against* the proposition given to you.
Rules:
- Challenge the opposing agent's arguments with evidence from the available MCP tools.
- Call the web_search tool to find counter-evidence.
- Point out logical fallacies, missing context, or unsupported assertions.
- Keep each turn concise (≤ 200 words).`;

const JUDGE_SYSTEM_PROMPT = `You are an impartial judge evaluating a structured debate.
Deliver a verdict with:
1. Which side presented the more compelling case and why.
2. Key caveats or nuances that neither side addressed.
3. A confidence score (0100) for the winning position.`;

type Message = { role: "user" | "assistant"; content: string };

type DebateTurn = { round: number; agent: "FOR" | "AGAINST"; text: string };

async function runAgentTurn(history: Message[], systemPrompt: string): Promise<string> {
  const response = await client.messages.create({
    model: "claude-opus-4-5",
    max_tokens: 512,
    system: systemPrompt,
    messages: history,
  });

  const text = response.content
    .filter((block) => block.type === "text")
    .map((block) => block.text)
    .join("\n")
    .trim();

  if (!text) {
    const blockTypes = response.content.map((block) => block.type).join(", ");
    throw new Error(
      `Expected at least one text response block, but received: ${blockTypes || "none"}`
    );
  }

  return text;
}

async function runDebate(
  proposition: string,
  numRounds = 3
): Promise<{ transcript: DebateTurn[]; verdict: string }> {
  const transcript: DebateTurn[] = [];
  const openingMessage: Message = { role: "user", content: `Proposition: ${proposition}` };
  const forHistory: Message[] = [openingMessage];
  const againstHistory: Message[] = [openingMessage];

  for (let round = 1; round <= numRounds; round++) {
    console.log(`\n--- Round ${round} ---`);

    // Agent A (PRO)
    const forResponse = await runAgentTurn(forHistory, FOR_SYSTEM_PROMPT);
    console.log(`Agent A (FOR): ${forResponse}`);
    transcript.push({ round, agent: "FOR", text: forResponse });
    forHistory.push({ role: "assistant", content: forResponse });
    againstHistory.push({ role: "user", content: `Opponent argued: ${forResponse}` });

    // Agent B (PROTI)
    const againstResponse = await runAgentTurn(againstHistory, AGAINST_SYSTEM_PROMPT);
    console.log(`Agent B (AGAINST): ${againstResponse}`);
    transcript.push({ round, agent: "AGAINST", text: againstResponse });
    againstHistory.push({ role: "assistant", content: againstResponse });
    forHistory.push({ role: "user", content: `Opponent argued: ${againstResponse}` });
  }

  // Rozhodčí
  const transcriptText = transcript
    .map((t) => `Round ${t.round}  ${t.agent}:\n${t.text}`)
    .join("\n\n");
  const judgeHistory: Message[] = [
    {
      role: "user",
      content: `Proposition: ${proposition}\n\nDebate transcript:\n${transcriptText}`,
    },
  ];
  const verdict = await runAgentTurn(judgeHistory, JUDGE_SYSTEM_PROMPT);
  console.log(`\n=== Judge Verdict ===\n${verdict}`);

  return { transcript, verdict };
}

// Spustit
const proposition =
  "Large language models will eliminate the need for junior software developers within five years.";
runDebate(proposition).catch(console.error);
C# Orchestrátor debaty
// DebateOrchestrator.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Anthropic.SDK;
using Anthropic.SDK.Messaging;

public class DebateOrchestrator
{
    private const string Model = "claude-opus-4-5";
    private readonly AnthropicClient _client = new();

    private const string ForSystemPrompt = @"You are Agent A in a structured debate.
Your role is to argue *in favour* of the proposition given to you.
Rules:
- Support your position with evidence.
- Challenge your opponent's claims specifically.
- Keep each turn concise (≤ 200 words).";

    private const string AgainstSystemPrompt = @"You are Agent B in a structured debate.
Your role is to argue *against* the proposition given to you.
Rules:
- Challenge the opposing agent's arguments with evidence.
- Point out logical fallacies or unsupported assertions.
- Keep each turn concise (≤ 200 words).";

    private const string JudgeSystemPrompt = @"You are an impartial judge evaluating a structured debate.
Deliver a verdict with:
1. Which side presented the more compelling case and why.
2. Key caveats neither side addressed.
3. A confidence score (0100) for the winning position.";

    private record DebateTurn(int Round, string Agent, string Text);

    private async Task<string> RunAgentTurnAsync(
        List<Message> history,
        string systemPrompt)
    {
        var request = new MessageParameters
        {
            Model = Model,
            MaxTokens = 512,
            System = [new SystemMessage(systemPrompt)],
            Messages = history
        };
        var response = await _client.Messages.GetClaudeMessageAsync(request);
        return response.Content.OfType<TextContent>().FirstOrDefault()?.Text ?? string.Empty;
    }

    public async Task<(List<DebateTurn> Transcript, string Verdict)> RunDebateAsync(
        string proposition,
        int numRounds = 3)
    {
        var transcript = new List<DebateTurn>();
        var opening = new Message { Role = RoleType.User, Content = $"Proposition: {proposition}" };

        var forHistory = new List<Message> { opening };
        var againstHistory = new List<Message> { opening };

        for (int round = 1; round <= numRounds; round++)
        {
            Console.WriteLine($"\n--- Round {round} ---");

            // Agent A (FOR)
            var forResponse = await RunAgentTurnAsync(forHistory, ForSystemPrompt);
            Console.WriteLine($"Agent A (FOR): {forResponse}");
            transcript.Add(new DebateTurn(round, "FOR", forResponse));
            forHistory.Add(new Message { Role = RoleType.Assistant, Content = forResponse });
            againstHistory.Add(new Message { Role = RoleType.User, Content = $"Opponent argued: {forResponse}" });

            // Agent B (AGAINST)
            var againstResponse = await RunAgentTurnAsync(againstHistory, AgainstSystemPrompt);
            Console.WriteLine($"Agent B (AGAINST): {againstResponse}");
            transcript.Add(new DebateTurn(round, "AGAINST", againstResponse));
            againstHistory.Add(new Message { Role = RoleType.Assistant, Content = againstResponse });
            forHistory.Add(new Message { Role = RoleType.User, Content = $"Opponent argued: {againstResponse}" });
        }

        // Judge
        var transcriptText = string.Join("\n\n",
            transcript.Select(t => $"Round {t.Round}  {t.Agent}:\n{t.Text}"));
        var judgeHistory = new List<Message>
        {
            new() { Role = RoleType.User, Content = $"Proposition: {proposition}\n\nDebate transcript:\n{transcriptText}" }
        };
        var verdict = await RunAgentTurnAsync(judgeHistory, JudgeSystemPrompt);
        Console.WriteLine($"\n=== Judge Verdict ===\n{verdict}");

        return (transcript, verdict);
    }

    public static async Task Main()
    {
        var orchestrator = new DebateOrchestrator();
        const string proposition =
            "Large language models will eliminate the need for junior software developers within five years.";
        await orchestrator.RunDebateAsync(proposition);
    }
}

Krok 4 — Propojení nástrojů MCP do agentů

Python orchestrátor výše už ukazuje kompletní implementaci s MCP. Klíčový vzor je:

  • Jedna sdílená relace: run_debate otevře jednu ClientSession a předá ji každému volání run_agent_turn, takže oba agenti a sudí pracují ve stejném nástrojovém prostředí.
  • Seznam nástrojů na tah: run_agent_turn volá session.list_tools() pro získání aktuálních definic nástrojů a předává je modelu jako parametr tools.
  • Smyčka používání nástrojů: Když model vrátí bloky tool_use, run_agent_turn zavolá session.call_tool() pro každý z nich a výsledky předá zpět modelu, opakuje dokud model nevytvoří finální textovou odpověď.

Podívejte se na 03-GettingStarted/02-client pro kompletní příklady MCP klientů v každém jazyce.


Praktické použití

Použití Agent PRO Agent PROTI Výstup sudího
Modelování hrozeb "Tento API endpoint je bezpečný" "Zde je pět vektorů útoku" Prioritizovaný seznam rizik
Revize návrhu API "Tento design je optimální" "Tyto kompromisy jsou problematické" Doporučený návrh s výhradami
Faktická kontrola "Tvrzení X je podpořeno důkazy" "Důkaz Y odporuje tvrzení X" Verdikt s hodnocením důvěryhodnosti
Výběr technologie "Vyberte framework A" "Framework B je lepší z těchto důvodů" Rozhodovací matice s doporučením

Bezpečnostní aspekty

Při nasazování adversariálních agentů do produkce mějte na paměti:

  • Izolované spouštění kódu: Nástroj run_python musí spouštět kód v izolovaném prostředí (např. kontejner bez síťového přístupu a s omezenými zdroji). Nikdy nespouštějte nespolehlivý kód generovaný LLM přímo na hostiteli.
  • Validace volání nástrojů: Ověřujte všechny vstupy nástrojů před jejich spuštěním. Oba agenti sdílí stejný server nástrojů, takže škodlivý podnět vložený do debaty by mohl nástroje zneužít.
  • Omezení rychlosti: Implementujte omezení volání nástrojů na agenta, aby se zabránilo nekonečným smyčkám.
  • Auditní protokolování: Protokolujte každé volání nástroje a výsledek, abyste mohli zpětně zkontrolovat, jaké důkazy agent použil ke svému závěru.
  • Lidský zásah: Pro rozhodnutí s vysokou váhou směrujte verdikt sudího k lidskému recenzentovi před jeho použitím.

Viz 02-Security pro komplexní průvodce nejlepšími bezpečnostními praktikami MCP.


Cvičení

Navrhněte adversariální MCP pipeline pro jeden z těchto scénářů:

  1. Revize kódu: Agent A obhajuje pull request; Agent B hledá chyby, bezpečnostní problémy a stylistické nedostatky. Sudí shrnuje hlavní problémy.
  2. Rozhodnutí o architektuře: Agent A navrhuje mikroslužby; Agent B podporuje monolit. Sudí produkuje rozhodovací matici.
  3. Moderace obsahu: Agent A argumentuje, že obsah je bezpečný ke zveřejnění; Agent B nachází porušení pravidel. Sudí přiřazuje skóre rizika.

Pro každý scénář:

  • Definujte systémové podněty pro oba agenty a sudího.
  • Identifikujte, jaké nástroje MCP každý agent potřebuje.
  • Nakreslete tok zpráv (úvodní argument → námitka → protiargument → verdikt).
  • Popište, jak byste validovali verdikt sudího před jeho použitím.

Klíčové poznatky

  • Adversariální multiagentní vzory používají opačné systémové podněty, aby nutily agenty prověřovat uvažování toho druhého.
  • Sdílení jednoho MCP nástrojového serveru zajišťuje, že oba agenti pracují s stejnými informacemi, takže neshody se týkají uvažování, nikoli přístupu k datům.
  • Sudí agent syntetizuje debatu do akčního verdiktu bez nutnosti lidské úzké místa u každého rozhodnutí.
  • Tento vzor je zvláště mocný pro detekci halucinací, modelování hrozeb, faktickou kontrolu a revize návrhů.
  • Bezpečné spouštění nástrojů a robustní protokolování jsou klíčové při provozu adversariálních agentů v produkci.

Co dál


Prohlášení o vyloučení odpovědnosti:
Tento dokument byl přeložen za použití AI překladatelské služby Co-op Translator. Přestože usilujeme o přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Originální dokument v jeho rodném jazyce by měl být považován za autoritativní zdroj. Pro kritické informace se doporučuje profesionální lidský překlad. Nejsme odpovědní za jakákoli nedorozumění nebo mylné interpretace vyplývající z použití tohoto překladu.