Dropstone Docs

커스텀 도구

Dropstone에서 LLM이 호출할 수 있는 도구를 만듭니다.

커스텀 도구는 대화 중에 LLM이 호출할 수 있는 함수입니다. Dropstone의 read, write, bash 같은 내장 도구와 함께 작동합니다.


도구 만들기

도구는 TypeScript 또는 JavaScript 파일로 정의됩니다. 도구 정의 자체는 TS/JS이지만, 실제 작업은 모든 언어로 구현할 수 있습니다: 셸 스크립트, Python, Go, Bun의 셸 헬퍼에서 실행할 수 있는 모든 것.


위치

도구는 다음 위치에 정의할 수 있습니다:

  • 프로젝트의 .dropstone/tools/ 디렉토리에 배치하여 로컬로 정의
  • 또는 ~/.config/dropstone/tools/에 배치하여 전역으로 정의

구조

도구를 만드는 가장 쉬운 방법은 타입 안전성과 검증을 제공하는 tool() 헬퍼를 사용하는 것입니다.

import { tool } from "@blankline/dropstone-plugin"

export default tool({
  description: "프로젝트 데이터베이스 쿼리",
  args: {
    query: tool.schema.string().describe("실행할 SQL 쿼리"),
  },
  async execute(args) {
    // 데이터베이스 로직을 여기에 작성하세요
    return `쿼리 실행됨: ${args.query}`
  },
})

파일명도구 이름이 됩니다. 위의 코드는 database 도구를 만듭니다.


파일당 여러 도구

단일 파일에서 여러 도구를 내보낼 수도 있습니다. 각 내보내기는 별도의 도구가 되며 이름은 **<filename>_<exportname>**입니다:

import { tool } from "@blankline/dropstone-plugin"

export const add = tool({
  description: "두 숫자를 더합니다",
  args: {
    a: tool.schema.number().describe("첫 번째 숫자"),
    b: tool.schema.number().describe("두 번째 숫자"),
  },
  async execute(args) {
    return args.a + args.b
  },
})

export const multiply = tool({
  description: "두 숫자를 곱합니다",
  args: {
    a: tool.schema.number().describe("첫 번째 숫자"),
    b: tool.schema.number().describe("두 번째 숫자"),
  },
  async execute(args) {
    return args.a * args.b
  },
})

이는 두 개의 도구를 만듭니다: math_addmath_multiply.


내장 도구와의 이름 충돌

커스텀 도구는 도구 이름으로 키가 지정됩니다. 커스텀 도구가 내장 도구와 같은 이름을 사용하면 커스텀 도구가 우선합니다.

예를 들어, 이 파일은 내장 bash 도구를 대체합니다:

import { tool } from "@blankline/dropstone-plugin"

export default tool({
  description: "제한된 bash 래퍼",
  args: {
    command: tool.schema.string(),
  },
  async execute(args) {
    return `차단됨: ${args.command}`
  },
})

Note:

내장 도구를 의도적으로 대체하려는 경우가 아니면 고유한 이름을 사용하세요. 내장 도구를 비활성화하되 재정의하지 않으려면 권한을 사용하세요.


인수

tool.schema를 사용할 수 있으며, 이는 단순히 Zod입니다.

args: {
  query: tool.schema.string().describe("실행할 SQL 쿼리")
}

Zod를 직접 가져오고 일반 객체를 반환할 수도 있습니다:

import { z } from "zod"

export default {
  description: "도구 설명",
  args: {
    param: z.string().describe("매개변수 설명"),
  },
  async execute(args, context) {
    // 도구 구현
    return "결과"
  },
}

컨텍스트

도구는 현재 세션에 대한 컨텍스트를 받습니다:

import { tool } from "@blankline/dropstone-plugin"

export default tool({
  description: "프로젝트 정보 가져오기",
  args: {},
  async execute(args, context) {
    // 컨텍스트 정보에 접근
    const { agent, sessionID, messageID, directory, worktree } = context
    return `에이전트: ${agent}, 세션: ${sessionID}, 메시지: ${messageID}, 디렉토리: ${directory}, Worktree: ${worktree}`
  },
})

세션 작업 디렉토리에는 context.directory를 사용하세요. git worktree 루트에는 context.worktree를 사용하세요.


예제

Python으로 도구 작성하기

원하는 모든 언어로 도구를 작성할 수 있습니다. 다음은 Python을 사용하여 두 숫자를 더하는 예제입니다.

먼저 Python 스크립트로 도구를 만듭니다:

import sys

a = int(sys.argv[1])
b = int(sys.argv[2])
print(a + b)

그런 다음 이를 호출하는 도구 정의를 만듭니다:

import { tool } from "@blankline/dropstone-plugin"
import path from "path"

export default tool({
  description: "Python을 사용하여 두 숫자 더하기",
  args: {
    a: tool.schema.number().describe("첫 번째 숫자"),
    b: tool.schema.number().describe("두 번째 숫자"),
  },
  async execute(args, context) {
    const script = path.join(context.worktree, ".dropstone/tools/add.py")
    const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text()
    return result.trim()
  },
})

여기서는 Bun.$ 유틸리티를 사용하여 Python 스크립트를 실행합니다.

Ctrl+I