برنامه نویسی

با تحویل ابزارها به مدل های AI

مقدمه ای مختصر در مورد فعال کردن LLM ها از طریق پروتکل Model Context با ساختن برنامه میزبان خود در TypeScript.

بیشتر LLM ها برای مکالمات ساده عالی هستند ، اما توانایی تعامل با محیط خود را ندارند. با استفاده از پروتکل زمینه Model (MCP) می توانیم LLM خود را به طیف گسترده ای از ابزارهای منبع باز دسترسی دهیم که به آن اجازه می دهد تا عمل عامل را انجام دهد.

در این آموزش ابتدا به ویژگی های اصلی MCP می پردازیم ، سپس یک عامل ساده AI را می سازیم که می تواند از ابزارهایی برای دسترسی به وب و نوشتن پرونده ها استفاده کند. ما این کار را با ایجاد یک میزبان انجام می دهیم که از چندین مشتری برای اتصال به سرورهای MCP موجود استفاده می کند ، ابزارهای این سرورها را در دسترس یک LLM قرار می دهد و تماس های ابزار را که توسط LLM ساخته شده است ، انجام می دهد.

چگونه پروتکل زمینه مدل کار می کند

MCP یک پروتکل باز است که نحوه ارائه برنامه های کاربردی زمینه LLMS را استاندارد می کند. این می تواند برای ایجاد سرورهایی که ابزارها و داده هایی را به مشتری MCP در یک قالب استاندارد ارائه می دهند ، استفاده شود و میزبان هایی باشد که یک یا چند نفر از این مشتری ها را به LLM متصل می کنند. سپس LLM می تواند ابزارها و داده های موجود از طریق میزبان را فراخوانی کند.

             ┌──>client_1<──>server_1
LLM<──>host<─┤
             └──>client_2<──>server_2

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

نمودار که ارتباط بین میزبان ، LLM ، مشتری و سرورها را نشان می دهد

بسیاری از سرورهای MCP در حال حاضر در دسترس هستند که هر روز بیشتر اضافه می شود. عملکرد آنها از استفاده از git ، تا کنترل Spotify ، جستجوی وب و موارد دیگر متغیر است. این سرورها می توانند LLM را به یک دستیار مفید تبدیل کنند که می تواند کارهای پیچیده ای را انجام دهد.

ابزار

ابزارها توابع قابل تماس هستند که توسط سرور در دسترس است. LLM قادر خواهد بود تا در صورت لزوم ، با استدلالهای خاص – با استدلالهای خاص خواسته شود – و برای نتیجه عملکرد به LLM برگردد. به عنوان مثال یک تابع محاسبه که دو مقدار را به خود اختصاص داده و جمع آنها را برمی گرداند.

منابع

منابع داده شده در دسترس LLM هستند. بر خلاف فراخوانی یک ابزار ، تماس با یک منبع هیچ عوارض جانبی نخواهد داشت. به عنوان مثال ، ردیف های خطای خطا از یک پایگاه داده ، اما نوشتن داده های جدید به پایگاه داده نیست.

اعلان

اعلان ها اساساً الگوهای ساخته شده توسط سرور هستند. آنها یک استدلال می کنند ، آن را در الگوی وارد می کنند و پیامی را با دستورالعمل ها باز می گردانند ، آماده برای انتقال به LLM. به عنوان مثال ، سریع فراخوانده می شود research ممکن است موضوعی را به عنوان یک استدلال مطرح کند و با دستورالعمل های دقیق در مورد چگونگی انتظار LLM برای تحقیق در مورد موضوع ، سریعاً برگردد.

ویژگی های پیشرفته

سایر ویژگی های پیشرفته تر در پروتکل وجود دارد ، مانند نمونه گیری ، ریشه و حمل و نقل رویدادهای سرور. ما برای این آموزش به آنها احتیاج نخواهیم داشت ، اما آنها ایده ای از انعطاف پذیری MCP به شما می دهند.

راه اندازی پروژه

قبل از نوشتن هر کد ، باید محیط و وابستگی های خود را تنظیم کنیم.

1. یک حساب کاربری با انسان شناسی ایجاد کنید

برای برقراری تماس با API انسان شناسی ، باید در کنسول API انسان شناسی یک حساب کاربری ایجاد کنید و اعتبار خود را اضافه کنید. 5 دلار برای این آموزش بیش از حد کافی خواهد بود.

2. یک پوشه پروژه ایجاد کنید

یک پوشه برای پروژه ایجاد کرده و فهرست کار فعلی را به این پوشه تغییر دهید.

mkdir mcp-host && cd mcp-host
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

3. وابستگی ها را نصب کنید

اگر قبلاً آن را ندارید ، PNPM را نصب کنید. می توانید آن را با استفاده از CorePack که با node.js. گنجانده شده است ، نصب کنید.

corepack enable pnpm
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس PNPM را آغاز کنید و وابستگی های مورد نیاز را نصب کنید.

pnpm init && pnpm add @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv && pnpm add -D @types/node
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ما همچنین برای اجرای سرورهای MCP که در پایتون نوشته شده اند به UV خواهیم رسید

brew install uv
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

4. تنظیم متغیرهای ENV و پیکربندی TypeScript

برای ذخیره ایمن متغیرهای ENV و اضافه کردن کلید API انسان شناسی ، که می توانید در کنسول انسان شناسی پیدا کنید ، یک فایل ایجاد کنید.

echo "ANTHROPIC_API_KEY=[YOUR API KEY HERE]" > .env
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ما همچنین برخی از پیکربندی های اساسی را برای TypeScript اضافه خواهیم کرد. ابتدا پرونده پیکربندی را ایجاد کنید.

touch tsconfig.json
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس قوانین زیر را به اضافه کنید tsconfig.json بنابراین می توانیم از سطح بالا در انتظار استفاده کنیم.

{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "target": "esnext",
    "types": ["node"]
  },
  "include": ["**/*.ts"]
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ایجاد میزبان که به ابزارها متصل می شود

قبل از شروع برقراری تماس با API LLM ، بیایید ارتباط را با سرورهای MCP بسازیم و آزمایش کنیم. فایلی به نام ایجاد کنید host.tsبشر یک کلاس را با تابعی اضافه کنید که آرایه ای از سرورها را برای اتصال به آن می برد ، یک مشتری MCP را برای هر یک ایجاد می کند و سپس مشتری را به سرور وصل می کند. برای هر مشتری ، ما تمام ابزارهای موجود از سرور متصل را دریافت می کنیم و آنها را به نقشه اضافه می کنیم که به ما امکان می دهد وقتی زمان تماس با ابزار فراخوانی می شود ، مشتری مناسب را پیدا کنیم. در حال حاضر ما فقط تمام نام های ابزار را وارد می کنیم تا ببینیم اتصالات کار کرده اند و کدام ابزارهایی را که در اختیار LLM قرار خواهیم داد.

// host.ts

import { StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio";
import { Client } from "@modelcontextprotocol/sdk/client/index";
import { Tool } from "@anthropic-ai/sdk/resources";

type Server = StdioServerParameters & { name: string };

export class Host {
  private clients: Client[] = [];
  private tools: Tool[] = [];
  private toolToClientMap: Record<string, Client> = {};

  async connect(servers: Server[]) {
    for (const server of servers) {
      const transport = new StdioClientTransport(server);
      const client = new Client({
        name: server.name + "-client",
        version: "1.0.0",
      });
      await client.connect(transport);
      this.clients.push(client);
      console.log(`Connected to ${server.name}`);

      const tools = (await client.listTools()).tools;
      for (const tool of tools) {
        if (tool.inputSchema) {
          this.tools.push({
            name: tool.name,
            description: tool.description,
            input_schema: tool.inputSchema as Tool.InputSchema,
          });
          this.toolToClientMap[tool.name] = client;
        }
      }
    }

    console.log(
      "Available tools: ",
      this.tools.map((tool) => tool.name)
    );
  }

  async disconnect() {
    for (const client of this.clients) {
      await client.close();
    }
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

انتقال ابزار به میزبان

فایلی به نام ایجاد کنید main.ts جایی که ما میزبان را آغاز خواهیم کرد و برخی از ابزارها را برای استفاده از آن منتقل می کنیم. برای این آموزش از سرورهای “Fetch” و “FileSystem” ایجاد شده توسط تیم MCP استفاده خواهیم کرد. از سرور “Fetch” می توان برای خواندن یک وب سایت در یک URL خاص استفاده کرد ، و “سیستم فایل” می تواند پرونده ها را در پوشه هایی که به آنها دسترسی دارند ، بخواند ، بنویسد و ویرایش کند. مورد سوم در args از “سیستم فایل” مسیری برای دسترسی به فهرست است. این را به مسیر پوشه ای که برای این پروژه ایجاد کرده اید تغییر دهید.

بعد از اینکه به سرورها وصل شدیم و تمام ابزارهایی را که برای پایان دادن به این روند نیاز به قطع داریم ، ذکر کردیم.

// main.ts

import { Host } from "./host";

const servers = [
  {
    name: "fetch",
    command: "uvx",
    args: ["mcp-server-fetch"],
  },
  {
    name: "filesystem",
    command: "npx",
    args: [
      "-y",
      "@modelcontextprotocol/server-filesystem",
      "/Users/yourname/mcp-host", // Replace with path to folder for this project
    ],
  },
];

const host = new Host();
await host.connect(servers);
await host.disconnect();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون برنامه را اجرا کرده و سیاهههای مربوط را بررسی کنید تا میزبان اتصال به سرورها و لیست ابزارهای موجود را ببینید.

npx tsx main.ts
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اتصال میزبان به LLM

پس از تأیید ما می توانیم به سرورهای MCP وصل شویم و ابزارهای آنها را لیست کنیم ، می توانیم میزبان را به LLM وصل کنیم و لیستی از ابزارهای موجود را LLM منتقل کنیم. مدل های Claude Anthropic به راحتی یک آرگومان ابزاری را می پذیرند و هنگامی که LLM بخواهد ابزار را فراخوانی کند ، یک بلوک “استفاده از ابزار” را در پاسخ خود قرار می دهد.

وقتی پاسخی دریافت می کنیم ، ابتدا متن را وارد می کنیم. سپس ، اگر یک بلوک استفاده از کد موجود باشد ، ما از نقشه ای که قبلاً ایجاد کردیم برای یافتن مشتری مناسب استفاده می کنیم. ما به آن مشتری می گوییم که ابزار را اجرا کند و آرگومان های ارائه شده توسط LLM را تصویب کند. سپس آن پیام را به کلود منتقل می کنیم و منتظر پاسخ هستیم. ما همچنان در کل این روند حلقه می کنیم.

پاسخ نهایی نیز یک stop_reason ارزش end_turn، نشان دهنده مدل تکمیل درخواست ، که برای بررسی ایمن تر است ، اما برای این پروژه ساده غیر ضروری است.

// host.ts

import Anthropic from "@anthropic-ai/sdk";
import { StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio";
import { Client } from "@modelcontextprotocol/sdk/client/index";
import {
  ContentBlockParam,
  ImageBlockParam,
  MessageParam,
  TextBlockParam,
  Tool,
} from "@anthropic-ai/sdk/resources";

type Server = StdioServerParameters & { name: string };
type ToolResult = {
  content: string | Array<TextBlockParam | ImageBlockParam>;
  isError: boolean;
};

export class Host {
  private llmClient: Anthropic;
  private clients: Client[] = [];
  private tools: Tool[] = [];
  private messages: MessageParam[] = [];
  private toolToClientMap: Record<string, Client> = {};

  constructor(llmClient: Anthropic) {
    this.llmClient = llmClient;
  }

  async connect(servers: Server[]) {
    for (const server of servers) {
      const transport = new StdioClientTransport(server);
      const client = new Client({
        name: server.name + "-client",
        version: "1.0.0",
      });
      await client.connect(transport);
      this.clients.push(client);
      console.log(`Connected to MCP server ${server.name}`);

      const tools = (await client.listTools()).tools;
      for (const tool of tools) {
        if (tool.inputSchema) {
          this.tools.push({
            name: tool.name,
            description: tool.description,
            input_schema: tool.inputSchema as Tool.InputSchema,
          });
          this.toolToClientMap[tool.name] = client;
        }
      }
    }
  }

  async disconnect() {
    for (const client of this.clients) {
      await client.close();
    }
  }

  private async handleResponse(response: Anthropic.Messages.Message) {
    if (response.content[0].type === "text") {
      console.log(`[Claude]: ${response.content[0].text}`);
    }

    this.messages.push({
      role: "assistant",
      content: response.content,
    });

    if (response.content[1]?.type === "tool_use") {
      const toolUse = response.content[1];
      const client = this.toolToClientMap[toolUse.name];
      console.log(`Using tool: ${toolUse.name} ...`);
      const toolResult = (await client.callTool({
        name: toolUse.name,
        arguments: toolUse.input as Record<string, unknown>,
      })) as ToolResult;

      const message = [
        {
          tool_use_id: toolUse.id,
          type: "tool_result",
          content: toolResult.content,
          is_error: toolResult.isError,
        } as const,
      ];

      await this.call(message);
    }
  }

  async call(message: string | Array<ContentBlockParam>) {
    this.messages.push({
      role: "user",
      content: message,
    });

    const response = await this.llmClient.messages.create({
      max_tokens: 2048,
      messages: this.messages,
      tools: this.tools,
      model: "claude-3-5-haiku-latest",
    });

    return await this.handleResponse(response);
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تماس با LLM

سرانجام ، ما اسکریپت اصلی را به روز می کنیم تا مشتری انسان شناسی را فوری کنیم و آن را به میزبان منتقل کنیم. سپس پیکربندی سرور را منتقل می کنیم و به میزبان می گوییم که مانند گذشته به سرورها متصل شود. سرانجام ، ما پیامی را به میزبان منتقل می کنیم و به آن دستور می دهیم که صفحه مقدمه سایت MCP را واگذار کند ، محتوا را خلاصه کنیم و خلاصه را در پرونده ای برای ما بنویسیم.

از آنجا که LLM فقط از طریق مشتری “FileSystem” به یک پوشه واحد دسترسی دارد ، این پرونده را در دایرکتوری که برای آن تهیه کرده اید می نویسد.

// main.ts

import "dotenv/config";
import Anthropic from "@anthropic-ai/sdk";
import { Host } from "./host";

const anthropicClient = new Anthropic({
  apiKey: process.env["ANTHROPIC_API_KEY"],
});

const servers = [
  {
    name: "fetch",
    command: "uvx",
    args: ["mcp-server-fetch"],
  },
  {
    name: "filesystem",
    command: "npx",
    args: [
      "-y",
      "@modelcontextprotocol/server-filesystem",
      "/Users/yourname/mcp-host", // Replace with path to folder for this project
    ],
  },
];

const host = new Host(anthropicClient);
await host.connect(servers);
await host.call(
  "Please fetch https://www.anthropic.com/news/model-context-protocol, summarise the content of that page, then write it to a markdown file."
);
await host.disconnect();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

دوباره برنامه را اجرا کنید. پس از اتمام روند ، به پرونده جدیدی که تازه ایجاد شده است نگاهی بیندازید. اگر همه خوب پیش رفت ، خلاصه خوبی از MCP را در داخل پیدا خواهید کرد.

npx tsx main.ts
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

پایان

اکنون ما با دسترسی به هر تعداد ابزار ، یک روش ساده برای تقویت قابلیت های کلود داریم. ما می توانیم به آن حافظه مداوم ، امکان گشت و گذار در وب یا حتی ارسال ایمیل از طرف خود ارائه دهیم. با تشکر از قدرت MCP.

غذای اصلی

  1. دسترسی به LLM به ابزارها به آن اجازه می دهد تا اقداماتی را انجام دهد تا بر محیط آن تأثیر بگذارد. این امر سودمندی LLM را تا حد زیادی افزایش می دهد.
  2. پروتکل زمینه مدل یک استاندارد عالی برای رابط های ابزار فراهم می کند و به ما امکان می دهد از بسیاری از سرورهای منبع باز موجود استفاده کنیم.
  3. با ایجاد یک میزبان نسبتاً ساده ، می توانیم LLM را به ابزارها وصل کنیم ، در حالی که در کنترل کامل باقی می مانند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا