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

28 KiB
Raw Permalink Blame History

Vaenulik mitmeagendiline mõtlemine MCP-ga

Mitmeagendiline vaidlusmuster kasutab kahte või enamat vastanduvat seisukohta omavat agenti, et toota usaldusväärsemaid ja paremini kalibreeritud väljundeid kui ühe agenti üksinda suudab.

Sissejuhatus

Selles õppetükis uurime vaenulikku mitmeagendilist mustrit — võtet, kus kaks tehisintellekti agenti saavad teemal vastanduvad seisukohad ning peavad põhjendama, kutsuma MCP tööriistu ja vaidlustama teineteise järeldusi. Kolmas agent (või inimhindaja) hindab seejärel argumente ja otsustab parima tulemuse.

See muster on eriti kasulik:

  • Hallutsinatsioonide tuvastamiseks: teine agent esitab väljakutseid kinnituseta väidetele, mida esimene agent teeb.
  • Ohumudeldamiseks ja turvauuringuteks: üks agent väidab, et süsteem on turvaline; teine otsib haavatavusi.
  • API või nõuete disainiks: üks agent kaitseb ettepanekut; teine esitab vastuväiteid.
  • Faktide kontrollimiseks: mõlemad agendid küsivad iseseisvalt samu MCP tööriistu ja kontrollivad teineteise järeldusi.

Jagades samu MCP tööriistu tegutsevad mõlemad agendid samas infokeskkonnas — mis tähendab, et eriarvamused peegeldavad tegelikke põhjenduste erinevusi, mitte informatsiooni asümmeetriat.

Õpieesmärgid

Selle õppetüübi lõpuks oskad sa:

  • Selgitada, miks vaenulik mitmeagendiline muster tabab vigu, mida üheagentset torujuhet jääb märkamata.
  • Kujundada vaidlus-aruhetuuri, kus kaks agenti jagavad ühist MCP tööriistakomplekti.
  • Rakendada "poolt" ja "vastu" süsteemipäringuid, mis juhivad iga agenti argumenteerima talle määratud seisukohta.
  • Lisada hindaja agent (või inimhindamise samm), mis sünteesib vaidluse lõplikuks otsuseks.
  • Mõista, kuidas MCP tööriistade jagamine toimib paralleelsetel agentidel.

Arhitektuuri ülevaade

Vaenuliku mustri kõrgetasemeline töövoog on järgmine:

flowchart TD
    Topic([Debitsi teema / Väide]) --> ForAgent
    Topic --> AgainstAgent

    subgraph SharedMCPServer["Jagatud MCP tööriista server"]
        WebSearch[Veebi otsingu tööriist]
        CodeExec[Koodi täitmise tööriist]
        DocReader[Valikuline: Dokumendi lugeja tööriist]
    end

    ForAgent["Agent A\n(Argumenteerib POOLT)"] -->|Tööriista kõned| SharedMCPServer
    AgainstAgent["Agent B\n(Argumenteerib VASTU)"] -->|Tööriista kõned| SharedMCPServer

    SharedMCPServer -->|Tulemused| ForAgent
    SharedMCPServer -->|Tulemused| AgainstAgent

    ForAgent -->|Algne argument| Debate[(Debitsi transkriptsioon)]
    AgainstAgent -->|Vastus| Debate

    ForAgent -->|Vastus vastuväidetele| Debate
    AgainstAgent -->|Vastus vastuväidetele| Debate

    Debate --> JudgeAgent["Kohtunik Agent\n(Hindab argumente)"]
    JudgeAgent --> Verdict([Lõplik otsus & põhjendus])

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

Olulised disainivalikud

Valik Põhjendus
Mõlemad agendid kasutavad üht MCP serverit Eemaldab infoasümmeetria — eriarvamused peegeldavad põhjendamist, mitte andmetele ligipääsu
Agendidel on vastanduvad süsteemipäringud Sunnib iga agenti tugevalt testima vastaspoole seisukohta
Hindaja agent sünteesib vaidluse Toob välja ühe tegutsemisvõimelise tulemuse ilma inim-pudelistikuta
Mitme vooru vaidlus Võimaldab igal agendil reageerida teise tööriistaga toetatud tõenditele

Rakendus

Samm 1 — Jagatud MCP tööriistaserver

Alustage tööriistade avalikustamisest, mida mõlemad agendid kutsuvad. Selles näites kasutame minimaalset Python MCP serverit, mis põhineb FastMCP-l.

Python Jagatud tööriistaserver
# 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."""
    # Asendage oma eelistatud otsingu API-ga (nt 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")

Käivitage järgmiselt:

python shared_tools_server.py
TypeScript Jagatud tööriistaserver
// 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 }) => {
    // Asenda eelistatud otsingu API-ga.
    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 }) => {
    // HOIATUS: See käivitab LLM-i juhitud koodi otse host-protsessis.
    // Tootmiskeskkonnas käivita alati isoleeritud liivakastis (nt konteineris
    // ilma võrguühenduseta ja range ressursside piirangutega).
    // Vaata täpsemat infot turvakaalutluste jaotises.
    try {
      // Edasta kood otse argumendina python3-le — ilma kestakutsuta,
      // ilma stringide interpoleerimiseta, ilma käsu süstimise riskita.
      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);

Käivitage järgmiselt:

npx ts-node shared-tools-server.ts

Samm 2 — Agendi süsteemipäringud

Iga agent saab süsteemipäringu, mis lukustab selle talle määratud seisukohta. Oluline on, et mõlemad agendid teavad, et on vaidluses ning peavad kasutama tööriistu oma väidete toetuseks.

Python Süsteemipäringud
# 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."""

Samm 3 — Vaidluse orkestreerija

Orkestreerija loob mõlemad agendid, juhib vaidlusvoorusid ja edastab seejärel kogu vestluse hindajale.

Python Vaidluse orkestreerija
# 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  # Edasis-tagasi vahetusringide arv


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.
    """
    # Hangi jagatud MCP serverist praegune tööriistade nimekiri.
    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,
        )

        # Kogu kõik mudeli toodetud tekstid.
        text_blocks = [b for b in response.content if b.type == "text"]

        # Kui mudel on lõpetanud (tööriistakõnesid pole), tagasta selle tekstvastus.
        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 ""

        # Salvestage abistaja kord (võib segada teksti + tööriistakasutuse plokke).
        messages.append({"role": "assistant", "content": response.content})

        # Käivita iga tööriistakutse ja kogu tulemused.
        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 "",
                }
            )

        # Sisesta tööriistade tulemused mudelile tagasi.
        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] = []

            # Alusta debatti ettepanekuga.
            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 argumenteerib POOLT.
                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})

                # Jaga Agenti A argumenti Agendi B-ga.
                for_history.append({"role": "assistant", "content": for_response})
                against_history.append({"role": "user", "content": f"Opponent argued: {for_response}"})

                # Agent B argumenteerib VASTU.
                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})

                # Jaga Agenti B argumenti Agendi A-ga järgmiseks ringiks.
                against_history.append({"role": "assistant", "content": against_response})
                for_history.append({"role": "user", "content": f"Opponent argued: {against_response}"})

            # Koosta transkriptsiooni kokkuvõte kohtunikule.
            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}",
                }
            ]

            # Kohtunik hindab arutelu.
            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 Vaidluse orkestreerija
// vaidluse-talitseja.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} ---`);

    // Esindaja A (TOETAB)
    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}` });

    // Esindaja B (VASTU)
    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}` });
  }

  // Kohtunik
  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 };
}

// Käivita
const proposition =
  "Large language models will eliminate the need for junior software developers within five years.";
runDebate(proposition).catch(console.error);
C# Vaidluse orkestreerija
// 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);
    }
}

Samm 4 — MCP tööriistade ühendamine agentidesse

Ülaltoodud Python orchestratorkood näitab täielikku MCP-ga ühendatud implementatsiooni. Põhimustrid on:

  • Üks jagatud sessioon: run_debate avab ühe ClientSession ja edastab selle igale run_agent_turn kutsumisele, nii töötavad mõlemad agendid ja hindaja samas tööriistakeskkonnas.
  • Tööriistade nimekiri iga vooru kohta: run_agent_turn kutsub session.list_tools() ja saadud tööriistade definitsioonid antakse mudelile tools parameetrina.
  • Tööriista kasutamise tsükkel: Kui mudel tagastab tool_use blokke, kutsub run_agent_turn iga tööriista puhul session.call_tool() ja suunab tulemused mudelile tagasi, kordades seda kuni mudel toodab lõpliku tekstiväljundi.

Vaata 03-GettingStarted/02-client täielikke MCP kliendi näiteid igas keeles.


Praktilised kasutusjuhtumid

Kasutusjuhud POOLT agent VASTU agent Hindaja väljund
Ohumudelid "See API lõpp-punkt on turvaline" "Siin on viis ründesuunad" Prioriteeritud riskide nimekiri
API disaini ülevaade "See disain on optimaalne" "Need kompromissid on probleemsed" Soovitatud disain koos hoiatusedega
Faktide kontroll "Väide X on tõendusega toetatud" "Tõend Y lükkab väite X ümber" Usaldusväärsusega hinnatud otsus
Tehnoloogia valik "Vali raamistiku A" "Raamistik B on nende põhjuste tõttu parem" Otsustusmaatriks koos soovitusega

Turvalisuse kaalutlused

Vaenulike agentide käitamisel tootmiskeskkonnas pea silmas:

  • Koodi käitus turvalises keskkonnas: run_python tööriist peab töötama isoleeritud keskkonnas (nt konteiner ilma võrgule ligipääsuta ja ressursipiirangutega). Ära kunagi käivita tundmatut LLM poolt genereeritud koodi otse hostil.
  • Tööriistakutsete valideerimine: Kontrolli kõiki tööriistasisendeid enne täitmist. Mõlemad agendid jagavad sama tööriistaserverit, seega pahatahtlik päring vaidluses võib püüda tööriistu väärkasutada.
  • Kiirusepiirangud: Rakenda iga agendi kohta tööriistakutsete piirmäärad, et vältida lõputuid silmuseid.
  • Auditilogimine: Logi iga tööriistakutse ja selle tulemus, et saaksid üle vaadata, milliseid tõendeid iga agent kasutas järelduste tegemisel.
  • Inimene lõpus: Kõrge riskiga otsuste puhul saada hindaja otsus enne täitmist inimesele ülevaatamiseks.

Vaata 02-Security MCP turvalisuse parimate tavade põhjalikku juhendit.


Harjutus

Kujunda vaenulik MCP torujuhe ühes järgnevatest stsenaariumitest:

  1. Koodi ülevaade: Agent A kaitseb pull-päringut; agent B otsib vigu, turvaauke ja stiiliprobleeme. Hindaja võtab kokku peamised probleemid.
  2. Arhitektuuri otsus: Agent A pakub mikroteenuseid; agent B toetab monoliiti. Hindaja koostab otsustusmaatriksi.
  3. Sisu modereerimine: Agent A väidab, et sisu on ohutu avaldamiseks; agent B leiab poliitikavigu. Hindaja määrab riskiskoori.

Iga stsenaariumi puhul:

  • Määra süsteemipäringud mõlemale agentile ja hindajale.
  • Määra, milliseid MCP tööriistu iga agent vajab.
  • Joonista sõnumivoog (avasõna → vastuväide → vastuse vastuväide → otsus).
  • Kirjelda, kuidas valideeriksid hindaja otsust enne selle täitmist.

Peamised järeldused

  • Vaenulik mitmeagendiline muster kasutab vastanduvaid süsteemipäringuid, et sundida agente teineteise põhjendusi kriitiliselt kontrollima.
  • Ühe MCP tööriistaserveri jagamine tagab, et mõlemad agendid töötavad samast infokeskkonnast, nii et eriarvamused on põhjenduse, mitte andmete ligipääsu teemal.
  • Hindaja agent sünteesib vaidluse tegutsemisvõimeliseks otsuseks ilma iga otsuse juures inimtõkestuseta.
  • Muster on eriti tugev hallutsinatsioonide tuvastuses, ohumudeldamises, faktide kontrollis ja disaini ülevaates.
  • Turvaline tööriistade täitmine ja põhjalik logimine on tootmiskeskkonnas vaenulike agentide jaoks hädavajalikud.

Mis järgmiseks


Vastutusest loobumine:
See dokument on tõlgitud kasutades tehisintellekti tõlketeenust Co-op Translator. Kuigi püüame täpsust, palun olge teadlikud, et automaatsed tõlked võivad sisaldada vigu või ebatäpsusi. Originaaldokument selle emakeeles tuleks pidada autoriteetseks allikaks. Olulise info puhul soovitatakse kasutada professionaalset inimtõlget. Me ei vastuta selle tõlke kasutamisest tulenevate arusaamatuste või valesti tõlgendamise eest.