Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Java/Maven single-module deep documentation generator. Generates L3(file-level) to L2(module-level) business logic docs for specified module. Supports multi-subagent parallel processing, context compression, checkpoint resume, and auto-retry.
SkillScore68/100
Test results 68
3/3 safety checks passed
14%68%of test cases passed +55 pts
Passed 15 of 22 test cases with the skill, and 3 of 22 without it.
12 fixed3 passed either way7 still failing0 broke
One test taskWe are generating the L3 document for the source file located at `admin-api/src/main/java/com/company/service/UserService.java`. What must be the exact output path for the generated markdown file relative to the project root?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add leoyeai-module-analyzer-generate-doc
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-module-analyzer-generate-doc")
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-module-analyzer-generate-docThe 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-module-analyzer-generate-doc/SKILL.md https://app.decimal.ai/s/leoyeai-module-analyzer-generate-doc/SKILL.md.claude/skills/leoyeai-module-analyzer-generate-doc/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 3 other files are not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 3 other files are not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 3 other files are not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add leoyeai-module-analyzer-generate-docimport 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 3 other files are not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add leoyeai-module-analyzer-generate-docfrom 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-module-analyzer-generate-doc")
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-module-analyzer-generate-doc/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 3 other files are not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add leoyeai-module-analyzer-generate-docNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.md https://app.decimal.ai/s/leoyeai-module-analyzer-generate-doc/SKILL.md.agents/skills/leoyeai-module-analyzer-generate-doc/SKILL.mdThis gets SKILL.md only. The skill's 3 other files are not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 3 other files are not included.
Raw files: /s/leoyeai-module-analyzer-generate-doc/SKILL.md · /s/leoyeai-module-analyzer-generate-doc.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-module-analyzer-generate-doc/SKILL.mdcurl -fsSL https://app.decimal.ai/s/leoyeai-module-analyzer-generate-doc.jsonThis gets SKILL.md only. The skill's 3 other files are not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
专注于单个 Java/Maven 模块的深度业务逻辑分析 - 让 AI 全面理解模块的每个细节
单模块深度分析:
智能任务执行:
文档质量保证:
智能跳过机制:
当用户提到以下关键词时激活:
与 project-analyzer-generate-doc 的区别:
project-analyzer-generate-doc:全项目多模块扫描,生成 L3→L2→L1 三层文档module-analyzer-generate-doc:单模块深度扫描,生成 L3→L2 两层文档(更详细、更快速)# 1. 扫描模块目录结构
Get-ChildItem "<模块路径>" -Directory -Recurse | Where-Object { $_.Name -notmatch 'target|\.git|build' }
# 2. 统计 Java 文件
$javaFiles = Get-ChildItem "<模块路径>/src/main/java" -Include *.java -Recurse | Where-Object { $_.FullName -notmatch '\\test\\' }
# 3. 统计 XML 文件(MyBatis Mapper)
$xmlFiles = Get-ChildItem "<模块路径>/src/main/resources" -Include *.xml -Recurse | Where-Object { $_.Name -match 'mapper|Mapper' }
# 4. 检查已存在文档
$existingDocs = Get-ChildItem "<项目根目录>/.ai-doc/<模块名>" -Include *.md -Recurse 2>$null
# 5. 制定分片计划
# - <20 文件:单子代理
# - 20-50 文件:3-4 个子代理分片
# - >50 文件:5-6 个子代理分片,每片 10-16 个文件
输出: 文件列表 + 分片计划 + 已存在文档检查
目的: 检查已存在的文档是否符合要求,按需迁移或更新
检查规则:
1. 文档路径是否符合 `.ai-doc/模块名/src/main/java/包路径/类名.java.md` 规则
2. 文档内容是否包含详细业务逻辑描述(非简单解释)
3. 文档是否包含代码片段(应全部为自然语言)
处理策略:
- 路径不符合 → 迁移到正确位置
- 内容过于简单 → 重新生成
- 内容符合要求 → 保留,不重复生成
- 源码已变更 → 更新文档
目的: 识别不符合要求的文档,仅生成报告,不自动删除
# 1. 识别低质量文档(只有模板框架,无实际业务内容)
$lowQualityDocs = Get-ChildItem "<项目根目录>/.ai-doc/<模块名>" -Include *.md -Recurse | Where-Object {
$content = Get-Content $_.FullName -Raw
$lineCount = (Get-Content $_.FullName).Count
# 行数少于 20 行
$lineCount -lt 20 -or
# 只包含模板框架文字
$content -match 'Business component - participates in system business processing' -or
$content -match 'Executes business logic based on specific scenario' -or
$content -match 'Simple data object' -or
$content -match 'Interface definition - declares contract specification'
}
# 输出报告,供用户决定是否处理
foreach ($doc in $lowQualityDocs) {
Write-Host "低质量文档:$($doc.FullName)"
}
# 2. 识别空文件夹(供用户参考)
Get-ChildItem "<项目根目录>/.ai-doc/<模块名>" -Directory -Recurse | ForEach-Object {
if ((Get-ChildItem $_.FullName -Force).Count -eq 0) {
Write-Host "空目录:$($_.FullName)"
}
}
⚠️ 重要安全约束:
# 询问用户确认
$confirm = Read-Host "是否删除 $($lowQualityDocs.Count) 个低质量文档?(y/n)"
if ($confirm -eq "y") {
# 移动到回收站而非直接删除(如果可能)
foreach ($doc in $lowQualityDocs) {
Write-Host "将移动到回收站:$($doc.FullName)"
}
}
子代理分片策略:
| 文件总数 | 子代理数 | 每片文件数 | 超时时间 |
|---|---|---|---|
| <20 | 1 | 全部 | 300 秒 |
| 20-50 | 3-4 | 10-16 | 600 秒 |
| 50-80 | 5 | 12-18 | 900 秒 |
| >80 | 6-8 | 10-14 | 900 秒 |
子代理任务模板:
# 任务:为 <模块名> 模块生成 L3 文档(分片 X/Y)
## 项目路径
<绝对路径>
## 源码根目录
<模块路径>/src/main/java
## 输出目录
<项目根目录>/.ai-doc/<模块名>/
## 本分片文件列表
<文件列表,10-16 个>
## 核心要求
### 1. 文档内容要求
- **详细业务逻辑描述**:将代码逻辑转换为自然语言,非程序员也能理解
- **不包含代码片段**:MD 文件中不要出现任何原代码
- **方法级别分析**:每个有业务逻辑的方法都要描述其执行流程、业务语义
- **领域知识**:解释涉及的业务概念、领域术语
- **流程上下文**:方法间的调用关系、数据流转
- **设计意图**:为什么这样设计,解决什么问题
### 2. 文档路径规则(⚠️ 重要!)
- 源文件:`<模块路径>/src/main/java/包路径/类名.java`
- 文档:`<项目根目录>/.ai-doc/<模块名>/src/main/java/包路径/类名.java.md`
- **⚠️ 必须包含 `src/main/java/` 完整路径!**
- **❌ 错误示例**:`.ai-doc/app-api/com/infypower/...`(缺少 src/main/java)
- **✅ 正确示例**:`.ai-doc/app-api/src/main/java/com/infypower/...`
- 生成文档前必须检查路径是否正确,错误路径的文档会被视为无效
### 3. 跳过规则(⚠️ 严格执行!)
**必须跳过的文件类型**(满足任一条件即跳过):
| 类型 | 判断标准 | 示例 |
|------|----------|------|
| **DTO/VO/Param** | 类名以 DTO/VO/Param/BO 结尾,且行数<50,且不包含方法(除 getter/setter) | UserDTO.java, LoginVO.java |
| **枚举** | 包含 `enum` 关键字,且不包含复杂方法 | PaymentStatus.java |
| **常量类** | 类名包含 Constant,且只包含 `public static final` 字段 | AppApiConstant.java |
| **接口** | 包含 `public interface`,且无方法实现 | UserService.java |
| **MapStruct Converter** | 包含 `@Mapper` 注解,或接口名包含 Converter | UserConverter.java |
| **抽象基类** | 包含 `public abstract class`,且方法都是抽象的 | AbstractHandler.java |
| **测试类** | 类名包含 Test,或包含 `@Test` 注解 | UserServiceTest.java |
**代码特征检查**(满足任一条件即跳过):
**⚠️ 必须生成文档的情况**(满足任一条件):
- Controller 类(包含 API 接口)
- Service/ServiceImpl 类
- Helper/Util 类(包含业务方法)
- Consumer/Listener 类(消息处理)
- Job/Task 类(定时任务)
- Config 配置类(包含 Bean 定义)
- Interceptor/Filter/Aspect 类
- 任何包含实际业务逻辑的类
### 4. 文档质量自检(⚠️ 生成后必须检查!)
**生成每个文档后自检**,确保文档合格:
**✅ 合格文档检查清单**(必须全部满足):
- [ ] 文档行数 > 30 行
- [ ] 包含"触发条件"或类似描述(什么时候执行)
- [ ] 包含"输入数据"或"处理流程"描述(如何处理)
- [ ] 包含"业务规则"或"判断逻辑"描述(判断条件)
- [ ] 包含"输出结果"或"数据流转"描述(结果去向)
- [ ] 不包含原代码片段(`public class`, `if ()`, `return` 等关键字)
**❌ 低质量文档特征**(出现任一需重新生成,不建议使用):
- [ ] 文档行数 < 20 行
- [ ] 只包含模板框架("Business component", "Interface definition", "Simple data object")
- [ ] 只重复类名和包名,无实际业务解释
- [ ] 核心业务逻辑部分只有"Executes business logic based on specific scenario"
**自检示例**:
```markdown
# ❌ 低质量文档(需要重新生成)
## Business Responsibility
Business component - participates in system business processing
## Core Business Logic
Executes business logic based on specific scenario
# ✅ 合格文档(正确示例)
## 业务职责
AuthService 是认证服务核心类,处理用户账户的创建、更新、查询,
以及支付宝授权码验证和加密手机号解密。当用户通过小程序授权登录时,
该类负责从微信/支付宝获取用户信息,创建或更新本地用户账户...
## 核心业务逻辑
### 支付宝授权码验证
触发条件:用户在小程序点击授权登录,前端传入 auth_code
处理流程:
1. 调用支付宝 API 换取用户 open_id
2. 验证返回的 open_id 是否有效
3. 根据 open_id 查询本地用户...
# {类名} - 业务逻辑详解
## 基本信息
- **文件路径**: {relativePath}
- **行数**: {lines}
- **文件类型**: {Config/Controller/Service/ServiceImpl/Interceptor/Handler/Util}
- **所属模块**: {moduleName}
## 业务职责
{用自然语言描述这个类的业务职责,200-300 字}
## 核心业务逻辑
### {方法/功能点 1}
{详细描述该功能的业务逻辑流程,包括:
- 触发条件
- 输入数据处理
- 业务规则判断
- 数据流转过程
- 输出结果
- 异常情况处理
}
### {方法/功能点 2}
{同上}
## 业务流程
{描述方法间的调用关系和业务流转过程}
## 数据交互
{描述与数据库、外部服务、Redis、MQ 等的交互}
## 依赖关系
{该类依赖的其他组件和服务}
## 设计意图
{解释为什么这样设计,解决了什么业务问题}
{
"chunk": "X/Y",
"status": "completed|partial",
"processed": ["File1.java", ...],
"skipped": ["SimpleClass.java", ...],
"failed": [],
"summaries": [
{"file": "File1.java", "lines": 150, "type": "Controller", "summary": "一句话业务摘要"}
]
}
**上下文压缩策略**:
每处理 2-3 个文件后: 保留:
丢弃:
---
### Step 2: 生成 L2 模块级文档
**触发条件**: 所有 L3 文档生成完成
**核心策略**:
- spawn 一个子代理
- 读取该模块所有 L3 文档的摘要信息
- 汇总生成 module.md
- 包含模块架构、核心业务流程、依赖关系
**L2 文档模板**:
详见 [references/l2-module-template.md](references/l2-module-template.md)
**核心章节**:
```markdown
# {模块名} - 模块详解
## 模块职责
{200-300 字概述模块的业务定位和核心价值}
## 文件索引表
| 文件路径 | 职责简述 | 类型 | 行数 |
|----------|----------|------|------|
{列出所有已生成 L3 文档的文件}
## 核心业务流程
### 1. {核心流程 1}
{详细描述跨类的业务流程,如用户认证授权流程}
### 2. {核心流程 2}
{如数据权限隔离流程}
### 3. {核心流程 3}
{如系统管理功能流程}
## MyBatis 映射关系
{SQL 与 Java 方法的映射关系,核心表说明}
## 模块依赖
- **内部依赖**: 依赖的其他模块
- **外部服务**: Redis/MySQL/Apollo/RabbitMQ/XXL-Job 等
- **框架依赖**: Spring Boot/MyBatis-Plus/Spring Security 等
## 配置项汇总
{application 配置文件的主要设置,按功能分类}
## 技术栈
{使用的框架和技术组件清单}
路径: <项目根目录>/.ai-doc/.generate-state.json
内容:
{
"version": "1.0.0",
"projectPath": "<项目根目录>",
"targetModule": "<模块名>",
"startTime": "2026-03-07T10:17:00+08:00",
"currentPhase": "L3",
"overallProgress": 76.5,
"phases": {
"L3": {
"status": "completed|in_progress|pending",
"totalFiles": 81,
"processedFiles": 62,
"skippedFiles": 19,
"failedFiles": 0,
"chunks": {
"total": 5,
"completed": 5,
"inProgress": 0,
"pending": 0,
"failed": 0
}
},
"L2": {
"status": "completed|in_progress|pending",
"totalModules": 1,
"completedModules": 0
}
},
"subagents": [
{
"label": "L3-chunk1",
"status": "completed|running|failed|timeout",
"files": 16,
"startTime": "...",
"endTime": "..."
}
],
"lastCheckpoint": "2026-03-07T10:40:00+08:00",
"canResume": true
}
retry_policy:
max_retries: 3 # 最大重试次数
initial_delay: 30 # 初始延迟(秒)
backoff_multiplier: 2 # 延迟倍增因子
max_delay: 300 # 最大延迟(秒)
retryable_errors:
- "timeout"
- "context_overflow"
- "file_access_error"
- "subagent_crash"
频率: 每 20 分钟或每完成一个分片
内容:
## 📊 文档生成进度报告
**模块**: admin-api
**开始时间**: 2026-03-07 10:17:00
**当前时间**: 2026-03-07 10:40:00
**已用时间**: 23 分钟
### 总体进度:76.5%
### 当前阶段:L3 文件级文档生成
| 分片 | 状态 | 已处理 | 已跳过 |
|------|------|--------|--------|
| chunk1 | ✅ | 16 | 0 |
| chunk2 | ✅ | 6 | 10 |
| chunk3 | ✅ | 16 | 0 |
| chunk4 | ✅ | 13 | 4 |
| chunk5 | ✅ | 11 | 7 |
### 统计
- 已处理文件:62
- 已跳过文件:19(纯定义类)
- 失败文件:0
目的: 确保所有包含业务逻辑的源码都有文档可依
流程:
# 1. 扫描所有 Java 文件
$javaFiles = Get-ChildItem "<模块路径>/src/main/java" -Include *.java -Recurse
# 2. 扫描所有已生成文档
$docFiles = Get-ChildItem "<项目根目录>/.ai-doc/<模块名>" -Include *.md -Recurse
# 3. 对比找出缺失文档的文件
foreach ($java in $javaFiles) {
$relative = $java.FullName.Replace("<模块路径>/src/main/java/", "")
$expectedDoc = "<项目根目录>/.ai-doc/<模块名>/$relative.md"
if (!(Test-Path $expectedDoc)) {
# 检查是否应该跳过
$content = Get-Content $java.FullName -Raw
if (ShouldSkip $content) {
Write-Host "跳过 (简单类): $relative"
} else {
Write-Host "缺失文档: $relative"
$missing += $relative
}
}
}
# 4. 对缺失文档的文件 spawn 补充任务
if ($missing.Count -gt 0) {
Spawn subagent to process missing files
}
问题:子代理处理大模块时超时
解决:
1. 检查已生成的文件
2. 将剩余文件拆分为更小的分片(每片 5-7 个文件)
3. 增加超时时间到 15 分钟
4. 重新 spawn 子代理,传递已完成进度
问题:子代理上下文使用率超过 60%
解决:
1. 立即触发强制压缩
2. 如果仍超过 60%,停止当前子代理
3. 将剩余文件拆分为更小的分片
4. 为新分片 spawn 新的子代理
5. 增加压缩频率(每 1 个文件就压缩)
问题:文件因权限限制无法读取
解决:
1. 记录无法访问的文件到日志
2. 请求用户确认文件访问权限
3. 在最终报告中标注无法访问的文件
4. ⚠️ 禁止尝试提权、bash 工具或其他替代读取方式
5. 如果重试 3 次仍失败,跳过该文件
在 TOOLS.md 中添加:
### Module Analyzer - Java 单模块深度文档生成器
- 默认分片大小:10-16 文件/子代理
- 最大并行:5-6 子代理
- 上下文阈值:40% 预警,50% 强制压缩
- 压缩频率:每处理 2-3 个文件
- 简单文件阈值:50 行
- 超时时间:300-900 秒(根据分片大小)
- 重试策略:最多 3 次,指数退避
- 进度汇报:每 20 分钟
- 断点续传:自动保存状态
- 文件读取失败处理:记录并重试
- 二次扫描:自动查漏补充
用户:分析 E:\projects\mgmt-api-cp 的 admin-api 模块,生成业务逻辑文档
AI: 收到!开始执行单模块深度分析流程:
Step 0: 扫描 admin-api 模块结构...
📊 发现 81 个 Java 文件,1 个 XML 文件
Step 0.5: 检查已存在文档...
✅ 发现 20 个已有文档,检查内容质量
Step 1: 生成 L3 文件级文档(5 个子代理并行)...
📊 进度:62/81 文件已处理
🔄 活跃子代理:5/5
⏱️ 预计剩余时间:15 分钟
Step 2: 生成 L2 模块级文档...
✅ admin-api.md 生成完成(26KB)
二次扫描:查漏补充...
✅ 所有业务类都有文档可依
✅ 完成!生成 62 个 L3 文档 + 1 个 L2 模块文档
用户:ces-domain 模块有代码变更,更新文档
AI: 收到!执行增量更新流程:
1. 检测变更文件(git diff 或时间戳比较)
2. 检查已存在文档质量
3. 只更新变更文件的 L3 文档
4. 重新汇总生成 ces-domain.md (L2)
注意:保持文档路径与源码路径一致
用户:继续之前的文档生成任务
AI: 检测到未完成的生成任务...
## 上次任务状态
- 模块:admin-api
- 中断时间:2026-03-07 10:30:00
- 完成进度:L3 阶段 76.5% (62/81 文件)
- 失败分片:1 个(已重试 2 次)
是否从断点继续?(y/n)
用户:y
AI: 恢复任务...
- 跳过已完成的 62 个文件
- 重新处理 1 个失败分片
- 继续生成剩余 19 个文件的 L3 文档
| 模块规模 | L3 生成 | L2 生成 | 总计 |
|---|---|---|---|
| 20 文件 | ~5 分钟 | ~2 分钟 | ~7 分钟 |
| 50 文件 | ~12 分钟 | ~4 分钟 | ~16 分钟 |
| 80 文件 | ~20 分钟 | ~5 分钟 | ~25 分钟 |
| 150 文件 | ~40 分钟 | ~8 分钟 | ~48 分钟 |
| 阶段 | 每文件/模块 | 总计 (80 文件) |
|---|---|---|
| L3 生成 | 200k tokens/文件 | 16M tokens |
| L2 生成 | 350k tokens/模块 | 350k tokens |
| 版本 | 日期 | 变更 |
|---|---|---|
| 1.0.3 | 2026-03-10 | 安全修复 (最终):移除 python 代码块引用、移除"必须执行"强制指令、完整清理所有风险关键词 |
| 1.0.2 | 2026-03-10 | 安全修复 (完整):移除所有 bash/external tool 引用、移除 elevated 权限引用、明确要求用户确认删除/迁移操作 |
| 1.0.1 | 2026-03-10 | 安全修复:移除提权/bash 引用、明确要求用户确认删除操作 |
| 1.0.0 | 2026-03-07 | 初始版本,基于 admin-api 模块实战经验 |
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.