Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Creates, revises, and reviews technical articles using formal encyclopedic language, numbered Markdown sections, manual tables of contents, coherent taxonomies, practical examples, and source-qualified references.
SkillScore68/100
Test results 68
3/3 safety checks passed
23%68%of test cases passed +45 pts
Passed 15 of 22 test cases with the skill, and 5 of 22 without it.
12 fixed3 passed either way5 still failing2 broke
One test taskIn a technical document on Distributed Systems, add a cross-link referencing an adjacent internal article about Versioning located at `../articles/versioning.md` inside a Sentenz repository.
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add sentenz-technical-article
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("sentenz-technical-article")
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 sentenz-technical-articleThe 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/sentenz-technical-article/SKILL.md https://app.decimal.ai/s/sentenz-technical-article/SKILL.md.claude/skills/sentenz-technical-article/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is 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 sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add sentenz-technical-articleimport 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add sentenz-technical-articlefrom 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("sentenz-technical-article")
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/sentenz-technical-article/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/sentenz-technical-article/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 1 other file is 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 sentenz-technical-articleNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/sentenz-technical-article/SKILL.md https://app.decimal.ai/s/sentenz-technical-article/SKILL.md.agents/skills/sentenz-technical-article/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 1 other file is not included.
Raw files: /s/sentenz-technical-article/SKILL.md · /s/sentenz-technical-article.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/sentenz-technical-article/SKILL.mdcurl -fsSL https://app.decimal.ai/s/sentenz-technical-article.jsonThis gets SKILL.md only. The skill's 1 other file is 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.
Instructions for AI agents on creating, revising, and reviewing technical articles using formal language, coherent structure, precise terminology, practical examples, and verifiable references.
Consistency
A stable article grammar makes technical content predictable across topics and allows readers to locate definitions, categories, principles, examples, and references without relearning the document structure.
Readability
Concise definitional paragraphs, explicit headings, and term-definition lists reduce cognitive load while preserving technical precision.
Navigability
A manually maintained hierarchical table of contents and numbered headings expose the conceptual hierarchy and provide direct navigation for long articles.
Reusability
Taxonomies, terminology lists, practical examples, and qualified references make each article useful as both an introduction and a durable engineering reference.
Reviewability
Deterministic formatting and evidence rules allow reviewers to separate structural defects, language defects, and technical inaccuracies.
Formal
Use neutral English suitable for software engineers, systems engineers, security professionals, and technical decision-makers.
Encyclopedic
Define the subject before prescribing practices. Explain what a concept is, how it is categorized, and where it is applied before presenting recommendations.
Precise
Prefer domain-specific nouns and verbs over broad or promotional wording. Distinguish standards, specifications, protocols, tools, frameworks, practices, metrics, and architectural patterns.
Impersonal
Prefer third-person or impersonal constructions. Avoid first-person narration, direct second-person address, rhetorical questions, and conversational filler.
Declarative
State definitions, relationships, constraints, and outcomes directly. Use modal verbs only when expressing an actual requirement, recommendation, possibility, or uncertainty.
Evidence
Support externally verifiable claims with authoritative sources. Prefer standards bodies, official documentation, primary research, and canonical repositories.
Currency
Verify time-sensitive facts, version-specific behavior, performance thresholds, legal requirements, and product capabilities before including them.
Scope
Keep each article centered on one technical subject. Link to adjacent articles rather than duplicating substantial background material.
Taxonomic Coherence
Group concepts by one explicit classification dimension at a time. Do not mix tools, practices, outcomes, and properties as peers unless the section explains the relationship.
Examples
Use examples that are syntactically valid, technically plausible, and directly connected to the preceding explanation.
File Name
Use a lowercase kebab-case file name that identifies the subject, for example
technical-debt.md,feature-flags.md, orfile-systems.md.
Frontmatter
Do not add YAML frontmatter to article files unless the target repository explicitly requires it.
H1 Title
Begin with exactly one H1 heading containing the canonical subject name in title case.
# Feature Flags
Place one or two concise paragraphs immediately after the H1 heading.
Definition
Define the subject in the first sentence. Expand an acronym on first use when it is not universally self-evident in the article domain.
Context
Explain the subject's purpose, operational role, or relationship to software engineering. Introduce no detailed taxonomy before the table of contents.
Example:
# Feature Flags
Feature flags are runtime controls that enable or disable application behavior without requiring a new deployment. They decouple code deployment from feature release and support controlled rollout, experimentation, and operational mitigation.
Insert a manually maintained Markdown table of contents after the introduction and before the first H2 section.
Hierarchy
Mirror every numbered H2, H3, and material H4 heading using two-space indentation per level.
Labels
Include the complete numeric prefix and heading text.
Anchors
Use GitHub-compatible lowercase anchors. Remove punctuation according to GitHub heading rules while preserving hyphens between words.
Completeness
Add, remove, or rename table-of-contents entries whenever headings change.
Example:
- [1. Category](#1-category)
- [1.1. Deployment Strategies](#11-deployment-strategies)
- [1.1.1. Blue-Green Deployment](#111-blue-green-deployment)
- [1.1.2. Canary Deployment](#112-canary-deployment)
- [2. Principle](#2-principle)
- [3. Best Practice](#3-best-practice)
- [4. Terminology](#4-terminology)
- [5. References](#5-references)
Use Arabic decimal numbering in every article heading below H1.
H2
Use
## 1. <Section>for top-level sections.
H3
Use
### 1.1. <Subsection>for second-level sections.
H4
Use
#### 1.1.1. <Topic>only when a subsection contains a substantial taxonomy that requires another level.
Depth
Prefer no more than four heading levels including H1. Replace excessive heading depth with term-definition lists or tables.
Canonical Sections
Select only sections that contribute to the subject. Common corpus-compatible labels include
Benefits,Category,Principle,Principles,Best Practice,Terminology, andReferences.
Order
Start with foundational concepts and categories, continue with principles or practices, then conclude with terminology and references.
Use prose for conceptual transitions and term-definition lists for scannable technical content.
Section Lead
Open a major section with one or two paragraphs that explain the classification dimension or purpose of the section.
Term-Definition Pattern
Present a technical label as a bullet and its explanation as an indented blockquote.
- Atomicity
> Atomicity ensures that a transaction completes as one unit or rolls back without retaining a partial result.
Grouped Pattern
Use an ordered list item as a local group heading when a subsection contains several distinct views, such as conventions, examples, or tools.
Label Capitalization
Use title case for conceptual labels and sentence case for descriptions.
Description Quality
Start descriptions with the term's role, behavior, or defining property. Avoid circular definitions that repeat the label without adding meaning.
Standalone Examples
Introduce prose-level standalone examples with
Example:. Within grouped subsections such asExamples and Explanations, use a descriptive example label instead.
Code Examples
Use a fenced code block with the most accurate language identifier.
Inline Syntax
Use backticks for commands, file paths, configuration keys, identifiers, literals, and short syntax fragments.
Tables
Use Markdown tables for compact comparisons, matrices, metrics, commands, or enumerated reference data. Keep cell content parallel and avoid prose paragraphs inside cells.
Diagrams
Use text-based diagrams such as Mermaid when relationships or flows cannot be explained efficiently with prose or a table.
Admonitions
Use GitHub admonitions sparingly for constraints, caveats, cross-links, or information that materially changes interpretation.
> [!NOTE]
> The metric threshold depends on the cited reporting period and must be verified before publication.
End every article with a numbered References section.
Internal References
Use repository-relative links for related Sentenz articles.
- Sentenz [Versioning](../articles/versioning.md) article.
External References
Name the organization or publisher before the linked title and identify the source type after the link.
- NIST [Secure Software Development Framework (SSDF) Version 1.1](https://csrc.nist.gov/pubs/sp/800/218/final) publication.
- Kubernetes [Documentation](https://kubernetes.io/docs/) documentation.
- GitHub [DORA Four Keys](https://github.com/dora-team/fourkeys) repository.
Source Types
Use a precise qualifier such as
article,documentation,page,publication,repository,report,specification, orstandard.
Relevance
Include only sources cited or materially used in the article. Do not create a general reading list unrelated to article claims.
Inspect
Read neighboring files in the target article directory. Record the local heading vocabulary, link style, code-fence conventions, and related internal articles.
Scope
Define the article subject, intended depth, and primary classification dimension. Separate adjacent subjects into cross-linked articles.
Research
Collect authoritative primary sources. Verify terminology, standards, metrics, product behavior, and time-sensitive details.
Outline
Select the required canonical sections and construct a numbered heading hierarchy before drafting prose.
Load Template
Load assets/technical-article-template.md when creating a new article. Remove sections that do not contribute to the subject.
Draft Introduction
Write the H1 title and one or two definitional paragraphs. Establish the subject and engineering context without front-loading implementation detail.
Build Table of Contents
Mirror the planned heading hierarchy and generate exact GitHub-compatible anchors.
Write Sections
Add section leads, term-definition lists, examples, tables, diagrams, and admonitions only where they improve comprehension.
Add References
Add internal relative links and external source-qualified references. Ensure every material external claim has an appropriate authoritative source.
Validate
Apply all Quality Gates before returning or committing the article.
Preserve Intent
Identify the existing article's subject, scope, and taxonomy before changing structure.
Load Template
Load assets/technical-article-template.md before revising the article. Use it as a structural baseline, remove inapplicable template sections, and preserve valid article-specific sections.
Diagnose
Separate defects into technical accuracy, taxonomy, organization, language, formatting, links, examples, and references.
Normalize
Align the title, introduction, table of contents, numbering, heading levels, lists, blockquotes, code fences, and references with this skill.
Refine Language
Replace vague, repetitive, conversational, or promotional wording with direct technical definitions and domain-appropriate verbs.
Reconcile Navigation
Update anchors, cross-links, and references after every heading or file-name change.
Validate
Re-run all quality gates and confirm that the revision does not remove technically relevant information without an explicit reason.
Load Template
Load assets/technical-article-template.md before reviewing an article. Use it as a structural baseline and do not report omitted optional sections as defects unless their absence creates a completeness or coherence problem.
Evaluate
Review the article in the following order:
Report Findings
Report findings with the affected heading or line, the defect, its technical consequence, and a concrete correction. Prioritize factual errors and structural inconsistencies over stylistic preferences.
Present Tense
Use present tense for definitions, capabilities, and current practices.
Past Tense
Use past tense only for historical events or superseded behavior.
Active Voice
Prefer active voice when the actor or mechanism matters.
Passive Voice
Use passive voice when the process or result is the focus and the actor is irrelevant.
Impersonal Perspective
Avoid first-person and second-person pronouns.
Professional Tone
Avoid humor, idioms, rhetorical questions, exclamation marks, and marketing language.
Qualified Language
Avoid unqualified adjectives such as
easy,simple,powerful,modern,best, orobvious.
Normative Modal Verbs
Use
should,must,may, andcanaccording to their actual normative meaning.
Acronym Expansion
Expand acronyms on first use, for example
Mean Time to Recovery (MTTR).
Canonical Capitalization
Preserve canonical capitalization for technologies, standards, protocols, and organizations.
Preferred Terminology
Use one preferred term consistently; introduce aliases only when they are widely used or needed for searchability.
Concept Classification
Distinguish a product from its category, a framework from a methodology, and a metric from the outcome it measures.
Literal Tokens
Use backticks for literal tokens, not for ordinary emphasis.
Domain Definitions
Define uncommon domain terms before relying on them in later sections.
Topic Sentence
Begin each paragraph with its main technical claim.
Paragraph Scope
Keep one conceptual purpose per paragraph.
Sentence Construction
Prefer direct subject-verb-object construction.
Redundancy
Remove repeated definitions and duplicated conclusions.
Parallel Grammar
Use parallel grammar across peer list items and table rows.
Complete Sentences
Use complete sentences in prose and blockquote descriptions.
Terminal Punctuation
Keep heading text and list labels free of terminal punctuation.
Example Notation
Prefer
for examplein prose; usee.g.only where compact notation is appropriate.
Adjacent Qualifications
State limitations and trade-offs adjacent to the capability they qualify.
Unordered Lists
Use unordered lists for taxonomies, properties, principles, tools, and terminology.
Ordered Lists
Use ordered lists for workflows, local group headings, and sequences.
Blockquote Descriptions
Place the description on the next line as an indented blockquote.
Item Separation
Separate complex list items with blank lines.
Parallel Labels
Keep peer labels grammatically parallel.
Category Grouping
Avoid a flat list when items belong to distinct categories; introduce subsections or grouped ordered-list headings instead.
First Material Mention
Link a technology, standard, or framework at its first material mention.
Source Authority
Prefer official documentation and primary sources over aggregators.
Internal Links
Use relative links for repository-local articles.
Descriptive Link Text
Use descriptive link text rather than raw URLs.
Link Frequency
Avoid linking every repeated occurrence of the same term.
Destination Accuracy
Ensure linked text accurately represents the destination.
Claim Support
Do not cite a source for a claim the source does not support.
Plaintext Fences
Use
plaintextfor abstract syntax, terminal output, and language-neutral examples.
Shell and Source Fences
Use
bashfor shell commands and a language-specific fence for source code.
Example Completeness
Keep code examples minimal but complete enough to demonstrate the stated concept.
Secure Examples
Do not include insecure or deprecated code without an explicit warning and safer alternative.
Table Applicability
Use tables only when columns represent stable comparable attributes.
Table Consistency
Align table headers consistently and keep terminology parallel.
Admonition Purpose
Use admonitions for high-value caveats; do not use them as decorative callouts.
Mermaid Validity
Ensure Mermaid diagrams use valid syntax and meaningful node labels.
An article is complete only when all applicable gates pass.
Scope
The article covers one coherent subject and links to adjacent subjects instead of duplicating them.
Definition
The first paragraph defines the subject and establishes its engineering context.
Navigation
The table of contents matches every numbered heading and every anchor resolves correctly.
Numbering
Heading numbers are sequential, hierarchical, and consistent after insertions or deletions.
Taxonomy
Peer concepts share one classification dimension and use parallel labels and descriptions.
Language
The prose is formal, declarative, impersonal, technically precise, and free of unsupported promotional claims.
Terminology
Acronyms are expanded on first use, canonical names are preserved, and aliases are controlled.
Examples
Code, commands, diagrams, and data are valid, relevant, and consistent with the explanation.
Evidence
Material claims use authoritative sources, and time-sensitive claims have been verified.
Links
Internal paths are relative and valid; external links use descriptive text and resolve to the intended source.
References
The final section contains only used sources and qualifies each source with an accurate source type.
Formatting
Markdown renders correctly, code fences are balanced, tables are valid, and list indentation is consistent.
Completeness
No placeholders, editorial notes, unverified assumptions, or unfinished sections remain.
assets/technical-article-template.md
Complete structural baseline for convention-style technical articles. Load it during create, revise, and review workflows; adapt optional sections to the subject rather than enforcing them mechanically.
Automatically, when a task matches. Use for technical or engineering articles and knowledge-base entries, especially Markdown files under content/articles, docs/articles, or articles.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.