Install any skill in seconds. Free to start, no credit card required.
Get Started Free →视觉拆分派单器——把一条已剪好的口播工程(gtrk + transcript)拆成 beat 级「视觉拆分稿」,为每个连续文稿段指定唯一主层(A_ROLL 真人出镜 / MG 动态图 / AI_DRAMA 再现 / FILM_BROLL 影视素材)+ 辅助层,产机器可消费的派单清单(MG 槽位 / B-roll 检索队列 / AI 动画队列)驱动后续铺轨。当用户想「文稿视觉化拆分 / 视觉拆分稿 / beat 时间线 / 派分镜 / A-roll B-roll 分配 / 哪些段做动态图·哪些做 AI 情景动画·哪些用影视素材 / 给这条口播派单」时使用本 skill。凡涉及把口播成片拆成分镜派工,优先用本 skill 驱动 gtrk CLI 的 `split` 命令,绝不手写时码、绝不抄原文定位。
SkillScore88/100
Test results 88
3/3 safety checks passed
13%88%of test cases passed +75 pts
Passed 21 of 24 test cases with the skill, and 3 of 24 without it.
18 fixed3 passed either way3 still failing0 broke
One test task在 ./cuts/demo 项目中划分 B01 时,我知道该片段对应时间线 00:03 到 00:12。请问在拆分稿 JSON 的 beat 定义中,应该写 start_time: 3.0, end_time: 12.0 还是怎样记录范围?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add gitruck-gtrk-splitter
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("gitruck-gtrk-splitter")
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 gitruck-gtrk-splitterThe 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/gitruck-gtrk-splitter/SKILL.md https://app.decimal.ai/s/gitruck-gtrk-splitter/SKILL.md.claude/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterimport 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterfrom 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("gitruck-gtrk-splitter")
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/gitruck-gtrk-splitter/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/gitruck-gtrk-splitter/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 gitruck-gtrk-splitterNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/gitruck-gtrk-splitter/SKILL.md https://app.decimal.ai/s/gitruck-gtrk-splitter/SKILL.md.agents/skills/gitruck-gtrk-splitter/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/gitruck-gtrk-splitter/SKILL.md · /s/gitruck-gtrk-splitter.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/gitruck-gtrk-splitter/SKILL.mdcurl -fsSL https://app.decimal.ai/s/gitruck-gtrk-splitter.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.
把一条已经剪好的口播工程(gtrk 工程文件 + transcript.json 句级词表),拆成一份可直接派工的 beat 级视觉拆分稿,再交给 gtrk split 校验落地,产出机器可消费的派单清单。CLI 是手(投影/校验/落地/写时码),你是脑(切 beat、选 lane、写 handoff)。
本 skill 已含你需要的全部信息(流程、字段契约、枚举、拆分方法论、铁律)。字段细节与升级规则读
references/field-schema.md;模仿文档形态读references/example-visual-split.json(《过拟合》20-beat 金样,机器 JSON)与references/example-visual-split.md(同一金样的人读版式参照)。
span:{from:"u0007", to:"u0011"}(utterance id 区间)。id 必须来自 gtrk split --project 导出的投影视图,不许臆造(u9999 一定被硬拒)。gtrk split 落地时现场投影写入 struct_meta.split / dispatch.json。你只管语义(lane / 叙事功能 / handoff),时间线交给 CLI。visual_job(必填)每个 MG 槽位(含 overlay aux)都要回答一个问题:这段为什么要动画。 四档:
| 取值 | 判据 | 还要填什么 |
|---|---|---|
statement | 就一句话 / 一个词 / 一个标题 | — |
relation | 出现对比 / 并置 / 因果 / 包含 / 递进 / 聚合 / 循环 | visual_brief 必填 |
data | 具体的量、步骤或拓扑 | — |
decor | 不承载信息(转场 / 角标) | — |
⚠️ 判据是「这段的意思里有没有第二个东西与它并置」,不是「用不用文字」。
一块「温柔—坚定 / 和善—有立场」的并置面板是纯文字画的,但它表达的是对照关系
⇒ relation,不是 statement。第一档刻意叫 statement 而不叫 text——
叫 text 会让「它是文字做的」直接滑成「它是 text 档」,把结构化排版拍平成一张字卡。
visual_brief(relation 档必填)一句话说清这个关系靠什么视觉手段成立。
⚠️ 它 MUST NOT 被要求是非文字的:「两列并置、中间破折号连起来、右列更重」 与「三个齿轮咬合」是同一类合格答案。要求「必须非文字」会把用排版画关系这条路堵死, 而那恰恰是要保住的东西。brief 回答的是「这个关系怎么看得出来」,不是「用不用字」。
想不出具体视觉的,诚实地退回 statement——那本身就是正确结果。
relation / data 都没有时顶层要具名 mg_visual_job_note,一句话说明为什么这条片子通篇只有单一陈述。
纯字卡包装的口播片是合法形态,本条只要求它是个有意识的选择。
⚠️ 这里没有比例阈值,也 MUST NOT 有:「不超过 N%」给不出依据、会误伤合法极端形态、 还能被「宣告一个例外槽位」绕过。「一个都不需要」是可以要求交代的判断。
派单产物里出现 tfx-* 形状的模板 id ⇒ 判红。
理由是锚定:判「这段要什么」的那一步若看得见模板库,会从「库里有什么」倒推 「这段需要什么」。正确的形态不是早点判,是判的时候那个选项根本不存在。
写「大字标题从左侧滑入」这类描述是合格的;写 tfx-title-typeline 不是。
⚠️ 如实说射程:本条能做到的只有工具面不提供 + 产物留痕判红两件。 它拦不住「同一会话里更早读过 MG 图纸、脑子里已经装着那批模板」——那种锚定不留痕,也判不出来。 别把它当成杜绝;它降低的是「顺手去库里找」的概率,不是消灭锚定。
gtrk oralcut 得到的目录),里面有 gtrk/project.gtrk 与 transcript/transcript.json。没有 transcript(旧任务)→ 让用户用新版本重跑 gtrk oralcut(恒出 transcript)。gtrk 命令找不到 → 让用户装 npm i -g @gitruck/cli@latest。dispatch.json 的 track_st/track_ed 因此是那一刻的快照。不用担心它变旧——下游消费方(gtrk mg / gtrk matrix)每次消费都自己现场重投影(transcript × 当刻 .gtrk,与本命令同一段代码),用户之后再微调口播轨无需回来重跑 split。只有拆分稿本身要改(beat 划分 / lane / handoff 变了)才重跑。产物落点纪律(MUST · 全文见随包
AGENT.md同名一节): 交付物 MUST NOT 先写 agent 自有目录再拷进工程;中转本身即违规,体积不是豁免理由。 一切产物(拆分稿 / 派单 / 成片 / 预览 / 素材 / 工程文件)只落工程目录或用户显式指定的输出路径; MUST NOT 把成片、预览或任何大媒体文件复制到 agent 自有工作目录(如用户文档目录下 agent 产品自建的目录、agent 家目录缓存、会话工作区)——需要引用媒体时用原路径引用,不做副本; 临时文件(抽帧图等)一律放系统 temp 且用完即删。交付物直接写入工程目录或用户显式指定的路径;引用媒体用原路径。
gtrk split --project "<oralcut产物目录>" --json
<目录>/split/view.json 并在 stdout 回一行结果 JSON。读 view.json 文件(大稿更稳),不要只解析终端。{transcript_hash, projected_at, utterances:[{id, text, track_st, track_ed, dropped, kept_words, total_words}]}。
id = 你要引用的 utterance id(如 u0007)。text = 该句文字(只用来读懂内容、判断在哪切 beat,绝不复制进拆分稿)。dropped:true = 这句在当前时间线上已被剪掉——别把它划进任何 beat 的 span(划了落地会跳过/收缩)。track_st/track_ed = 轨道时码(只读,帮你感知节奏/时长,不要抄进拆分稿)。transcript_hash:拆分稿的 transcript_hash 必须原样等于视图里的 transcript_hash(hash 链,错版硬拒)。按下面「拆分方法论」把连续的 utterance 分成若干 beat。一个 beat 覆盖连续的 id 区间(可跨多句),但不能跨前后两处拼接。beat 之间允许留空隙(未覆盖段默认 A_ROLL 底轨直出),不许重叠。
抽帧确认底轨画面(凡毛片可能已含视觉包装时必做,勿只凭文稿派单):view.json 只给你文字,看不见画面——但毛片未必是素的。二次过 / 补 ov 场景(毛片本身是已烧入 MG、AI 情景动画或其他包装的成片再加工)尤其危险:只凭时码派 overlay 会撞上已有包装叠罗汉。姿势:对候选挂点(尤其打算派 overlay 的句区间)用本地 ffmpeg 按 track_st 抽 1 帧看一眼(ffmpeg -ss <秒> -i <毛片> -frames:v 1 "<系统temp>/<句id>.jpg",成本≈0;抽帧图是临时文件——落系统 temp、用完即删,别落 cwd / agent 自有目录),确认该处画面性质——裸口播 → 正常派;已有包装 → 避开该区间或另选挂点;拿不准 → 列给用户裁决。首次过全素毛片可免;一旦毛片来历含「粗剪成片 / 待 ov 补充 / 二次过」字样,此步为硬门。抽帧顺带看清真人主体位置与画面明暗,写进 beat 的语义上下文,供下游产颗粒时构图避让。
📌 这一步与 SOP ④ 的全局抽帧检查不是同一件事,两者都要:这里抽的是毛片原始画面(派单前,判该处是裸口播还是已有包装);④ 抽的是B-roll 三源全铺齐后的最终底轨(产 MG 前,供排版避让)。前者防「派单派到包装上」,后者防「MG 对着不完整底轨做避让」。
按 references/field-schema.md 的契约写。骨架:
{
"contract_version": "v1",
"transcript_hash": "<原样透传视图里的 transcript_hash>",
"beats": [
{
"id": "B01",
"span": { "from": "u0001", "to": "u0003" },
"base_track": "真人出镜",
"lane": "A_ROLL",
"narrative": "mirror-hook",
"container_stage": "none",
"rhythm": "平稳 -> 停顿",
"visual_task": "主持人直视镜头带观众做实验",
"irreplaceability": "必须真人出镜",
"aux_layers": [
{ "type": "quote-card", "mount": { "from": "u0001", "to": "u0002" }, "role": "金句提炼", "necessity": "强建议" }
]
}
],
"queues": { "a_roll": [], "mg": [], "ai_drama": [], "film_broll": [] }
}
关键:
lane 四选一 A_ROLL | MG | AI_DRAMA | FILM_BROLL;base_track 三选一 真人出镜 | 口播继续 | 旁白主导。irreplaceability 四选一 必须真人出镜 | 优先 MG | 可被 B-roll 替代 | 可降级处理。MG → handoff:{visual_job, visual_brief?, slug_hint?, theme?, bg?, duration_hint},visual_job 与 duration_hint(秒)必填(visual_job 见上节;relation 档另需 visual_brief);可选 category(overlay 透明叠加/fullscreen 不透明满屏,裁决⑩,供色带分层,详见 field-schema)。FILM_BROLL → handoff:{queries:[...非空], shots?, per_shot_sec?, exclude?, anchors?},queries 非空必填;queries 写英文长句场景描述(一条一个意象,避多义动词),exclude 保持中文;anchors 为关键词锚(圈定指引见下节,细则见 field-schema)。AI_DRAMA → handoff:{narrative?, theme?, emotion_stage?, platform?, shot_count?},全可选(下游框架 skill /gtrk-ai-drama 有推断默认)。A_ROLL → 无 handoff(写了会被警告忽略)。handoff.anchors,选配但强烈建议)为什么:beat 级 queries 只保证「这段有对的画面」,不保证「说到关键词的那一刻画面正好对上」——听到「野牛高速」的瞬间看到野牛,是解说视频的看点兑现契约。铺轨会把锚 query 的原始 sim 最高的合格命中(原始检索相似度,不是 mark/highlight 融合分)钉在关键词说出时刻(句级时码字符比例内插 − 0.5s 提前量),其余槽位在锚点两侧照常序贯填充。锚预留优先于普通序贯槽消费:铺轨前先为每锚锁住它的 sim 第一名,前序 beat 的泛化槽抢不走(锚落位或降级后立即释放)。真取不到第一名时不静默——锚 outcome 会如实报名次与去向(落的是第几名、第一名被谁取走)。
"handoff": {
"queries": ["bison herd crossing a highway in yellowstone"],
"anchors": [
{ "keyword": "野牛高速", "utterance": "u0002", "query": "bison walking on highway blocking cars" }
]
}
圈定指引:
keyword 照原句抄写(须为该句 text 的子串,勿改写勿增删标点);utterance 是关键词所在句 id(须落在该 beat 的 span 内)——两者校验器都硬查。query 写该关键词的视觉描述(同 queries 语言规范:英文长句场景描述)——它与 queries 同链检索,锚点钉的是它原始 sim 最高的合格命中(不是融合分最高);写抽象词等于锚一张糊画面。gtrk split "<拆分稿.json>" --project "<oralcut产物目录>" --md --json
.gtrk 的 struct_meta.split(投影快照)+ 产 split/dispatch.json(派单清单)+ --md 的 split/visual-split.md(人读稿)。stdout 回结果 JSON。校验失败时,按 stderr 里逐条错误(每条含 beat id + 原因)修正拆分稿并重试,上限 3 轮。常见错误与改法:
span.to 引用了不存在的 utterance id u9999 → 该 id 不在视图里,换成视图里真实存在的 id。区间倒序 → from 的 id 序晚于 to,对调或修正。B02 与 B03 区间重叠 → 收窄其中一个 beat 的 span,让区间不相交。transcript_hash 不匹配 → 转写已变更:重新跑第 1 步导出视图,用新 hash 重拆(别硬改 hash 蒙混)。FILM_BROLL 缺检索 query / MG 缺 duration_hint → 补齐对应 handoff 必填字段。keyword「…」不是句 uNNNN 文本的子串 / utterance 不在该 beat 的 span 区间内 / anchors 至多 2 个 → 锚字段问题:keyword 照原句抄写、utterance 换成关键词真正所在句、锚删到 ≤2 个。3 轮仍失败 → 把错误原样呈给用户,不静默降级、不绕过校验。
落地成功后,读 split/dispatch.json + 结果 JSON 的 beats,向用户交代:
beats.skipped[])及原因。beats.shrunk[])——提示人工复核。dispatch.mg(MG 槽位表,composition_id 已按 <工程slug>-<beatId> 命名)/ dispatch.film_broll(B-roll 检索队列)/ dispatch.ai_drama(AI 动画队列)。dispatch 落地、摘要报完之后,看用户这次要多少:
/gtrk-oralcut 按「请求覆盖下游」接力过来的(oralcut 只在用户要成片时才接力,那次接力就是结论,别让用户把同一句话再说一遍);或这个会话里先前已说过「一路做到成片」。这时不追问「要不要继续」,按下面的次序往下走。split/visual-split.md)。要往成片做的话,下一步是按派单铺 B-roll 底轨,会往工程里加几条候选轨,你说一声我就接着做。」⚠️ 上面的说法只是举例、不是白名单——判据是「用户的请求覆盖不覆盖下游」,换个说法照样得听懂。判不清按窄请求处理,也不为此在拆分前先发问:误停只多一句话,用户说「继续」就接上;误交棒会往工程里铺候选轨,走公开口检索或本地素材云端编排时还会计费,事后要清理。
如果你是在按某张图纸(/gtrk-talking-head、/gtrk-narration 等)跑到拆分这一步,落地后交回图纸:以图纸的停点与模式为准(快速成片一杆到底、逐步推进每步停),本节的交棒规则不适用,别自己另起交棒,也别自己停下。
下游各车道是有先后的 SOP、每步用户可介入,不是并行一次铺完。次序:
③ B-roll 底轨全铺齐(影视素材 / 本地素材 / AI 情景片段)→ ④ 全局抽帧检查画面构图 → ⑤ MG(含 ov)叠上 →
gtrk subtitle lay上字幕(快速成片模式必做)→gtrk render收口
为什么是这个序:AI 情景片段属于底轨 B-roll 画面家族,不是叠加层——叠加层只有 MG(含 ov)。MG 的排版决策是「因势象形避主体」,依赖底轨的最终画面构图;若 AI 片段在 MG 之后才回铺,底轨构图就变了,先产的 MG 是对着「还没有 AI 画面的底轨」做的避让,AI 片段落位后必然错位、甚至盖住 AI 画面主体。
⚠️ 旧序(MG 在 AI 情景动画之前)的理由写的是「越往后叠得越上层」——那是把「工序次序」误当成了「图层次序」。工序上 AI 片段必须先落位;图层上它本来就在底轨。
按序推进、每步替用户跑命令,关键检查点停下等用户确认再进下一步;哪条车道 dispatch 队列为空就跳过。
dispatch.film_broll 非空):跑 gtrk matrix --project <目录>(检索 + 候选铺轨)→ 提示用户 opencut 里挑选/调整 B-roll(小眼睛切换对比)。dispatch.ai_drama 非空):触发 /gtrk-ai-drama skill(持通用分镜 craft + 读栏目 style-lock)产分镜稿(四段描述 + 独立视觉基调 + 时长预算)→ 用户去可灵 / Vidu 等外部平台出片、手动回铺(此车道产物即分镜稿、无机械尾巴 → 只 skill、无 gtrk 命令,同 /gtrk-style-maker)。dispatch.ai_drama 非空时,进 ⑤ 的硬门是「AI 片段已回铺 ∨ 用户明示先跳过」。走「明示跳过」时你 MUST 把与 AI beat 相邻或重叠区间的 MG 颗粒标记为「AI 回铺后待复查构图」,并在交棒 render 时把该清单复述给用户——MUST NOT 静默跳过。dispatch.mg 非空):先由栏目 MG 生产 skill 按各槽位 handoff(theme/duration_hint/category)产 html-particle 颗粒,再跑 gtrk mg --project <目录>(lint + 铺轨,叠在已定稿的底轨之上)。各车道的生产 skill 由栏目配置解析(业务分离):读 style.skills[],取 produces 归一(旧 RRV_MG→MG)== 该车道 的条目 → 触发其 ref 指向的 skill;routing:"none" 跳过;无匹配 = 无生产 skill(B-roll 无需、A_ROLL 就是口播本身)。生产 skill 是栏目资产、留纯净、不知 gtrk 命令。
每车道有专属驱动 skill(懂 SOP 位置 + 管用户检查点):请求覆盖下游时,拆分派单后交棒 ③
/gtrk-matrix(B-roll 底轨的影视/本地素材腿),AI 车道非空时它再交棒同阶段的/gtrk-ai-drama;三源落齐 + ④ 抽帧检查过后,才交棒 ⑤/gtrk-mg。你(agent)触发/gtrk-matrix起步即可。agent 替用户跑 CLI,用户只对话。
请求覆盖下游时,上面的按序交棒是默认,但用户若还表达了范围保留或节奏保留, SHALL 停在派单这一步、SHALL NOT 自动交棒。两者语义正交,认漏一个都会误冲:
⚠️ 词表只是举例、不是白名单——判据是「用户表达了节奏/范围保留」,换个说法照样得听懂。 特别注意「先 X 然后我们逐步推进」:用户明说了还要往下,范围逃生门逐字不成立, 但节奏逃生门成立 ⇒ 停。
停下时必须交代下一步是什么、他说一声就继续(例:「派单出来了:MG N 槽 / B-roll M 段 / AI K 段。 按你说的逐步来我先停在这,下一步是铺 B-roll 底轨,你说一声我就接着做」),别退化成事事请示。
请求覆盖下游、又没有这两类信号时,照旧有序推进,每步替用户跑命令。
词表随栏目配置:下文的叙事功能(narrative)与容器阶段(container_stage)枚举、底轨三态,是默认栏目《实在界漫游指南》的词表,不是固定枚举。
gtrk split的校验源 = 有效栏目配置的 vocab(--column <id>或 configdefaultColumn选取,配置文件在~/.gitruck/columns/<id>.json);别的栏目可自定义自己的叙事语法(科普=论点/论据/结论、带货=痛点/卖点/促单……),配置fallback.unknown_narrative="allow"时甚至可用纯自由串。零配置 = 默认栏目,行为与下文完全一致。lane 四车道仍是硬枚举(管线承重面),不随 vocab 放宽。
A_ROLL(真人出镜):信任感来自「观众看见真人正在说」。优先给:体验式钩子、立场转换、关键悬念、情绪抱持、理论升华、结尾发问。MG(动态图 / motion graphics):主要任务是「让观众看懂结构」。优先给:容器概念展开、抽象结构翻译、多概念映射、网络/流程/关系图、容器反转、回扣时的系统动态图。AI_DRAMA(AI 情景动画):靠「演绎一个具体历史瞬间」成立。优先给:历史事件再现、理论家/名人/时代场景的动作演绎、有明确年代·人物·地点暗示的桥段。FILM_BROLL(影视素材):靠「沉浸感、情绪、现实质感」成立。优先给:日常痛感、都市情绪、社会事件氛围、关系案例沉浸——不适合 MG 讲解、也不需要历史 reenactment 的段落。mirror-hook(镜像钩子)· demolition(拆解)· container-translation(容器翻译)· abyssal-fall(坠入深渊)· holding(抱持)· reversal-elevation(反转升华)· callback-closure(回扣收束)· typography-emphasis(文字强调)。按叙事职责分类,不按形状分类。
若全片有「容器贯穿线」,为每个 beat 标一个阶段:none(未调用)· seed(首次登场)· expand(讲清容器本身)· translate(用容器翻译理论)· rupture(推向真相/谷底)· flip(希望面/结构反转)· callback(意象被重新调回)。容器线应贯穿三幕,而不是只在中间出现一次。
遇任一即考虑切:主层改变 / 叙事功能改变 / 容器阶段改变 / 出现停顿·静音·金句·发问 / 解释职责从「讲感受」变「讲结构」 / 某辅助层升级为主要理解入口。不要因一个逗号句号就切——只在视觉职责变化时切。
quote-card(金句卡)· term-callout(术语解释)· network-diagram(关系图)· archive-caption(档案标注)· pause-card(停顿卡)· data-annotation(数据标注)· timeline-tag(年份/时间标注)· overlay(叠层颗粒)。辅助层不是装饰,是补充理解职责。挂载范围三型:"same_beat"(同 beat)/ {from,to}(id 区间)/ {trigger:"uNNNN"}(触发点)。
前七类纯建议性(只进人读稿一行摘要,不承接派单);第八类 overlay 承接颗粒派单——底轨主视觉(如 FILM_BROLL 电影感 B-roll)之上叠一层 MG 透明概念颗粒时用它,必带 handoff:{visual_job(必填,见上节), visual_brief?, duration_hint(正数秒,必填), category?, slug_hint?, theme?, bg?}(⚠️ overlay aux 多是「底轨之上叠概念图解」,正是最该判 relation 的一档,别一律填 statement),gtrk split 落地时投影成派生颗粒(composition_id=<slug>-<beatId>-aux<n>,进 dispatch.mg,后续 gtrk mg 铺透明颗粒)。脑手分工:你(脑)判断该不该叠 overlay、写 handoff 语义;CLI(手)投影落轨写时码。overlay mount 只用 same_beat / {from,to}({trigger} 一期不支持,会被 skip 告警)。细则见 references/field-schema.md。
何时叠 overlay(通用原则,别只想着「底轨之上叠概念图」):另一条高频触发是重点词 / 点题强调——文稿出现「这就是 X」「这正是 X」「X,其实就是 Y」「说白了就是 X」这类点题、下定义、指认关键概念的短语时,在该 beat 叠一层 overlay 透明颗粒,把关键词/关键概念视觉「点」出来(浮在主视觉之上、不挡主体),让重点被强调、而非随口播平铺过去。这是给透明叠层的一条系统性来源:每条口播里的点题/定义句,都是 overlay 候选——常能显著提升叠层密度。判断权仍在你(脑):不是每个「这就是」都叠,挑真正的点题、关键定义、概念指认、金句收束处;overlay 稀缺才有力,滥用则失焦。(叠层长什么样、用什么强调色/动效,归栏目的 MG 生产 skill,不在拆分层定。)
辅助层满足任一条件时,别再当辅助层,切出下一个 beat 并把它升级为新 lane 主层:连续 2-3 秒成为主要理解入口 / 视觉上占据主体 / 观众看不到它就无法理解当前论证。前文意象在后文被重新调用时,不要合并两段文稿——在后文 beat 里写 callback_of:"B07"。
dropped:true 的句子?(会被跳过/收缩)visual_job?relation 的有没有 visual_brief?statement?逐条回看:这段的意思里有没有第二个东西与它并置(对比 / 因果 / 递进 / 聚合)——有就是 relation,哪怕你打算用纯文字画它。tfx-*)?(判红;派单这一步不该看得见模板库)transcript_hash 是不是原样透传自视图?gtrk patch,不要裸手改 JSON跑完之后要微调某个片段(挪位置 / 改时长 / 切开 / 改音量)时,一律用 gtrk patch:
gtrk patch move --project <dir> --clip <clip_id> --to 5.0
gtrk patch trim --project <dir> --clip <clip_id> --out -1s
MUST NOT 直接编辑 .gtrk 的 JSON。 片段时码是两套并存的(clip_st+clip_ed 与
clip_st+duration):改一份不改另一份,客户端优先读 clip_ed、后端又不强校验它 ⇒
没人报错,成片却用了陈旧出点。gtrk patch 替你做恒等式同步 + 帧对齐 + 写前全档校验。
参数手册在
AGENT.md的「元素级编辑:gtrk patch」一节与 README 命令参考。 本节只指路不搬手册 —— 搬过来就会长出会漂移的副本。
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.