Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Medical evidence grading orchestrator. 当用户需要评估医学文献的证据强度、比较多篇论文的质量、查找某疾病的高等级证据(指南或 RCT)、或验证临床声明的证据支持度时,调用本 skill。整合 6 个原子 skill 的检索结果,按证据金字塔自动分级为 A/B/C/D。优先使用 BioMCP fast-path(~3-5s),无 BioMCP 时回退 slow-path(~15-25s)。
SkillScore95/100
Test results 95
3/3 safety checks passed
36%95%of test cases passed +59 pts
Passed 21 of 22 test cases with the skill, and 8 of 22 without it.
13 fixed8 passed either way1 still failing0 broke
This benchmark measured an earlier version of the skill.
One test task在并发检索 PubMed、EuropePMC 及 ClinicalTrials 时,同一篇研究同时返回了 PMID: 32001002、PMCID: PMC7010001 和 DOI: 10.1056/NEJMoa1912345。请说明合成内部唯一键(evidence_id)的优先级规则。
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add ethanyoq-medical-evidence-grading
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("ethanyoq-medical-evidence-grading")
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 ethanyoq-medical-evidence-gradingThe 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/ethanyoq-medical-evidence-grading/SKILL.md https://app.decimal.ai/s/ethanyoq-medical-evidence-grading/SKILL.md.claude/skills/ethanyoq-medical-evidence-grading/SKILL.mdThis gets SKILL.md only. The skill's 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingimport 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingfrom 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("ethanyoq-medical-evidence-grading")
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/ethanyoq-medical-evidence-grading/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/ethanyoq-medical-evidence-grading/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 4 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 ethanyoq-medical-evidence-gradingNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/ethanyoq-medical-evidence-grading/SKILL.md https://app.decimal.ai/s/ethanyoq-medical-evidence-grading/SKILL.md.agents/skills/ethanyoq-medical-evidence-grading/SKILL.mdThis gets SKILL.md only. The skill's 4 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 4 other files are not included.
Raw files: /s/ethanyoq-medical-evidence-grading/SKILL.md · /s/ethanyoq-medical-evidence-grading.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/ethanyoq-medical-evidence-grading/SKILL.mdcurl -fsSL https://app.decimal.ai/s/ethanyoq-medical-evidence-grading.jsonThis gets SKILL.md only. The skill's 4 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.
对底层 6 个原子 skill 召回的医学文献做"证据金字塔排序",输出带 GRADE A/B/C/D 评级的文献集与汇总报告;同时充当智能调度器,根据问题类型(疗效/诊断/病因/预后/不良反应/预测/指南/SR)自动选择最佳原子 skill 与 PubMed Clinical Queries filter。
GRADE 评级前必须调用
pubmed-eutils.efetch_pubmed()拿真实 publication_type。不可仅凭 title/abstract 关键词推断。
理由:title 含"randomized"未必是 RCT(可能是综述讨论 RCT);只有 NLM MeSH 索引员人工标注的 publication_type 才是权威依据。仅当 efetch 返回为空(发表 < 6 个月新文献)才允许启发式推断,且必须给 grade 加 _inferred 后缀。
完整规则见 references/grade-rules.md。
调用本 skill (✅):
cross_validate_evidence(claim=...)evidence_search(query=..., target_grade='guideline_only')grade_pmid_list(pmid_list=[...])grade_pmid_list + evidence_summaryevidence_search(target_grade='rct_or_above')不调用本 skill (❌,直接调原子 skill):
pubmed-eutilsclinical-trials-v2bioc-fulltext-fetchaact-bulk-trials| 协作方向 | Skill | 调用的具体函数 | 用途 |
|---|---|---|---|
| 上游调用方 | ifi-market-sizing-skill | (调本 skill) | 市场规模研究的"数据回补" |
| 上游调用方 | disease-market-sizing-orchestration | (调本 skill) | 调研启动阶段的高等级证据搜集 |
| 下游被调 1 | pubmed-eutils | .esearch_pubmed() / .efetch_pubmed() / .pubmed_clinical_queries() | 拿 PMID + publication_type |
| 下游被调 2 | europepmc-search | .search_articles() / .find_similar_articles() | EuropePMC + open-access 链接 |
| 下游被调 3 | clinical-trials-v2 | .search_studies() | NCT + phase + enrollment |
| 下游被调 4 | aact-bulk-trials | .bulk_disease_landscape() | 全库历史试验(罕见病/纵向) |
| 下游被调 5 | bioc-fulltext-fetch | .to_rag_chunks() | 抽样本量(只对疑似 RCT/Cohort) |
| 下游被调 6 | pubtator-entity-search | .search_by_relation() | 给文献打疾病/药物 entity tag |
| 下游接收方 | evidence-appendix-sync | (接受本 skill 输出) | 报告附录 C 同步 |
用户 / 上游 skill (ifi-market-sizing-skill, disease-market-sizing-orchestration)
│
▼
[medical-evidence-grading]
↙ ↘
BioMCP fast-path 自建 slow-path
│ │
(单次 fan-out) 并发调 6 原子 skill
↓ ↓
统一去重 (PMID > PMCID > DOI)
↓
publication_type 解析 (efetch · Iron Law)
↓
GRADE 评级 (A/B/C/D/excluded · 见 grade-rules.md)
↓
evidence-appendix-sync (报告附录 C)
genomoncology/biomcp 一次性 fan-out PubMed + EuropePMC + ClinicalTrials + PubTator。
当 BioMCP 不可用,并发调 pubmed-eutils.esearch_pubmed() + europepmc-search.search_articles() + clinical-trials-v2.search_studies(),然后 pubmed-eutils.efetch_pubmed() 拿 publication_type,可选调 bioc-fulltext-fetch.to_rag_chunks() 抽样本量。
完整检测/配置/兜底逻辑见 references/biomcp-integration.md。
性能对比:
| 模式 | 100 条文献延迟 | API 调用数 | 缓存命中后 |
|---|---|---|---|
| Fast-path (BioMCP) | ~3-5s | 1 | <500ms |
| Slow-path (自建) | ~15-25s | 6-10 | <500ms |
# ============== 1. 主入口:综合证据搜索 ==============
def evidence_search(
query: str,
target_grade: str = "all", # 'guideline_only' | 'rct_or_above' | 'all'
max_results: int = 200,
include_preprints: bool = False,
include_trials: bool = True,
date_range: str = "10years", # 'all' | '5years' | '10years' | '2020:2025'
rare_disease_mode: bool = False, # 罕见病阈值放宽,见 grade-rules.md
use_biomcp_if_available: bool = True,
) -> dict:
"""
返回 {total, by_grade, fast_path_used, cache_hit, elapsed_seconds, results: [{evidence_id, pmid, pmcid, doi, title, authors, journal, year, publication_types, sample_size, is_preprint, grade, grade_rationale, abstract, source}]}
"""
# ============== 2. 给现有 PMID 列表打分 ==============
def grade_pmid_list(
pmid_list: list[str],
fetch_fulltext_for_sample_size: bool = False,
) -> list[dict]:
"""
输入 ['38234567', ...] → 输出每条带 grade / grade_rationale 的字典。
内部:批量 pubmed-eutils.efetch_pubmed() → 解析 publication_type → 应用 grade-rules.md。
fetch_fulltext_for_sample_size=True 时,对疑似 RCT/Cohort 调 bioc-fulltext-fetch.to_rag_chunks() 抽 n。
"""
# ============== 3. 推荐检索策略 ==============
def recommend_search_strategy(
question_type: str, # 'therapy' | 'diagnosis' | 'etiology' | 'prognosis' | 'harm' | 'prediction' | 'guideline' | 'sr'
user_query: str = "",
) -> dict:
"""
返回 {clinical_queries_filter, pubmed_query_template, europepmc_query_template,
expected_grade_distribution, recommended_skill, tips[]}.
完整 8 类映射见 references/clinical-queries-mapping.md。
"""
# ============== 4. 反向证据交叉验证 ==============
def cross_validate_evidence(
claim: str, # 例: "Posaconazole 预防 IFI 比 fluconazole 更有效"
top_k: int = 10,
min_grade: str = "B",
) -> dict:
"""
NLP 拆解 claim → PICO → 反向搜索高等级证据。
返回 {claim, pico, supporting[], contradicting[], verdict, confidence}.
verdict ∈ {supported, contradicted, mixed, insufficient}.
"""
# ============== 5. 证据汇总报告 ==============
def evidence_summary(
graded_list: list[dict],
output_format: str = "markdown", # 'markdown' | 'html' | 'json'
output_path: str | None = None, # 提供则写 evidence/_summary.md
) -> str:
"""
生成等级分布表 + Top 5 grade-A 摘要表 + 关键发现 + 引用建议 + 缺口提示。
"""
| question_type | 优先 grade | 主调 skill |
|---|---|---|
| therapy | A-B | pubmed-eutils.pubmed_clinical_queries(scope='therapy/narrow') |
| diagnosis | A-C | pubmed-eutils + europepmc-search |
| etiology | B-C | pubmed-eutils |
| prognosis | B-C | pubmed-eutils |
| harm | A-C | pubmed-eutils + clinical-trials-v2 (AE 表) |
| prediction | A-B | pubmed-eutils |
| guideline | A only | pubmed-eutils.pubmed_clinical_queries(scope='guidelines') |
| sr | A only | pubmed-eutils + europepmc-search |
完整查询模板与罕见病调整见 references/clinical-queries-mapping.md。
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
| BioMCP 检测到但调用失败 | MCP server 配置存在但未启动/版本不兼容 | 静默回退 slow-path,日志告警,不阻塞 |
| BioMCP 故障 fall-back 至 slow-path 但 NCBI 也限流 | 双路连续失败 | 加 jitter 退避,3 次后切 europepmc-search 单源,grade 标 _partial |
| GRADE 自动评级 publication_type 缺失 | 文献 < 6 个月未 MeSH 索引 | 启发式推断(见 grade-rules.md),grade 加 _inferred 后缀,警告用户人工复核 |
| 样本量提取失败(efetch 摘要不含 n) | 全文不可访问 / 摘要写法不规范 | 跳过 n 校验,grade 按 publication_type 默认值,不应用 n 阈值降权 |
| 重复 PMID 跨原子 skill 未去重 | BioMCP 已去重但回退到 slow-path 未去重 | 强制 evidence_id = "PMID:" + pmid 三段优先级(PMID > PMCID > DOI)再去重 |
| 证据矛盾(同一 claim 高等级证据正反皆有) | 真实存在的临床争议 | cross_validate_evidence 返回 verdict='mixed',supporting 与 contradicting 并列展示,不强行下结论 |
| 缓存命中但 GRADE 规则更新过 | grade-rules.md 升级未 bump 版本 | grade_rule_version 字段不匹配视为 miss,自动重算并刷新缓存 |
| evidence/ 文件夹组织规范冲突 | 下游 evidence-appendix-sync 期望 grade-A/B/C/D 子目录 | 严格按 grade-A/PMID-XXX_AuthorYear.json 命名,变动需双方同步升级 |
| 同一研究多 PMID(预印本+正式版) | medRxiv → 期刊 | 优先保留期刊版,预印本标记 superseded_by |
| 中文期刊文献缺失 | NCBI 不索引部分中文期刊 | 提示用户用 CNKI / 万方补充,本 skill 不覆盖中文数据库 |
完整缓存策略见 references/cache-schema.md。
下游 evidence-appendix-sync 期望本 skill 产出:
evidence/
├── grade-A/
│ ├── PMID-32786187_DiNardo-NEJM-2020.json
│ └── PMID-32786187_DiNardo-NEJM-2020_abs.txt
├── grade-B/ grade-C/ grade-D/ excluded/
├── _summary.md # evidence_summary() 产出
├── _index.csv # 全部文献索引(便于附录 C 引用)
└── _query_log.jsonl # 检索日志(可复现)
每条 *.json 含 {evidence_id, grade, grade_rationale, citation_apa, citation_chinese, metadata, abstract, fetched_at, source_chain}。
本 skill 与具体疾病无关,移植到肺癌/糖尿病等只需:
/skills 列表查看)evidence_search(rare_disease_mode=True) 自动放宽阈值(见 grade-rules.md)Comparative Effectiveness Research 类型识别| 平台 | 兼容性 | 说明 |
|---|---|---|
| Claude Code | 原生 | SKILL.md 自动加载,Skill 工具直接调用 |
| Codex (CLI) | 兼容 | 复制到 $CODEX_HOME/skills/medical-evidence-grading/,通过 skill-installer |
| Gemini CLI | 兼容 | 作为 prompt template 使用,函数签名需手工实现 |
| Cursor / Continue | 部分 | 提取 GRADE 规则表(见 grade-rules.md)作为 system prompt |
关键不变量(确保跨平台一致):
~/.claude/skills/medical-evidence-grading/cache.sqlite (Path.home() 自动适配)~/.claude/mcp.json / ~/.codex/config.toml / BIOMCP_ENDPOINT 环境变量主文件保持精简;深度细节按需加载:
references/grade-rules.md — GRADE 评级完整规则表 + 降权升权信号 + 启发式推断 + 跨疾病阈值references/clinical-queries-mapping.md — Clinical Queries 8 类问题映射 + 多类型并行 + 罕见病调整 + 中国本土补充references/biomcp-integration.md — BioMCP fast-path 检测三路 + fall-back 触发条件 + slow-path 自建 fan-out + 跨平台配置references/cache-schema.md — SQLite cache 表结构 + TTL 策略 + 命中检测 + 维护命令# 示例 1: 找血液 IFI 最新指南
result = evidence_search(
query="invasive fungal infection prophylaxis hematology",
target_grade="guideline_only",
max_results=20,
date_range="5years",
)
# 返回 ECIL / IDSA / NCCN 等指南
# 示例 2: 给已有 PMID 列表打分
graded = grade_pmid_list(
pmid_list=["32786187", "37123456", "38234567"],
fetch_fulltext_for_sample_size=True,
)
# 示例 3: 反向验证临床声明
verdict = cross_validate_evidence(
claim="Posaconazole 预防 IFI 比 fluconazole 更有效",
top_k=10,
min_grade="B",
)
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.