tools
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAI 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 a new tool definition with a schema
create-ai-tool - -- attach tools to an AI Config variation
update-ai-config-variation - -- verify tools are attached to the variation
get-ai-config
Optional MCP tools:
- -- browse existing tools in the project
list-ai-tools - -- inspect a specific tool's schema
get-ai-tool
本技能要求环境中已配置远程托管的LaunchDarkly MCP服务器。
必需的MCP工具:
- —— 创建带有Schema的新工具定义
create-ai-tool - —— 将工具关联到AI Config变体
update-ai-config-variation - —— 验证工具是否已关联到变体
get-ai-config
可选的MCP工具:
- —— 浏览项目中已有的工具
list-ai-tools - —— 查看特定工具的Schema
get-ai-tool
Core Principles
核心原则
- Start with Capabilities: Think about what your AI needs to do before creating tools
- Framework Matters: LangGraph/CrewAI often auto-generate schemas; OpenAI SDK needs manual schemas
- Create Before Attach: Tools must exist before you can attach them to variations
- Verify: The agent fetches the config to confirm attachment
- 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.
- 从能力出发:在创建工具前,先思考AI需要完成什么任务
- 框架很重要:LangGraph/CrewAI通常会自动生成Schema;OpenAI SDK需要手动编写Schema
- 先创建再关联:工具必须先存在,才能关联到变体
- 验证:Agent会获取配置以确认关联成功
- 完成完整流程:列出已有工具只是发现步骤,而非最终目标。列出后,务必继续创建所需工具、关联并验证,不要停留在探索阶段。
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:
- -- explore what exists
list-ai-tools - -- create the new tool (with a key different from existing ones)
create-ai-tool - -- attach it
update-ai-config-variation - -- verify
get-ai-config
Call as your first tool call before any creation. Never stop after listing alone -- always proceed through all four steps.
list-ai-toolsAI应该能做什么?
- 查询数据库、调用API、执行计算、发送通知
- 检查代码库中已有的内容(API客户端、函数)
- 考虑框架:LangGraph/LangChain会自动生成Schema;直接使用SDK需要手动编写Schema
如果用户要求先检查已有工具,或者你没有关于代码库中工具的上下文,请严格按照以下顺序操作:
- —— 探索已有工具
list-ai-tools - —— 创建新工具(使用与已有工具不同的key)
create-ai-tool - —— 关联工具
update-ai-config-variation - —— 验证
get-ai-config
在创建任何工具之前,首先调用。不要仅停留在列出工具这一步——务必完成全部四个步骤。
list-ai-toolsStep 2: Create Tools
步骤2:创建工具
Use with:
create-ai-tool- -- unique identifier for the tool
key - -- clear description (the LLM uses this to decide when to call the tool)
description - -- raw JSON Schema (do NOT use the OpenAI function calling wrapper):
schema
json
{
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "integer", "default": 10}
},
"required": ["query"]
}使用时需提供:
create-ai-tool- —— 工具的唯一标识符
key - —— 清晰的描述(LLM会根据此决定何时调用工具)
description - —— 原始JSON Schema(请勿使用OpenAI函数调用包装器):
schema
json
{
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"limit": {"type": "integer", "default": 10}
},
"required": ["query"]
}Step 3: Attach to Variation
步骤3:关联到变体
Use to attach tools. Pass only the field. Do not bundle , , , or 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.
update-ai-config-variationtoolsinstructionsmessagesmodelparametersjson
{
"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 response — that masks the bug and can resurrect stale values that the user has since edited. Report the bug instead.
get-ai-config使用关联工具。仅传递字段。除非用户明确要求同时更新其他字段,否则不要将、、或包含在此次PATCH请求中。自变体创建以来,这些字段可能已在LaunchDarkly UI中被编辑,将它们包含在工具关联的PATCH请求中会静默覆盖UI中的编辑内容。
update-ai-config-variationtoolsinstructionsmessagesmodelparametersjson
{
"projectKey": "my-project",
"configKey": "support-chatbot",
"variationKey": "default",
"tools": [
{"key": "search-knowledge-base", "version": 1}
]
}如果遇到关联工具会清除其他字段的UI漏洞,不要通过重新发送之前响应中的那些字段来解决——这会掩盖漏洞,还可能恢复用户已编辑过的陈旧值。应报告该漏洞。
get-ai-configStep 4: Verify
步骤4:验证
- Use to confirm the tool exists with a valid schema
get-ai-tool - Use to confirm the tool is attached to the variation (check
get-ai-configin the variation's output)tools
Report results:
- Tool created with valid schema
- Tool attached to variation
- Flag any issues
- 使用确认工具已存在且Schema有效
get-ai-tool - 使用确认工具已关联到变体(检查变体输出中的
get-ai-config字段)tools
报告结果:
- 工具已创建且Schema有效
- 工具已关联到变体
- 标记任何问题
Per-provider schema at the call site
调用端的按提供商划分的Schema
LaunchDarkly stores the tool schema once — the flat shape you passed to . Your application reads it back via (completion mode) or (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.
{type, name, description, parameters}create-ai-toolconfig.model.parameters.toolsagent_config.model.parameters.tools| Provider / framework | Target shape | Where it goes on the call |
|---|---|---|
| OpenAI Chat Completions (direct SDK) | | top-level |
| Anthropic direct SDK | | top-level |
| Bedrock Converse | | inside |
Gemini ( | | |
| OpenAI Responses API | LaunchDarkly's flat shape passes through unchanged | top-level |
| LangChain / LangGraph | | framework-native; no per-call conversion |
| Strands Agents | LaunchDarkly's flat shape; drop | |
Minimal conversion snippets (Python):
python
ld_tools = (ai_config.model.to_dict().get("parameters") or {}).get("tools", []) or []LaunchDarkly仅存储一次工具Schema——即你传递给的扁平结构。你的应用通过(完成模式)或(Agent模式)读取它,然后转换为提供商SDK所需的结构。LaunchDarkly不会发起提供商调用;调用由你的代码完成。实现每个工具的处理程序也保留在应用代码中——LaunchDarkly存储Schema,你的应用负责行为逻辑。
create-ai-tool{type, name, description, parameters}config.model.parameters.toolsagent_config.model.parameters.tools| 提供商/框架 | 目标结构 | 调用时的位置 |
|---|---|---|
| OpenAI Chat Completions(直接SDK) | | 顶层 |
| Anthropic直接SDK | | 顶层 |
| Bedrock Converse | | |
Gemini ( | | |
| OpenAI Responses API | LaunchDarkly的扁平结构直接传递 | 顶层 |
| LangChain / LangGraph | | 框架原生;无需每次调用转换 |
| Strands Agents | LaunchDarkly的扁平结构;在将参数传递给Strands模型类( | |
最小转换代码片段(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 []
undefinedgemini_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 []
undefinedAgent 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:
- Bound the loop. is a safe default. A runaway tool loop is almost always a prompt or schema bug, not a case that needs 50 iterations.
MAX_STEPS = 5 - Track every tool invocation. Call /
tracker.track_tool_call(tool_name)for each tool the agent actually executes. This is what the Monitoring tab counts as tool usage.tracker.trackToolCall(toolName) - Break on the provider's "no more tool calls" signal. The exact signal differs per provider: OpenAI Chat Completions → ; Anthropic →
choice.finish_reason != "tool_calls"; Bedrock Converse →response.stop_reason != "tool_use"; Gemini →response["stopReason"] != "tool_use"empty; OpenAI Responses API → noresponse.function_callsitems infunction_call.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 references:
built-in-metrics- openai-tracking.md — Chat Completions + Responses API
- anthropic-tracking.md — blocks and
tool_usepayloadstool_result - bedrock-tracking.md — /
toolUseConverse formattoolResult - gemini-tracking.md — /
functionCallspartsfunctionResponse - langchain-tracking.md — LangGraph tool loop inherits from
create_react_agent
使用工具的Agent会运行一个短循环:调用提供商、分发任何工具调用、再次循环,直到提供商返回最终答案。无论提供商是谁,都适用三条规则:
- 限制循环次数。是安全的默认值。失控的工具循环几乎总是提示词或Schema的问题,而非需要50次迭代的场景。
MAX_STEPS = 5 - 跟踪每次工具调用。对于Agent实际执行的每个工具,调用/
tracker.track_tool_call(tool_name)。这是监控标签页中统计工具使用情况的依据。tracker.trackToolCall(toolName) - 根据提供商的“无更多工具调用”信号终止循环。不同提供商的信号不同:OpenAI Chat Completions → ;Anthropic →
choice.finish_reason != "tool_calls";Bedrock Converse →response.stop_reason != "tool_use";Gemini →response["stopReason"] != "tool_use"为空;OpenAI Responses API →response.function_calls中无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 —— /
toolUseConverse格式toolResult - 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
边缘情况
| Situation | Action |
|---|---|
| Tool already exists (409) | Use existing or create with different key |
| Schema invalid | Use raw JSON Schema format (type: object, properties, required) |
| Wrong endpoint assumed | The tools use |
| 场景 | 操作 |
|---|---|
| 工具已存在(409错误) | 使用现有工具或创建带有不同key的新工具 |
| Schema无效 | 使用原始JSON Schema格式(type: object, properties, required) |
| 错误假设端点 | 工具使用 |
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, ormodelinto the tool-attachment PATCH. Sendparametersalone unless the user explicitly asked for a multi-field update — bundled PATCHes silently clobber UI edits to the other fields.tools
- 不要在创建配置时尝试关联工具——之后再更新变体
- 不要跳过清晰的工具描述(LLM需要它来决定何时调用工具)
- 不要忘记在更新变体后验证关联情况
- 不要将、
instructions、messages或model包含在工具关联的PATCH请求中。除非用户明确要求多字段更新,否则仅发送parameters字段——捆绑的PATCH请求会静默覆盖其他字段的UI编辑内容。tools
Related Skills
相关技能
- -- Create config before attaching tools
configs-create - -- Manage variations with different tool sets
configs-variations
- —— 在关联工具之前创建配置
configs-create - —— 管理带有不同工具集的变体
configs-variations