Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Minium 录制脚本转测试用例工具。自动解析录制脚本,生成符合规范的测试用例和页面对象,确保步骤完整、逻辑一致。
SkillScore70/100
Test results 70
3/3 safety checks passed
9%70%of test cases passed +61 pts
Passed 16 of 23 test cases with the skill, and 2 of 23 without it.
14 fixed2 passed either way7 still failing0 broke
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add minium-test-generator
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install minium-test-generatorThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/minium-test-generator/SKILL.md https://app.decimal.ai/s/minium-test-generator/SKILL.md.claude/skills/minium-test-generator/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add minium-test-generatorimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add minium-test-generatorfrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add minium-test-generatorimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add minium-test-generatorimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add minium-test-generatorfrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add minium-test-generatorfrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 3 other files are not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add minium-test-generatorimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add minium-test-generatorfrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add minium-test-generatorfrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add minium-test-generatorimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 3 other files are not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add minium-test-generatorimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 3 other files are not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add minium-test-generatorfrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("minium-test-generator")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/minium-test-generator/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/minium-test-generator/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add minium-test-generatorNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/minium-test-generator/SKILL.md https://app.decimal.ai/s/minium-test-generator/SKILL.md.agents/skills/minium-test-generator/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 3 other files are not included.
Raw files: /s/minium-test-generator/SKILL.md · /s/minium-test-generator.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/minium-test-generator/SKILL.mdcurl -fsSL https://app.decimal.ai/s/minium-test-generator.jsonThis gets SKILL.md only. The skill's 3 other files are not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
本技能用于将 Minium 录制脚本自动转换为符合项目规范的测试用例,确保步骤一个不漏,逻辑完全一致。
核心能力:
当用户提供录制文件时,禁止直接生成!
正确流程:
第 1 步:询问目录
→ "好的,我来帮你生成测试用例。请问测试用例目录在哪里?(完整路径)"
→ 等待用户回复
第 2 步:检查目录是否存在
→ 如果目录不存在 → 走【新建项目】流程
→ 如果目录已存在 → 走【添加到现有目录】流程
第 3 步:确认创建方式
→ 向用户展示将要创建/添加的文件列表
→ 等待用户确认
第 4 步:生成内容
→ 新建:创建完整项目结构
→ 添加:仅新增文件,不覆盖已有文件
错误示范(禁止!):
当目录已存在时,禁止直接生成!
正确流程:
第 1 步:读取现有文件结构
→ 列出目录内容(pages/、test_cases/、*.py 等)
第 2 步:阅读已有代码
→ 阅读 pages/ 中的现有 Page Object
→ 分析命名规范、类命名、元素定位风格
→ 阅读 test_*.py 中的现有测试用例
→ 分析测试结构、断言风格、等待方式
第 3 步:总结现有规则
→ Page Object 命名规则(如:驼峰/下划线)
→ 元素定位规则(如:优先 selector 还是 xpath)
→ 测试用例结构(如:是否使用 mark_step_start)
→ 截图点命名规则(如:step_1、tap_1 等)
第 4 步:按现有规则生成新用例
→ 新 Page Object 遵循已有命名和结构
→ 新测试用例遵循已有风格和格式
→ 不引入与现有代码冲突的规范
示例:
我:检测到目录已存在,我先阅读一下现有代码结构...
[阅读 pages/ 和 test_*.py 后]
我:现有代码规则如下:
- Page Object 命名:大驼峰(如 GroupHomepage)
- 元素定位:优先 selector,xpath 备用
- 测试结构:使用 mark_step_start 和 capture
- 截图点命名:动作 + 序号(如 tap_1、scroll_2)
我将按此规则生成新用例,确认吗?
当 Page Object 文件已存在时:
❌ 错误做法:
- 创建新文件:pages/xxx_new.py
- 或创建重复文件:pages/xxx/xxx_v2.py
- 或创建分散的多个小方法
✅ 正确做法:
- 在原有文件末尾追加新方法
- 保持原有代码不变
- 同一个页面的操作整合到一个方法里
- 使用 basedef.py 中封装的方法(tap()、send_key())
示例:
原文件:publish_start_group.py (已有 1000 行)
❌ 错误:创建多个分散小方法
def input_theme(self): ...
def click_help_entry(self): ...
def click_reward_switch(self): ...
✅ 正确:整合到一个完整方法
def pub_group_supply(self, theme_text="xxx"):
"""跟团供货模式发布完整流程"""
self.send_key(self.theme_input, theme_text)
self.tap(self.promise_btn)
self.scroll_to(400)
self.tap(self.help_entry)
...
用例存放目录规则:
分析录制脚本中的页面路径
/pro/pages/homepage/group-homepage/... → 包含 homepage/pro/pages/home/leaders-management/... → 包含 home/pro/pages/seq-publish/... → 包含 seq-publish检查现有 testcase 目录结构
testcase/ 下的子目录home → 找 testcase/home_page/ 或 testcase/home/没有合适的目录时
/pro/pages/seq-publish/... → 创建 testcase/seq_publish/核心原则:看项目的实际目录结构,不要硬编码映射关系!
Page Object 核心规则:
先阅读用户的基类代码(如 basedef.py)
检查用户的封装方式
tap(), click(), click_element() 等send_key(), input_text(), type() 等scroll_to(), scroll() 等元素定位策略
view.btn-know.button)元素定位与操作分离
方法命名规范
click_xxx, input_xxx, select_xxx不要返回 self(除非需要链式调用)
self不要照搬录制脚本的等待时间!
self.page.wait_for(x) 是录制工具自动生成的tap(), send_key())内部已有等待逻辑sleep() 或 wait_for()不需要生成 .bat 运行脚本
run.py).bat 文件示例:
# 情况 1:用户已有封装方法(如 basedef.py 中有 tap() 和 send_key())
class SelectFollowReward(BaseDef):
reward_value_input = "..."
confirm_btn = "..."
def input_reward_value(self, value):
self.send_key(self.reward_value_input, str(value)) # 使用用户的封装
def click_confirm(self):
self.tap(self.confirm_btn) # 使用用户的封装
# 情况 2:用户没有封装方法
class SelectFollowReward(BaseDef):
reward_value_input = "..."
confirm_btn = "..."
def input_reward_value(self, value):
self.page.get_element(self.reward_value_input).input(str(value))
def click_confirm(self):
self.page.get_element(self.confirm_btn).tap()
新建项目结构:
tests/
├── pages/ # Page Object 层
│ ├── __init__.py # 导出所有页面对象
│ ├── [页面].py # 每个页面一个类
│ └── README.md # PO 模型说明
├── test_cases/ # 测试用例文档
│ └── [用例名].md # Markdown 格式用例
├── conftest.py # Pytest 配置
├── run_test.py # 测试启动脚本
└── test_[用例名].py # 可执行测试脚本
当用户提供的目录不存在时:
我:好的,我来帮你生成测试用例。
检测到目录不存在,我将为你创建完整的测试项目结构:
📁 [用户提供的路径]/
├── pages/ # Page Object 层
│ ├── __init__.py
│ ├── [页面 1].py
│ └── [页面 2].py
├── test_cases/ # 测试用例文档
│ └── [用例名].md
├── conftest.py # Pytest 配置
├── run_test.py # 测试启动脚本
└── test_[用例名].py # 可执行测试脚本
确认开始创建吗?
用户确认后:
当用户提供的目录已存在时:
我:好的,我来帮你生成测试用例。
检测到目录已存在,我将在现有目录下添加新用例:
📁 [用户提供的路径]/
├── pages/ # 新增 Page Object
│ └── [新页面].py
├── test_cases/ # 新增测试用例文档
│ └── [新用例名].md
└── test_[新用例名].py # 新增测试脚本
⚠️ 不会覆盖已有文件
确认开始创建吗?
用户确认后:
使用 exec 检查目录是否存在:
# Windows PowerShell
Test-Path "<用户提供的路径>"
# 返回 True → 目录存在 → 走添加流程
# 返回 False → 目录不存在 → 走新建流程
检查子目录结构:
# 检查是否有 pages 目录
Test-Path "<路径>/pages"
# 检查是否有 test_cases 目录
Test-Path "<路径>/test_cases"
# 检查是否有 conftest.py
Test-Path "<路径>/conftest.py"
根据检查结果判断:
pages/ 存在 → 追加新 Page Objectpages/ 不存在 → 创建 pages/ 目录test_cases/ 存在 → 追加新用例文档test_cases/ 不存在 → 创建 test_cases/ 目录你:帮我生成测试用例
[粘贴录制脚本]
我:好的,我来帮你生成测试用例。
首先,请告诉我:
1. 测试用例目录在哪里?(完整路径)
你:D:\projects\minium-tests\scenario-a
我:好的,我来检查目录...
检测到目录不存在,我将为你创建完整的测试项目结构:
📁 D:\projects\minium-tests\scenario-a\
├── pages/
│ ├── __init__.py
│ ├── homepage.py
│ └── detail_page.py
├── test_cases/
│ └── scenario_a.md
├── conftest.py
├── run_test.py
└── test_scenario_a.py
确认开始创建吗?
你:确认
我:✅ 项目结构已创建完成!
[输出所有文件内容]
你:帮我生成测试用例
[粘贴录制脚本]
我:好的,我来帮你生成测试用例。
首先,请告诉我:
1. 测试用例目录在哪里?(完整路径)
你:C:\workspace\expression-trainer-miniprogram\tests
我:好的,我来检查目录...
检测到目录已存在,我将在现有目录下添加新用例:
📁 C:\workspace\expression-trainer-miniprogram\tests\
├── pages/ # 新增 Page Object
│ └── [新页面].py
├── test_cases/ # 新增测试用例文档
│ └── [新用例名].md
└── test_[新用例名].py # 新增测试脚本
⚠️ 不会覆盖已有文件
确认开始创建吗?
你:确认
我:✅ 测试用例已添加完成!
[输出新增文件内容]
当你有以下需求时,直接说即可:
示例:
你:我给你一个录制文件,帮我生成测试用例
[从你的录制脚本目录找到 Python 文件,复制内容粘贴]
我:好的,我来帮你生成测试用例。
首先,请告诉我:
1. 测试用例目录在哪里?(完整路径)
2. 是否有现有的测试项目结构?
核心触发场景: 用户提供 Minium 录制脚本,要求生成或验证测试用例
触发词:
文件路径示例:
<你的录制脚本目录>\[场景名称]\[时间戳]\xxx.py
响应流程:
你:我给你一个录制文件,帮我生成测试用例
[粘贴录制脚本内容]
我:好的,我来帮你生成测试用例。
首先,请告诉我:
1. 测试用例目录在哪里?(完整路径)
2. 是否有现有的测试项目结构?
触发词:
响应流程:
你:帮我生成测试用例
[粘贴录制脚本内容]
我:好的,我来帮你生成测试用例。
首先,请告诉我:
1. 测试用例目录在哪里?(完整路径)
2. 是否有现有的测试项目结构?
触发词:
示例:
你:帮我验证一下这个测试用例有没有漏掉步骤
录制脚本:<你的录制脚本目录>\xxx.py
测试用例:<你的项目目录>\testcase\xxx\test_xxx.py
我:好的,我来对比验证...
触发词:
示例:
你:帮我解析这个录制脚本,看看有多少步
[从你的录制脚本目录找到 Python 文件,复制内容粘贴]
我:好的,我来运行 parse_steps.py 解析...
功能: 解析录制脚本,生成步骤清单
用法:
python <技能包路径>/scripts/parse_steps.py \
--input <录制脚本路径> \
--output <输出路径>
示例:
python scripts/parse_steps.py \
--input recorded_script.py \
--output steps_checklist.md
功能: 生成页面对象和测试用例
用法:
python <技能包路径>/scripts/generate_pages.py \
--input <录制脚本路径> \
--output <测试用例输出目录> \
--pages <页面类目录>
示例:
python scripts/generate_pages.py \
--input recorded_script.py \
--output testcase/xxx/ \
--pages pages/pages/
功能: 验证测试用例是否漏掉步骤
用法:
python <技能包路径>/scripts/validate_steps.py \
--input <录制脚本路径> \
--test <测试用例路径> \
--report <验证报告路径>
检查项:
# 1. 运行解析脚本
python scripts/parse_steps.py \
--input recorded_script.py \
--output steps_checklist.md
# 2. 查看生成的步骤清单
cat steps_checklist.md
输出:
# 运行生成脚本
python scripts/generate_pages.py \
--input recorded_script.py \
--output testcase/xxx/ \
--pages pages/pages/
输出:
# 运行验证工具
python scripts/validate_steps.py \
--input recorded_script.py \
--test testcase/xxx/test_xxx.py \
--report validation_report.md
输出:
wait_for_page_success()在生成测试用例后,必须检查:
validate_steps.py 验证?| 文档 | 说明 |
|---|---|
| core-skills/避免漏掉步骤.md | 核心技能:如何避免漏掉步骤 |
| docs/代码生成质量控制流程.md | 完整的质量控制流程 |
| docs/代码审查清单.md | 提交前必须逐项检查 |
| docs/代码规范.md | 代码规范详细说明 |
你:
我给你一个录制文件,帮我生成测试用例
[从你的录制脚本目录找到 Python 文件,复制内容粘贴]
我:
好的,我来使用 minium-test-generator 技能为你生成测试用例。
第 1 步:解析录制脚本...
python scripts/parse_steps.py --input recorded_script.py --output steps_checklist.md
第 2 步:生成测试用例...
python scripts/generate_pages.py --input recorded_script.py --output testcase/xxx/ --pages pages/pages/
第 3 步:验证步骤完整性...
python scripts/validate_steps.py --input recorded_script.py --test testcase/xxx/test_xxx.py --report validation_report.md
✅ 生成完成!测试用例已保存到 testcase/xxx/test_xxx.py
验证报告:validation_report.md
你:
帮我验证一下这个测试用例有没有漏掉步骤
录制脚本:<你的录制脚本目录>\recorded_script.py
测试用例:<你的项目目录>\testcase\xxx\test_xxx.py
我:
好的,我来运行 validate_steps.py 验证...
python scripts/validate_steps.py \
--input <你的录制脚本目录>\recorded_script.py \
--test <你的项目目录>\testcase\xxx\test_xxx.py \
--report validation_report.md
验证结果:
✅ 所有步骤都已转换(X 步,一个不漏)
✅ 相邻步骤元素检查通过
✅ 特殊逻辑检查通过
✅ 页面跳转等待检查通过
| 指标 | 数值 |
|---|---|
| 支持的文件格式 | Minium 录制脚本 (.py) |
| 生成的文件格式 | Python 测试用例 (.py) |
| 验证检查项 | 4 项 |
| 支持的特殊逻辑 | 三层判断、else 判断、循环、页面跳转 |
| 典型录制脚本路径 | <你的录制脚本目录>\[场景名称]\[时间戳]\ |
# 1. 查看技能文档
cat <技能包路径>/README.md
# 2. 学习核心技能
cat <技能包路径>/core-skills/避免漏掉步骤.md
# 3. 使用工具
python <技能包路径>/scripts/parse_steps.py --help
最后更新:2026-03-23
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.