Install any skill in seconds. Free to start, no credit card required.
Get Started Free →ECM 尽职调查工具类 Skill:调用第三方公开数据源(Tushare Pro / 企查查开放平台)与客户 提供的材料做交叉比对,发现数据不一致、未披露变更、过期信息等问题。当用户提到以下场景时 触发:外部数据验证、第三方数据核实、自动比对工商信息 / 股东 / 主要人员 / 知识产权 / 行政处罚、 用 Tushare 查财务数据 / 用企查查查工商、客户提供的营业执照 / 股东名册与外部工商档案是否一致、 API 数据比对、public data verification、cross-check 客户材料、抓取外部公开数据、 核实注册资本、核实法定代表人、核实实控人穿透、查专利 / 商标 / 软著是否真实存在、 查行政处罚记录。 典型输入:公司统一社会信用代码 / 名称 / ts_code、需比对的维度列表、客户提供的对应数据; 典型输出:数据比对报告(Markdown 表格 + 差异分析 + 建议核实清单)。 非触发边界:本 skill 是**工具类**不输出 DD Memo(五段式);真正的合规判断由各业务 DD skill 去做。不负责文件读取(归 ecm-dd-file-
SkillScore74/100
Test results 74
3/3 safety checks passed
22%74%of test cases passed +52 pts
Passed 17 of 23 test cases with the skill, and 5 of 23 without it.
12 fixed5 passed either way6 still failing0 broke
One test task对'华创微电子有限公司'注册地址做比对。客户登记地址为'北京市海淀区中关村南大街1号101室',外部接口返回'北京市海淀区中关村南大街1号101'。请给出差异级别判断。
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add thomasmoreai-ecm-dd-data-verify
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("thomasmoreai-ecm-dd-data-verify")
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 thomasmoreai-ecm-dd-data-verifyThe 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/thomasmoreai-ecm-dd-data-verify/SKILL.md https://app.decimal.ai/s/thomasmoreai-ecm-dd-data-verify/SKILL.md.claude/skills/thomasmoreai-ecm-dd-data-verify/SKILL.mdThis gets SKILL.md only. The skill's 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyimport 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyfrom 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("thomasmoreai-ecm-dd-data-verify")
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/thomasmoreai-ecm-dd-data-verify/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/thomasmoreai-ecm-dd-data-verify/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 2 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 thomasmoreai-ecm-dd-data-verifyNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/thomasmoreai-ecm-dd-data-verify/SKILL.md https://app.decimal.ai/s/thomasmoreai-ecm-dd-data-verify/SKILL.md.agents/skills/thomasmoreai-ecm-dd-data-verify/SKILL.mdThis gets SKILL.md only. The skill's 2 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 2 other files are not included.
Raw files: /s/thomasmoreai-ecm-dd-data-verify/SKILL.md · /s/thomasmoreai-ecm-dd-data-verify.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/thomasmoreai-ecm-dd-data-verify/SKILL.mdcurl -fsSL https://app.decimal.ai/s/thomasmoreai-ecm-dd-data-verify.jsonThis gets SKILL.md only. The skill's 2 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.
本 skill 是 ECM DD 的工具类 skill,和 17 个业务性 DD skill(dd-approval / dd-entity / … / dd-compliance)有明显的职责分工:
⚠️ 本 skill 不套用
shared/templates/dd-skill-template.md的五段式输出契约。 该模板只约束业务性 DD skill。本 skill 走自己的"数据比对报告"格式。
scripts/tushare_connector.py / scripts/qcc_connector.py 取外部数据ecm-dd-file-reviewecm-setup-file-organizeecm-research-reg-search / ecm-research-reg-study本 skill 产出的数据比对报告仅为尽调辅助工具底稿,不构成最终法律意见。Tushare 与企查查是 第三方商业数据源,数据口径与更新频率由其运营方决定,存在滞后或偏差的可能。关键事项仍须 以政府主管部门出具的官方文件为准。完整免责声明见 DISCLAIMER.md。
执行本 skill 时,必须同时遵循 senior-lawyer-execution-standards.md。本 skill 的任何输出不得突破四条底线:事实可追溯、法源可核验、风险可分级、建议可落地;无法核验时必须显式标注。
from __future__ import annotations)pip install -r scripts/requirements.txt(requests / pandas 等)TUSHARE_TOKEN(Tushare Pro 账号 token)QCC_APPKEY + QCC_SECRET(企查查开放平台凭证)ecm-setup-file-organize:已归位的客户文件,本 skill 据此定位"客户侧数据"ecm-dd-file-review:如需从 PDF/Word/Excel 中抽取客户侧字段值,先调用它目前已封装的数据源:
| 数据源 | 覆盖维度 | 典型用途 |
|---|---|---|
| Tushare Pro | 上市公司基础、财务指标、前十大股东、利润表 / 资产负债表 | 已上市标的反查、财务口径核验 |
| 企查查 | 工商基础、股东及出资、主要人员、工商变更、知识产权、行政处罚 | 全量非上市标的核验(发行人自身 / 股东 / 子公司 / 关联方) |
和律师确认本次需要比对的维度。ECM DD 场景常见的 6 大维度:
| 维度 | 对应字段 | 数据源优先级 |
|---|---|---|
| 工商基本信息 | 企业名称、统一社会信用代码、注册资本(实缴 / 认缴)、成立日期、注册地址、经营范围、法定代表人、登记机关、企业状态 | 企查查 > Tushare |
| 股东信息 | 股东名称、出资额、持股比例、出资方式、出资日期 | 企查查(穿透)+ Tushare(上市公司前十大) |
| 主要人员 | 法定代表人、董事、监事、高管 | 企查查 + Tushare stock_company |
| 知识产权 | 专利号、商标注册号、软著登记号、权利人 | 企查查 |
| 行政处罚 | 处罚机关、处罚日期、处罚事由、处罚结果 | 企查查 |
| 财务数据 | 营业收入、净利润、资产总额、负债总额、股东权益、ROE | Tushare(仅上市公司) |
不在列表里但用户要求的维度,应以"可扩展点"加入 references/dimensions-registry.md。
使用对应脚本的 --smoke 模式检查凭证:
python scripts/tushare_connector.py --smoke
python scripts/qcc_connector.py --smoke
对于每个维度,先确定"客户说什么":
02-尽职调查/02-02-主体资格/ 等目录读取相关文件(由
ecm-dd-file-review 完成)把客户侧数据整理成结构化表格写入 references/client-data-staging.md(工作区临时文件),
明确每个值的来源。
按维度调用 connector。推荐脚本方式(可追溯 + 留日志):
# 工商基础 + 股东 + 处罚
python scripts/qcc_connector.py \
--basic "腾讯科技(深圳)有限公司" \
> 05-底稿和附件/数据比对/qcc_basic_$(date +%Y%m%d_%H%M%S).json
# 已上市标的:基础 + 财务
python scripts/tushare_connector.py \
--ts-code 600519.SH --fields full \
--period 20241231 --financials
库方式(供编排脚本使用):
from scripts.qcc_connector import QccClient, MissingCredentialError
c = QccClient()
try:
basic = c.company_basic("腾讯科技(深圳)有限公司")
keyno = basic["Result"][0]["KeyNo"]
shareholders = c.shareholders(keyno)
penalty = c.penalty(keyno)
except MissingCredentialError:
# 跳到 fallback
...
所有原始响应 留痕到 05-底稿和附件/数据比对/ 目录,保留到项目归档。
按下方"输出格式契约"生成 Markdown 报告。差异分级规则:
| 级别 | 含义 | 典型情形 |
|---|---|---|
| 高 | 核心字段存在实质差异,可能触发业务级高风险 | 注册资本客户说 5000 万、API 显示 3000 万;法定代表人客户写张三、API 显示李四;实控人穿透链断裂 |
| 中 | 次要字段差异或信息滞后 | 经营范围表述不同但实质相近;最近一次变更未同步到 API(<30 天) |
| 低 | 格式 / 笔误 / 翻译差异 | 名称全角 / 半角括号差异;地址后缀"号""栋"差异;单位万元 / 元 |
差异 ≠ 业务风险。差异的业务意义由调用本 skill 的上层业务 DD skill 判断。
无法取到外部数据时,绝不伪造。改为输出"人工核对清单":
# 数据比对报告(fallback 模式)
> 本次比对因 [外部 API 凭证缺失 / API 返回错误 / 数据源暂时不可用],
> 已自动降级为"人工核对清单"。以下字段需要项目组律师**手工登录相应平台**核对,
> 核对完成后把结果补充到本报告。
## 建议的人工核对渠道
- 企查查官网 https://www.qcc.com/
- 天眼查 https://www.tianyancha.com/
- 国家企业信用信息公示系统 https://www.gsxt.gov.cn/
- 裁判文书网 https://wenshu.court.gov.cn/
- 证监会行政处罚库 http://www.csrc.gov.cn/pub/zjhpublic/ (搜索"行政处罚决定书")
## 待人工核对字段清单
| 维度 | 字段 | 客户侧数据 | 官方口径(待核对) | 核对结果 |
|------|------|-----------|-------------------|---------|
| 工商 | 注册资本 | 5000 万元 | (待核对) | |
| 工商 | 法定代表人 | 张三 | (待核对) | |
| ... | ... | ... | ... | |
# 数据比对报告:{客户简称}
> 项目:{客户简称} | 编制日期:YYYY-MM-DD | 编制人:{律师姓名}
> 数据源:{Tushare Pro / 企查查 / 二者}
> 凭证状态:{均可用 / 仅 Tushare / 仅企查查 / 均不可用(fallback 模式)}
## 一、比对维度与数据源
| 维度 | 数据源 | 抓取时间 | 原始响应存档 |
|------|-------|---------|-------------|
| 工商基本信息 | 企查查 | 2026-04-24 10:30 | 05-底稿和附件/数据比对/qcc_basic_20260424_103000.json |
| 股东信息 | 企查查 | 2026-04-24 10:31 | ... |
| 财务数据 | Tushare Pro | 2026-04-24 10:32 | ... |
## 二、比对结果汇总
| 序号 | 维度 | 字段 | 客户侧数据 | 外部数据 | 差异 | 级别 | 备注 |
|-----:|------|------|-----------|---------|------|------|------|
| 1 | 工商 | 注册资本 | 5000 万元 | 5000 万元 | 无 | - | 一致 |
| 2 | 工商 | 法定代表人 | 张三 | 李四 | 人名不同 | 高 | 建议核实最近变更 |
| 3 | 股东 | 股东 A 持股比例 | 30% | 28% | -2 个百分点 | 高 | 疑有未披露股权转让 |
## 三、差异分析
### 差异 2:法定代表人不一致
- 客户侧来源:02-02-主体资格/营业执照-20250312.pdf
- API 侧数据:企查查 2026-04-23 抓取
- 可能原因:
1. 客户营业执照为旧版,未及时更换
2. 外部数据源未同步最近变更
3. 存在未披露的治理层变更
- 建议核实:向客户索取最新营业执照 + 变更登记通知书;同时查工商局在线档案
### 差异 3:股东持股比例不一致
...
## 四、建议核实事项
- **高风险项(立即核实)**:
1. 法定代表人差异——要求客户提供最近一次变更登记完整档案
2. 股东 A 持股比例差异——要求客户提供近两年历次股权变更协议
- **中风险项(次轮核实)**:
- ...
- **低风险项(可一并处理)**:
- ...
## 五、数据源局限与注意事项
- 企查查数据有 T+{N} 天滞后,本次抓取时间:2026-04-24
- Tushare 财务数据以公司披露的定期报告为准,定期报告披露前可能暂无最新季度数据
- 行政处罚维度仅覆盖公开发布的处罚决定书,部门内部处理、未公开的警示谈话等不在覆盖范围
- 关键事项仍以政府主管部门出具的官方文件为准
## 六、附件
- 05-底稿和附件/数据比对/qcc_basic_YYYYMMDD_HHMMSS.json
- 05-底稿和附件/数据比对/qcc_shareholders_YYYYMMDD_HHMMSS.json
- 05-底稿和附件/数据比对/tushare_fina_YYYYMMDD_HHMMSS.csv
- (下级业务 DD skill 可直接引用上述原始响应)
契约硬性要求:
05-底稿和附件/数据比对/数据比对报告-{YYYYMMDD}.md
(如该目录尚未建立,先按 shared/templates/project-folder-structure.md 创建)05-底稿和附件/数据比对/,不得仅贴到报告里业务 DD skill 可以在自己的"核心工作流"里插入本 skill 作为可选前置步骤。约定:
ecm-dd-data-verify 对 {具体字段}
做外部数据核验"典型链路:
ecm-dd-entity(主体资格)
└─ 可选调用 ecm-dd-data-verify(工商基本信息维度)
└─ 调用 scripts/qcc_connector.py --basic
Q:可以让本 skill 直接生成 DD Memo 吗? A:不可以。本 skill 是工具,产出的是"数据差异"。业务合规判断必须由对应业务 DD skill 完成。
Q:API 数据和客户数据都对不上怎么办? A:记为"高"级差异,写进报告的"差异分析",并建议人工登录政府主管部门官网核对 —— 以官方 档案为最终仲裁。
Q:可以把 TUSHARE_TOKEN 写到仓库的某个文件里吗? A:不可以。任何形式落盘都违反本 skill 的安全约束。见 docs/data-connectors.md。
Q:我只想手动对一下,不想跑脚本? A:可以。走 fallback 模式:不调用 API,仅输出"人工核对清单"+"建议核对渠道"。
references/dimensions-registry.md 和
docs/data-connectors.mdSkills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.