mcpField
T
tools

tools

github.com/launchdarklyAgent 工作流281.9k 次安装今天更新
代码仓库

关于 tools

LaunchDarkly 的 tools 技能指导 Agent 工具定义、配置变体挂载与验证,适用于管理工具调用能力的开发流程。它还涵盖不同模型提供方和框架的 schema 转换及工具调用循环。

主要功能

  1. 01创建带 JSON Schema 的工具定义
  2. 02将工具挂载到配置变体
  3. 03检查工具和配置变体
  4. 04参考提供方适配工具 schema
  5. 05追踪并限制工具调用循环

适用场景

  1. 01为 Agent 增加 API 或数据库调用能力
  2. 02将已创建工具关联到配置变体
  3. 03确认工具 schema 与配置关联有效

MCP 相关

该技能要求配置远程托管的 LaunchDarkly MCP 服务,并通过其工具创建、挂载和验证 AI 工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/launchdarkly/ai-tooling --skill tools

安装后在 Claude Code 中输入/tools确认已加载。

附带文件README.md

详细介绍

配置工具

你正在使用一项技能,它将指导你通过工具(函数调用)为 Agent 添加功能。你的任务是确定 Agent 需要执行哪些操作,创建工具定义,将其附加到不同配置,并验证其是否正常工作。

前置条件

此技能要求在你的环境中配置远程托管的 LaunchDarkly MCP 服务。

必需的 MCP 工具:

  • create-ai-tool -- 使用架构创建新的工具定义
  • update-ai-config-variation -- 将工具附加到配置变体
  • get-ai-config -- 验证工具是否已附加到变体

可选的 MCP 工具:

  • list-ai-tools -- 浏览项目中的现有工具
  • get-ai-tool -- 检查特定工具的架构

核心原则

  1. 从功能出发:创建工具前,先思考 Agent 需要执行哪些操作
  2. 框架很重要:LangGraph/CrewAI 通常会自动生成架构;OpenAI SDK 则需要手动定义架构
  3. 先创建,再附加:工具必须先存在,才能附加到配置变体
  4. 验证:Agent 获取配置以确认工具已附加
  5. 完成完整工作流:列出现有工具只是发现步骤,而非最终目标。列出后,始终继续创建所需工具、附加工具并进行验证。不要止步于探索。

工作流

第 1 步:确定所需功能

Agent 应该能够做什么?

  • 查询数据库、调用 API、执行计算、发送通知
  • 检查代码库中已有的内容(API 客户端、函数)
  • 考虑框架:LangGraph/LangChain 会自动生成架构;直接使用 SDK 则需要手动定义架构

如果用户要求先检查现有工具,或者你不了解代码库中有哪些工具,请严格按以下顺序操作:

  1. list-ai-tools -- 查看现有工具
  2. create-ai-tool -- 创建新工具(使用与现有工具不同的 key)
  3. update-ai-config-variation -- 附加该工具
  4. get-ai-config -- 验证

创建任何工具前,必须先调用 list-ai-tools 作为第一个工具调用。不要只列出工具就停止——务必完成全部四个步骤。

第 2 步:创建工具

使用 create-ai-tool 并提供:

  • key -- 工具的唯一标识符
  • description -- 清晰的描述(大模型会据此决定何时调用该工具)
  • schema -- 原始 JSON Schema(不要使用 OpenAI 函数调用封装):
{
  "type": "object",
  "properties": {
    "query": {"type": "string", "description": "Search query"},
    "limit": {"type": "integer", "default": 10}
  },
  "required": ["query"]
}
第 3 步:附加到配置变体

使用 update-ai-config-variation 附加工具。**仅传入 tools 字段。**除非用户明确要求同时更新这些字段,否则不要在此 PATCH 中一并传入 instructions、messages、model 或 parameters。自创建该变体以来,这些字段可能已在 LaunchDarkly UI 中编辑过;在附加工具的 PATCH 中包含这些字段会悄无声息地覆盖 UI 中的编辑内容。

{
  "projectKey": "my-project",
  "configKey": "support-chatbot",
  "variationKey": "default",
  "tools": [
    {"key": "search-knowledge-base", "version": 1}
  ]
}

如果你发现附加工具会清除其他字段的 UI 缺陷,不要通过重新发送之前 get-ai-config 响应中的字段来规避——这会掩盖缺陷,还可能恢复用户后来已修改的过时值。请报告该缺陷。

第 4 步:验证
  1. 使用 get-ai-tool 确认工具存在且架构有效
  2. 使用 get-ai-config 确认工具已附加到配置变体(检查输出中该变体的 tools)

报告结果:

  • 工具已创建且架构有效
  • 工具已附加到配置变体
  • 标明任何问题

调用时使用的各提供方架构

LaunchDarkly 会存储一次工具架构,即你传给 create-ai-tool 的扁平 {type, name, description, parameters} 形状。你的应用通过 config.model.parameters.tools(补全模式)或 agent_config.model.parameters.tools(Agent 模式)读取它,然后转换为提供方 SDK 所需的形状。LaunchDarkly 不会调用提供方;调用由你的代码完成。实现各工具的处理程序也仍由应用代码负责——LaunchDarkly 存储架构,你的应用负责行为。

提供方 / 框架目标形状调用时传入的位置
OpenAI Chat Completions(直接使用 SDK){type: "function", function: {name, description, parameters}}顶层 tools=[...]
Anthropic 直接使用 SDK{name, description, input_schema} — 将 parameters 重命名为 input_schema顶层 tools=[...]
Bedrock Converse{toolSpec: {name, description, inputSchema: {json: parameters}}}放入 toolConfig.tools=[...]
Gemini(google-genai){function_declarations: [{name, description, parameters}]}(Python)/ {functionDeclarations: [...]}(Node)GenerateContentConfig.tools=[...]
OpenAI Responses APILaunchDarkly 的扁平形状可直接传入,无需更改顶层 tools=[...]
LangChain / LangGraphcreateLangChainModel(config)(Node)/ create_langchain_model(config)(Python),并将 ai_config.tools(或你自己的 StructuredTool 列表)传入 bind_tools(...) / create_react_agent(tools=[...])框架原生格式;无需逐次调用转换
Strands AgentsLaunchDarkly 的扁平形状;传递参数给 Strands 模型类(AnthropicModel、OpenAIModel)之前,移除 parameters.tools — Python 中由 @tool 装饰的可调用对象仍保留在代码中Agent(tools=[...]) 构造函数;无需逐次调用转换

最简转换代码片段(Python):

ld_tools = (ai_config.model.to_dict().get("parameters") or {}).get("tools", []) or []

# OpenAI Chat Completions
openai_tools = [
    {
        "type": "function",
        "function": {
            "name": t["name"],
            "description": t.get("description", ""),
            "parameters": t.get("parameters", {"type": "object", "properties": {}}),
        },
    }
    for t in ld_tools
]

# Anthropic
anthropic_tools = [
    {
        "name": t["name"],
        "description": t.get("description", ""),
        "input_schema": t.get("parameters", {"type": "object", "properties": {}}),
    }
    for t in ld_tools
]

# Bedrock Converse
bedrock_tool_config = {
    "tools": [
        {
            "toolSpec": {
                "name": t["name"],
                "description": t.get("description", ""),
                "inputSchema": {"json": t.get("parameters", {"type": "object", "properties": {}})},
            }
        }
        for t in ld_tools
    ]
}

# Gemini
gemini_tools = [
    {
        "function_declarations": [
            {
                "name": t["name"],
                "description": t.get("description", ""),
                "parameters": t.get("parameters", {"type": "object", "properties": {}}),
            }
            for t in ld_tools
        ]
    }
] if ld_tools else []

带工具调用的 Agent 循环

使用工具的 Agent 会运行一个简短循环:调用提供方、分发任何工具调用、再次循环,直到提供方返回最终答案。无论提供方是什么,都适用以下三条规则:

  1. 限制循环次数。 MAX_STEPS = 5 是一个稳妥的默认值。失控的工具循环几乎总是提示词或架构错误,而不是需要迭代 50 次的情况。
  2. 跟踪每次工具调用。 对 Agent 实际执行的每个工具,调用 tracker.track_tool_call(tool_name) / tracker.trackToolCall(toolName)。Monitoring 选项卡会根据此项统计工具使用情况。
  3. 根据提供方的“没有更多工具调用”信号退出。 各提供方的具体信号不同:OpenAI Chat Completions → choice.finish_reason != "tool_calls";Anthropic → response.stop_reason != "tool_use";Bedrock Converse → response["stopReason"] != "tool_use";Gemini → response.function_calls 为空;OpenAI Responses API → response.output 中没有 function_call 项。

代码框架(Python、Anthropic — 其他提供方结构相同,但需使用各自的停止原因检查和工具结果格式):

messages = [{"role": "user", "content": initial_input}]
MAX_STEPS = 5
for _ in range(MAX_STEPS):
    response = tracker.track_metrics_of(
        anthropic_metrics,
        lambda: anthropic_client.messages.create(
            model=agent.model.name,
            system=agent.instructions,
            messages=messages,
            tools=anthropic_tools,
            **params,
        ),
    )
    if response.stop_reason != "tool_use":
        break

    messages.append({"role": "assistant", "content": response.content})

    tool_results = []
    for block in response.content:
        if block.type != "tool_use":
            continue
        if block.name not in tool_handlers:
            raise ValueError(f"Unknown tool: {block.name}")
        result = tool_handlers[block.name](**block.input)
        tracker.track_tool_call(block.name)
        tool_results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": result,
        })
    messages.append({"role": "user", "content": tool_results})

各提供方的工具调用载荷形状见 built-in-metrics 参考文档:

Orchestrator 说明

LangGraph、CrewAI 和 AutoGen 通常会根据函数定义生成架构。你仍需在 LaunchDarkly 中创建工具,并将键附加到变体,以便 SDK 知道有哪些可用工具。

边缘情况

情况操作
工具已存在(409)使用现有工具,或使用不同的键创建工具
Schema 无效使用原始 JSON Schema 格式(type: object, properties, required)
假定的端点错误这些工具使用 /ai-tools,而不是 /ai-configs/tools

不要这样做

  • 不要在创建配置时尝试附加工具——之后再更新变体
  • 不要省略清晰的工具描述(大模型需要依靠这些描述来判断何时调用工具)
  • 更新变体后,不要忘记验证工具是否已附加
  • 不要在附加工具的 PATCH 中捆绑 instructions、messages、model 或 parameters。除非用户明确要求更新多个字段,否则只发送 tools——捆绑的 PATCH 会在不提示的情况下覆盖其他字段的 UI 编辑内容。

相关技能

  • configs-create——在附加工具之前创建配置
  • configs-variations——管理具有不同工具集的变体

评论

支持 Markdown