tools

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AI Config Tools

AI Config工具

You're using a skill that will guide you through adding capabilities to your AI agents through tools (function calling). Your job is to identify what your AI needs to do, create tool definitions, attach them to variations, and verify they work.
你正在使用一项技能,它将引导你通过工具(函数调用)为AI Agent添加能力。你的任务是确定AI需要执行的任务、创建工具定义、将其关联到变体,并验证功能是否正常。

Prerequisites

前提条件

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.
Required MCP tools:
  • create-ai-tool
    -- create a new tool definition with a schema
  • update-ai-config-variation
    -- attach tools to an AI Config variation
  • get-ai-config
    -- verify tools are attached to the variation
Optional MCP tools:
  • list-ai-tools
    -- browse existing tools in the project
  • get-ai-tool
    -- inspect a specific tool's schema
本技能要求环境中已配置远程托管的LaunchDarkly MCP服务器。
必需的MCP工具:
  • create-ai-tool
    —— 创建带有Schema的新工具定义
  • update-ai-config-variation
    —— 将工具关联到AI Config变体
  • get-ai-config
    —— 验证工具是否已关联到变体
可选的MCP工具:
  • list-ai-tools
    —— 浏览项目中已有的工具
  • get-ai-tool
    —— 查看特定工具的Schema

Core Principles

核心原则

  1. Start with Capabilities: Think about what your AI needs to do before creating tools
  2. Framework Matters: LangGraph/CrewAI often auto-generate schemas; OpenAI SDK needs manual schemas
  3. Create Before Attach: Tools must exist before you can attach them to variations
  4. Verify: The agent fetches the config to confirm attachment
  5. Complete the Full Workflow: Listing existing tools is a discovery step, not the end goal. After listing, always proceed to create the requested tool, attach it, and verify. Do not stop after exploration.
  1. 从能力出发:在创建工具前,先思考AI需要完成什么任务
  2. 框架很重要:LangGraph/CrewAI通常会自动生成Schema;OpenAI SDK需要手动编写Schema
  3. 先创建再关联:工具必须先存在,才能关联到变体
  4. 验证:Agent会获取配置以确认关联成功
  5. 完成完整流程:列出已有工具只是发现步骤,而非最终目标。列出后,务必继续创建所需工具、关联并验证,不要停留在探索阶段。

Workflow

工作流程

Step 1: Identify Needed Capabilities

步骤1:确定所需能力

What should the AI be able to do?
  • Query databases, call APIs, perform calculations, send notifications
  • Check what exists in the codebase (API clients, functions)
  • Consider framework: LangGraph/LangChain auto-generate schemas; direct SDK needs manual schemas
If the user asks to check existing tools first, or you have no codebase context about what tools exist, follow this exact order:
  1. list-ai-tools
    -- explore what exists
  2. create-ai-tool
    -- create the new tool (with a key different from existing ones)
  3. update-ai-config-variation
    -- attach it
  4. get-ai-config
    -- verify
Call
list-ai-tools
as your first tool call before any creation. Never stop after listing alone -- always proceed through all four steps.
AI应该能做什么?
  • 查询数据库、调用API、执行计算、发送通知
  • 检查代码库中已有的内容(API客户端、函数)
  • 考虑框架:LangGraph/LangChain会自动生成Schema;直接使用SDK需要手动编写Schema
如果用户要求先检查已有工具,或者你没有关于代码库中工具的上下文,请严格按照以下顺序操作:
  1. list-ai-tools
    —— 探索已有工具
  2. create-ai-tool
    —— 创建新工具(使用与已有工具不同的key)
  3. update-ai-config-variation
    —— 关联工具
  4. get-ai-config
    —— 验证
在创建任何工具之前,首先调用
list-ai-tools
。不要仅停留在列出工具这一步——务必完成全部四个步骤。

Step 2: Create Tools

步骤2:创建工具

Use
create-ai-tool
with:
  • key
    -- unique identifier for the tool
  • description
    -- clear description (the LLM uses this to decide when to call the tool)
  • schema
    -- raw JSON Schema (do NOT use the OpenAI function calling wrapper):
json
{
  "type": "object",
  "properties": {
    "query": {"type": "string", "description": "Search query"},
    "limit": {"type": "integer", "default": 10}
  },
  "required": ["query"]
}
使用
create-ai-tool
时需提供:
  • key
    —— 工具的唯一标识符
  • description
    —— 清晰的描述(LLM会根据此决定何时调用工具)
  • schema
    —— 原始JSON Schema(请勿使用OpenAI函数调用包装器):
json
{
  "type": "object",
  "properties": {
    "query": {"type": "string", "description": "Search query"},
    "limit": {"type": "integer", "default": 10}
  },
  "required": ["query"]
}

Step 3: Attach to Variation

步骤3:关联到变体

Use
update-ai-config-variation
to attach tools. Pass only the
tools
field.
Do not bundle
instructions
,
messages
,
model
, or
parameters
into this PATCH unless the user has explicitly asked you to also update those fields. Those fields may have been edited in the LaunchDarkly UI since the variation was created, and including them in a tool-attachment PATCH will silently clobber the UI edits.
json
{
  "projectKey": "my-project",
  "configKey": "support-chatbot",
  "variationKey": "default",
  "tools": [
    {"key": "search-knowledge-base", "version": 1}
  ]
}
If you observe a UI-clear bug where attaching tools wipes other fields, do not work around it by re-sending those fields from the previous
get-ai-config
response
— that masks the bug and can resurrect stale values that the user has since edited. Report the bug instead.
使用
update-ai-config-variation
关联工具。仅传递
tools
字段
。除非用户明确要求同时更新其他字段,否则不要将
instructions
messages
model
parameters
包含在此次PATCH请求中。自变体创建以来,这些字段可能已在LaunchDarkly UI中被编辑,将它们包含在工具关联的PATCH请求中会静默覆盖UI中的编辑内容。
json
{
  "projectKey": "my-project",
  "configKey": "support-chatbot",
  "variationKey": "default",
  "tools": [
    {"key": "search-knowledge-base", "version": 1}
  ]
}
如果遇到关联工具会清除其他字段的UI漏洞,不要通过重新发送之前
get-ai-config
响应中的那些字段来解决
——这会掩盖漏洞,还可能恢复用户已编辑过的陈旧值。应报告该漏洞。

Step 4: Verify

步骤4:验证

  1. Use
    get-ai-tool
    to confirm the tool exists with a valid schema
  2. Use
    get-ai-config
    to confirm the tool is attached to the variation (check
    tools
    in the variation's output)
Report results:
  • Tool created with valid schema
  • Tool attached to variation
  • Flag any issues
  1. 使用
    get-ai-tool
    确认工具已存在且Schema有效
  2. 使用
    get-ai-config
    确认工具已关联到变体(检查变体输出中的
    tools
    字段)
报告结果:
  • 工具已创建且Schema有效
  • 工具已关联到变体
  • 标记任何问题

Per-provider schema at the call site

调用端的按提供商划分的Schema

LaunchDarkly stores the tool schema once — the flat
{type, name, description, parameters}
shape you passed to
create-ai-tool
. Your application reads it back via
config.model.parameters.tools
(completion mode) or
agent_config.model.parameters.tools
(agent mode), then converts to the shape the provider SDK expects. LaunchDarkly never makes the provider call; your code does. The handlers that implement each tool also stay in application code — LaunchDarkly stores the schema, your application owns the behavior.
Provider / frameworkTarget shapeWhere it goes on the call
OpenAI Chat Completions (direct SDK)
{type: "function", function: {name, description, parameters}}
top-level
tools=[...]
Anthropic direct SDK
{name, description, input_schema}
— rename
parameters
input_schema
top-level
tools=[...]
Bedrock Converse
{toolSpec: {name, description, inputSchema: {json: parameters}}}
inside
toolConfig.tools=[...]
Gemini (
google-genai
)
{function_declarations: [{name, description, parameters}]}
(Python) /
{functionDeclarations: [...]}
(Node)
GenerateContentConfig.tools=[...]
OpenAI Responses APILaunchDarkly's flat shape passes through unchangedtop-level
tools=[...]
LangChain / LangGraph
createLangChainModel(config)
(Node) /
create_langchain_model(config)
(Python) and pass
ai_config.tools
(or your own
StructuredTool
list) into
bind_tools(...)
/
create_react_agent(tools=[...])
framework-native; no per-call conversion
Strands AgentsLaunchDarkly's flat shape; drop
parameters.tools
before passing params to the Strands model class (
AnthropicModel
,
OpenAIModel
) — Python
@tool
-decorated callables stay in code
Agent(tools=[...])
constructor; no per-call conversion
Minimal conversion snippets (Python):
python
ld_tools = (ai_config.model.to_dict().get("parameters") or {}).get("tools", []) or []
LaunchDarkly仅存储一次工具Schema——即你传递给
create-ai-tool
的扁平
{type, name, description, parameters}
结构。你的应用通过
config.model.parameters.tools
(完成模式)或
agent_config.model.parameters.tools
(Agent模式)读取它,然后转换为提供商SDK所需的结构。LaunchDarkly不会发起提供商调用;调用由你的代码完成。实现每个工具的处理程序也保留在应用代码中——LaunchDarkly存储Schema,你的应用负责行为逻辑。
提供商/框架目标结构调用时的位置
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 / LangGraph
createLangChainModel(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):
python
ld_tools = (ai_config.model.to_dict().get("parameters") or {}).get("tools", []) or []

OpenAI Chat Completions

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 ]
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

anthropic_tools = [ { "name": t["name"], "description": t.get("description", ""), "input_schema": t.get("parameters", {"type": "object", "properties": {}}), } for t in ld_tools ]
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 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 ] }
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

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 []
undefined
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 []
undefined

Agent loop with tool calls

带有工具调用的Agent循环

An agent that uses tools runs a short loop: call the provider, dispatch any tool calls, loop again, stop when the provider returns a final answer. Three rules apply regardless of provider:
  1. Bound the loop.
    MAX_STEPS = 5
    is a safe default. A runaway tool loop is almost always a prompt or schema bug, not a case that needs 50 iterations.
  2. Track every tool invocation. Call
    tracker.track_tool_call(tool_name)
    /
    tracker.trackToolCall(toolName)
    for each tool the agent actually executes. This is what the Monitoring tab counts as tool usage.
  3. Break on the provider's "no more tool calls" signal. The exact signal differs per provider: OpenAI Chat Completions →
    choice.finish_reason != "tool_calls"
    ; Anthropic →
    response.stop_reason != "tool_use"
    ; Bedrock Converse →
    response["stopReason"] != "tool_use"
    ; Gemini →
    response.function_calls
    empty; OpenAI Responses API → no
    function_call
    items in
    response.output
    .
Skeleton (Python, Anthropic — the other providers follow the same shape with their own stop-reason check and tool-result formatting):
python
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})
Per-provider tool-call payload shapes live in the
built-in-metrics
references:
  • openai-tracking.md — Chat Completions + Responses API
  • anthropic-tracking.md
    tool_use
    blocks and
    tool_result
    payloads
  • bedrock-tracking.md
    toolUse
    /
    toolResult
    Converse format
  • gemini-tracking.md
    functionCalls
    /
    functionResponse
    parts
  • langchain-tracking.md — LangGraph tool loop inherits from
    create_react_agent
使用工具的Agent会运行一个短循环:调用提供商、分发任何工具调用、再次循环,直到提供商返回最终答案。无论提供商是谁,都适用三条规则:
  1. 限制循环次数
    MAX_STEPS = 5
    是安全的默认值。失控的工具循环几乎总是提示词或Schema的问题,而非需要50次迭代的场景。
  2. 跟踪每次工具调用。对于Agent实际执行的每个工具,调用
    tracker.track_tool_call(tool_name)
    /
    tracker.trackToolCall(toolName)
    。这是监控标签页中统计工具使用情况的依据。
  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——其他提供商遵循相同结构,仅需修改终止原因检查和工具结果格式化):
python
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
参考文档中找到:
  • openai-tracking.md —— Chat Completions + Responses API
  • anthropic-tracking.md ——
    tool_use
    块和
    tool_result
    负载
  • bedrock-tracking.md ——
    toolUse
    /
    toolResult
    Converse格式
  • gemini-tracking.md ——
    functionCalls
    /
    functionResponse
    部分
  • langchain-tracking.md —— LangGraph工具循环继承自
    create_react_agent

Orchestrator Note

编排器说明

LangGraph, CrewAI, and AutoGen often generate schemas from function definitions. You still need to create tools in LaunchDarkly and attach keys to variations so the SDK knows what's available.
LangGraph、CrewAI和AutoGen通常会从函数定义生成Schema。你仍需在LaunchDarkly中创建工具,并将key关联到变体,以便SDK知道可用的工具。

Edge Cases

边缘情况

SituationAction
Tool already exists (409)Use existing or create with different key
Schema invalidUse raw JSON Schema format (type: object, properties, required)
Wrong endpoint assumedThe tools use
/ai-tools
, not
/ai-configs/tools
场景操作
工具已存在(409错误)使用现有工具或创建带有不同key的新工具
Schema无效使用原始JSON Schema格式(type: object, properties, required)
错误假设端点工具使用
/ai-tools
,而非
/ai-configs/tools

What NOT to Do

禁止操作

  • Don't try to attach tools during config creation -- update the variation afterward
  • Don't skip clear tool descriptions (LLM needs them to decide when to call)
  • Don't forget to verify attachment after updating the variation
  • Don't bundle
    instructions
    ,
    messages
    ,
    model
    , or
    parameters
    into the tool-attachment PATCH. Send
    tools
    alone unless the user explicitly asked for a multi-field update — bundled PATCHes silently clobber UI edits to the other fields.
  • 不要在创建配置时尝试关联工具——之后再更新变体
  • 不要跳过清晰的工具描述(LLM需要它来决定何时调用工具)
  • 不要忘记在更新变体后验证关联情况
  • 不要将
    instructions
    messages
    model
    parameters
    包含在工具关联的PATCH请求中。除非用户明确要求多字段更新,否则仅发送
    tools
    字段——捆绑的PATCH请求会静默覆盖其他字段的UI编辑内容。

Related Skills

相关技能

  • configs-create
    -- Create config before attaching tools
  • configs-variations
    -- Manage variations with different tool sets
  • configs-create
    —— 在关联工具之前创建配置
  • configs-variations
    —— 管理带有不同工具集的变体