Install any skill in seconds. Free to start, no credit card required.
Get Started Free →钉钉操作助手(DingTalk)。当用户通过钉钉对话、或提到以下任何场景时必须使用此技能:查人(查下某某、搜一下某人、找一下谁谁)、查部门、查手机号、查工号、约会议(预约会议、创建会议、安排会议、开个会)、发消息(给某人发消息、群里发个通知)、查审批(我的审批、待审批、审批状态)、发起审批、同意/拒绝审批、查日程、创建日程、查员工数、查离职、开视频会议、钉钉知识库(查钉钉知识库、在钉钉创建文档、搜索钉钉文档、覆写钉钉文档)。注意:当用户从钉钉渠道发送消息时,"知识库"默认指钉钉知识库,不是飞书知识库。
SkillScore88/100
Test results 88
3/3 safety checks passed
16%88%of test cases passed +72 pts
Passed 22 of 25 test cases with the skill, and 4 of 25 without it.
18 fixed4 passed either way3 still failing0 broke
One test taskA manager with userId 'mgr001' needs to approve an OA approval instance 'inst_999' with a comment 'Approved'. Which command should be executed?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add leoyeai-ding-skills
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("leoyeai-ding-skills")
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 leoyeai-ding-skillsThe 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/leoyeai-ding-skills/SKILL.md https://app.decimal.ai/s/leoyeai-ding-skills/SKILL.md.claude/skills/leoyeai-ding-skills/SKILL.mdThis gets SKILL.md only. The skill's 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsimport 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsfrom 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("leoyeai-ding-skills")
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/leoyeai-ding-skills/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/leoyeai-ding-skills/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 45 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 leoyeai-ding-skillsNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/leoyeai-ding-skills/SKILL.md https://app.decimal.ai/s/leoyeai-ding-skills/SKILL.md.agents/skills/leoyeai-ding-skills/SKILL.mdThis gets SKILL.md only. The skill's 45 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 45 other files are not included.
Raw files: /s/leoyeai-ding-skills/SKILL.md · /s/leoyeai-ding-skills.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/leoyeai-ding-skills/SKILL.mdcurl -fsSL https://app.decimal.ai/s/leoyeai-ding-skills.jsonThis gets SKILL.md only. The skill's 45 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.
钉钉全功能技能集:用户管理、部门管理、消息发送、OA审批、视频会议、日程管理。
DINGTALK_APP_KEY 和 DINGTALK_APP_SECRETexport DINGTALK_APP_KEY="<your-app-key>"
export DINGTALK_APP_SECRET="<your-app-secret>"
export DINGTALK_ROBOT_CODE="<your-robot-code>" # 可选,发消息时使用
大部分钉钉 API 需要 userId 或 unionId,但用户通常只会说人名。遇到人名时,必须先查人再执行操作。
当用户说"帮我和张三、李四开个会"或"预约一个会议,参会人:张三、李四"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: 对每个参会人重复步骤1-2
步骤4: python scripts/create_schedule_conference.py "<主题>" "<发起人unionId>" "<开始时间>" "<结束时间>" "<参会人unionId1,unionId2>" "[会议地点]"
当用户说"给张三发个消息"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/send_user_message.py "<userId>" "<消息内容>"
注意:robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
当用户说"查下张三的待审批"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/list_user_todo_approvals.py "<userId>"
当用户说"查下张三今天的日程"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/list_events.py "<unionId>" "[开始时间]" "[结束时间]"
当用户说"在知识库里创建一个文档"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/list_workspaces.py "<unionId>" → 得到 workspaceId
步骤4: python scripts/create_doc.py "<workspaceId>" "<文档名>" "<unionId>"
当用户说"帮我找一下知识库里的《周报》"时:
步骤1: python scripts/search_user.py "张三" → 得到 userId
步骤2: python scripts/get_user.py "<userId>" → 得到 unionId
步骤3: python scripts/search_doc.py "<unionId>" "周报" → 得到文档链接
search_user.py 获取 userIdget_user.py 从 userId 获取 unionId根据姓名搜索用户,返回匹配的 UserId 列表。
python scripts/search_user.py "<搜索关键词>"
输出:
{
"success": true,
"keyword": "张三",
"totalCount": 3,
"hasMore": false,
"userIds": ["123456789", "987654321"]
}
获取指定用户的详细信息。
python scripts/get_user.py "<userId>"
输出:
{
"success": true,
"user": {
"userid": "user001",
"name": "张三",
"mobile": "138****1234",
"dept_id_list": [12345],
"unionid": "xxxxx"
}
}
python scripts/get_user_by_mobile.py "<手机号>"
输出:
{ "success": true, "mobile": "13800138000", "userId": "user001" }
python scripts/get_user_by_unionid.py "<unionid>"
输出:
{ "success": true, "unionid": "xxxxx", "userId": "user001" }
python scripts/get_user_count.py [--onlyActive]
输出:
{ "success": true, "onlyActive": false, "count": 150 }
python scripts/get_user_todo_count.py "<userId>"
输出:
{ "success": true, "userId": "user001", "count": 5 }
python scripts/list_inactive_users.py "<queryDate>" [--deptIds "id1,id2"] [--offset 0] [--size 100]
queryDate 格式: yyyyMMdd
输出:
{ "success": true, "queryDate": "20240115", "userIds": ["user001"], "hasMore": false }
python scripts/list_resigned_users.py "<startTime>" ["<endTime>"] [--nextToken "xxx"] [--maxResults 100]
startTime/endTime 格式: ISO8601
输出:
{
"success": true,
"startTime": "2024-01-01T00:00:00+08:00",
"records": [{ "userId": "user001", "name": "张三", "leaveTime": "2024-01-15T10:00:00Z" }]
}
python scripts/search_department.py "<搜索关键词>"
输出:
{ "success": true, "keyword": "技术部", "totalCount": 2, "departmentIds": [12345, 67890] }
python scripts/get_department.py "<deptId>"
输出:
{ "success": true, "department": { "deptId": 12345, "name": "技术部", "parentId": 1 } }
根部门 deptId = 1。
python scripts/list_sub_departments.py "<deptId>"
输出:
{ "success": true, "deptId": 1, "subDepartmentIds": [12345, 67890] }
自动分页获取所有用户(简略信息)。
python scripts/list_department_users.py "<deptId>"
输出:
{
"success": true,
"deptId": 12345,
"users": [{ "userId": "user001", "name": "张三" }, { "userId": "user002", "name": "李四" }]
}
分页获取,支持 cursor 和 size。
python scripts/list_department_user_details.py "<deptId>" [--cursor 0] [--size 100]
输出:
{ "success": true, "deptId": 12345, "users": [...], "hasMore": true, "nextCursor": 100 }
python scripts/list_department_user_ids.py "<deptId>"
输出:
{ "success": true, "deptId": 12345, "userIds": ["user001", "user002"] }
python scripts/list_department_parents.py "<deptId>"
输出:
{ "success": true, "deptId": 12345, "parentIdList": [12345, 67890, 1] }
python scripts/list_user_parent_departments.py "<userId>"
输出:
{ "success": true, "userId": "user001", "parentIdList": [12345, 1] }
python scripts/get_bot_list.py "<openConversationId>"
输出:
{
"success": true,
"openConversationId": "cid",
"botList": [{ "robotCode": "code", "robotName": "name" }]
}
robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
python scripts/send_group_message.py "<openConversationId>" "<消息内容>" ["<robotCode>"]
输出:
{ "success": true, "openConversationId": "cid", "robotCode": "code", "processQueryKey": "key", "message": "消息内容" }
robotCode 自动从环境变量 DINGTALK_ROBOT_CODE 读取,也可作为第3个参数手动传入。
python scripts/send_user_message.py "<userId>" "<消息内容>" ["<robotCode>"]
输出:
{ "success": true, "userId": "user001", "robotCode": "code", "processQueryKey": "key", "message": "消息内容" }
python scripts/list_approval_instance_ids.py "<processCode>" --startTime <timestamp> --endTime <timestamp> [--size 20] [--nextToken "xxx"]
输出:
{ "success": true, "processCode": "PROC-XXX", "instanceIds": ["id1", "id2"], "totalCount": 2, "hasMore": false }
python scripts/get_approval_instance.py "<instanceId>"
输出:
{
"success": true,
"instanceId": "xxx-123",
"instance": {
"processInstanceId": "xxx-123",
"title": "请假申请",
"status": "COMPLETED",
"formComponentValues": [...],
"tasks": [...]
}
}
python scripts/list_user_initiated_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
输出:
{ "success": true, "userId": "user001", "instances": [...], "totalCount": 5, "hasMore": false }
python scripts/list_user_cc_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
python scripts/list_user_todo_approvals.py "<userId>" [--maxResults 20]
输出:
{ "success": true, "userId": "user001", "instances": [...], "totalCount": 3, "hasMore": false }
python scripts/list_user_done_approvals.py "<userId>" [--startTime <ts>] [--endTime <ts>] [--maxResults 20]
python scripts/create_approval_instance.py "<processCode>" "<originatorUserId>" "<deptId>" '<formValuesJson>' [--ccList "user1,user2"]
formValuesJson 示例: '[{"name":"标题","value":"请假申请"}]'
输出:
{ "success": true, "processCode": "PROC-XXX", "originatorUserId": "user001", "instanceId": "xxx-new" }
python scripts/terminate_approval_instance.py "<instanceId>" "<operatingUserId>" ["<remark>"]
输出:
{ "success": true, "instanceId": "xxx-123", "message": "审批实例已撤销" }
同意或拒绝审批任务。
python scripts/execute_approval_task.py "<instanceId>" "<userId>" "<agree|refuse>" [--taskId "xxx"] [--remark "审批意见"]
输出:
{ "success": true, "instanceId": "xxx-123", "userId": "user001", "action": "agree", "message": "已同意审批" }
python scripts/transfer_approval_task.py "<instanceId>" "<userId>" "<transferToUserId>" [--taskId "xxx"] [--remark "转交原因"]
输出:
{ "success": true, "instanceId": "xxx-123", "userId": "user001", "transferToUserId": "user002", "message": "审批任务已转交" }
python scripts/add_approval_comment.py "<instanceId>" "<commentUserId>" "<评论内容>"
输出:
{ "success": true, "instanceId": "xxx-123", "userId": "user001", "message": "评论已添加" }
立即创建视频会议并邀请参会人。
python scripts/create_video_conference.py "<会议主题>" "<发起人unionId>" "[邀请人unionId1,unionId2]"
输出:
{ "success": true, "title": "测试会议", "conferenceId": "xxx", "conferencePassword": "123456" }
python scripts/close_video_conference.py "<conferenceId>" "<操作人unionId>"
输出:
{ "success": true, "conferenceId": "xxx", "message": "视频会议已关闭" }
通过日历 API 创建预约会议,自动关联钉钉视频会议,日程会出现在钉钉日历中。
python scripts/create_schedule_conference.py "<会议主题>" "<创建人unionId>" "<开始时间>" "<结束时间>" "[参会人unionId1,unionId2]" "[会议地点]"
时间格式: "2026-03-16 14:00" 或 ISO 8601
输出:
{
"success": true,
"title": "周会",
"eventId": "NXZCUEtxOGZMN3JpcDQ3ZE45UVRFdz09",
"onlineMeetingUrl": "dingtalk://...",
"conferenceId": "xxx",
"startTime": "2026-03-16T14:00:00+08:00",
"endTime": "2026-03-16T15:00:00+08:00",
"attendeeCount": 2
}
python scripts/cancel_schedule_conference.py "<scheduleConferenceId>" "<创建人unionId>"
输出:
{ "success": true, "scheduleConferenceId": "xxx", "message": "预约会议已取消" }
python scripts/list_events.py "<用户unionId>" [--time-min "2026-03-01 00:00"] [--time-max "2026-03-31 23:59"]
输出:
{
"success": true,
"totalCount": 5,
"events": [{ "id": "eventId", "summary": "周会", "start": {...}, "end": {...} }]
}
python scripts/get_event.py "<用户unionId>" "<eventId>"
输出:
{
"success": true,
"event": { "id": "eventId", "summary": "周会", "attendees": [...], "onlineMeetingInfo": {...} }
}
python scripts/delete_event.py "<用户unionId>" "<eventId>" [--push-notification]
输出:
{ "success": true, "eventId": "xxx", "message": "日程已删除" }
python scripts/add_event_attendee.py "<用户unionId>" "<eventId>" "<参与者unionId1,unionId2>"
输出:
{ "success": true, "eventId": "xxx", "addedCount": 2, "message": "已添加 2 位参与者" }
python scripts/remove_event_attendee.py "<用户unionId>" "<eventId>" "<参与者unionId1,unionId2>"
输出:
{ "success": true, "eventId": "xxx", "removedCount": 1, "message": "已移除 1 位参与者" }
获取用户能访问的所有知识库。
python scripts/list_workspaces.py "<操作人unionId>"
输出:
{
"success": true,
"totalCount": 2,
"workspaces": [
{ "workspaceId": "xxx", "name": "技术部知识库", "type": "TEAM", "url": "https://...", "rootNodeId": "yyy" }
]
}
在指定知识库中创建新文档。
python scripts/create_doc.py "<workspaceId>" "<文档名>" "<操作人unionId>" ["<docType>"]
docType 可选值:alidoc(钉钉文档,默认)、alisheet(表格)、alinote(笔记)
输出:
{
"success": true,
"name": "周报",
"docType": "alidoc",
"workspaceId": "xxx",
"nodeId": "yyy",
"docKey": "zzz",
"url": "https://..."
}
根据文档名关键词搜索知识库文档,返回文档链接。
python scripts/search_doc.py "<操作人unionId>" "<文档名关键词>" ["<workspaceId>"]
不指定 workspaceId 时搜索所有知识库。
输出:
{
"success": true,
"keyword": "周报",
"totalCount": 3,
"documents": [
{ "name": "3月第2周周报", "nodeId": "xxx", "url": "https://...", "category": "ALIDOC", "workspaceName": "技术部知识库" }
]
}
覆写知识库文档的全部内容(全量替换,非追加)。
python scripts/overwrite_doc.py "<workspaceId>" "<nodeId>" "<操作人unionId>" "<内容>"
输出:
{ "success": true, "workspaceId": "xxx", "nodeId": "yyy", "message": "文档内容已覆写" }
所有脚本在错误时返回统一格式:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "错误描述"
}
}
常见错误码:
MISSING_CREDENTIALS - 未设置环境变量INVALID_ARGS - 参数不足UNKNOWN_ERROR - API 调用异常userId 是企业内部用户 ID,unionId 是全局唯一标识unionId,可通过 get-user 查询获取workspaceId 通过 list-workspaces 获取,nodeId 通过 search-doc 获取Automatically, when a task matches. Use when user mentions anything about DingTalk or when the message comes from a DingTalk channel: looking up people, searching users/departments, scheduling meetings, creating conferences, sending messages, managing approvals, checking calendar ev
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.