> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs-beta.getzep.com/v3/agent-skills/quickstart/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-beta.getzep.com/_mcp/server. # Agent Skills quickstart > Create an Agent, capture a Trajectory, close the Trajectory with verification, search for the compiled Skill, and record the Skill use. This guide shows the main Agent Skills workflow. Your agent records a task run, and Zep compiles a Skill from the verified run. The agent then retrieves the Skill on the next run of the same task. For the concepts, read the [Agent Skills overview](/agent-skills). In production, your agent runtime sends these calls for each task run. You do not write the Skills. ## Prerequisites * A Zep project API key in the `ZEP_API_KEY` environment variable. * Access to Agent Skills for your account. Without access, the API returns `403 permission_denied`. * The v4 preview SDK. The Agent Skills methods are not in the 3.x SDKs. **`Python`** ```bash Python pip install --upgrade "zep-cloud>=4.0.0a6" ``` **`TypeScript`** ```bash TypeScript npm install @getzep/zep-cloud@preview ``` ## Create an Agent An Agent owns its Trajectories and Skills. The `agent_id` is your identifier and is unique in the project. The `security_domain` is immutable. Skills can move only between Agents with the same security domain. This example sets `compilation_mode` to `on_close`, so that Zep compiles after one closed Trajectory. The default [compilation mode](/agent-skills/learning-and-admission) is `scheduled`. **`Python`** ```python Python import os from zep_cloud import AgentMemorySettings, AgentTrajectoryCloseVerifier, Zep client = Zep(api_key=os.environ["ZEP_API_KEY"]) agent = client.agent.create( agent_id="billing-support", name="Billing support agent", security_domain="support", version="1.0.0", memory_settings=AgentMemorySettings(compilation_mode="on_close"), ) agent_uuid = agent.uuid_ ``` **`TypeScript`** ```typescript TypeScript import { Zep, ZepClient } from "@getzep/zep-cloud"; const client = new ZepClient({ apiKey: process.env.ZEP_API_KEY }); const agent = await client.agent.create({ agentId: "billing-support", name: "Billing support agent", securityDomain: "support", version: "1.0.0", memorySettings: { compilationMode: "on_close" }, }); const agentUuid = agent.uuid!; ``` ## Record a Trajectory A Trajectory is one task attempt. Give the Trajectory an `objective` for this task instance and a `task_family` for the kind of task. **`Python`** ```python Python trajectory = client.agent.trajectory.create( agent_uuid=agent_uuid, objective="Resolve a duplicate charge question for invoice 1042", task_family="billing.support", ) trajectory_uuid = trajectory.uuid_ ``` **`TypeScript`** ```typescript TypeScript const trajectory = await client.agent.trajectory.create(agentUuid, { objective: "Resolve a duplicate charge question for invoice 1042", taskFamily: "billing.support", }); const trajectoryUuid = trajectory.uuid!; ``` Append one event for each step that the agent takes. Zep assigns the next sequence number when you do not set `sequence`. **`Python`** ```python Python events = [ ("input_reference", "The customer reports two charges for invoice 1042."), ("tool_call", "billing.get_payments(invoice_id=1042)"), ("tool_result", "One payment succeeded. One authorization was voided."), ("decision", "The second charge is a voided authorization. Do not refund."), ("artifact", "Reply: the second charge is a pending authorization that will expire."), ] for event_type, content in events: client.agent.trajectory.append_event( agent_uuid=agent_uuid, trajectory_uuid=trajectory_uuid, event_type=event_type, content=content, ) ``` **`TypeScript`** ```typescript TypeScript const events: Array<[Zep.AgentTrajectoryEventType, string]> = [ ["input_reference", "The customer reports two charges for invoice 1042."], ["tool_call", "billing.get_payments(invoice_id=1042)"], ["tool_result", "One payment succeeded. One authorization was voided."], ["decision", "The second charge is a voided authorization. Do not refund."], ["artifact", "Reply: the second charge is a pending authorization that will expire."], ]; for (const [eventType, content] of events) { await client.agent.trajectory.appendEvent(agentUuid, trajectoryUuid, { eventType, content, }); } ``` ## Close the Trajectory with verification Zep compiles Skills only from successful Trajectories with strong verification. The `tool`, `customer`, and `external` verification values are strong, and each one needs a verifier. The verifier identifies the check that confirmed the outcome. The first time that an Agent receives a `verifier_id`, the verifier must also have a `class`. Zep then registers the verifier for the Agent. **`Python`** ```python Python client.agent.trajectory.close( agent_uuid=agent_uuid, trajectory_uuid=trajectory_uuid, outcome="succeeded", verification="tool", verifier=AgentTrajectoryCloseVerifier( verifier_id="billing-ledger-check", class_="ledger_reconciliation", outcome="succeeded", assertion_id="ledger-1042", ), ) ``` **`TypeScript`** ```typescript TypeScript await client.agent.trajectory.close(agentUuid, trajectoryUuid, { outcome: "succeeded", verification: "tool", verifier: { verifierId: "billing-ledger-check", class: "ledger_reconciliation", outcome: "succeeded", assertionId: "ledger-1042", }, }); ``` The close request returns `202 Accepted`. Zep summarizes the Trajectory and starts compilation in the background. ## Check the learning state The learning state tells you what Zep needs before a Skill is available for the task family. **`Python`** ```python Python state = client.agent.learning.get(agent_uuid=agent_uuid, task_family="billing.support") print(state.compilation_pending, state.next_step) ``` **`TypeScript`** ```typescript TypeScript const state = await client.agent.learning.get(agentUuid, { taskFamily: "billing.support" }); console.log(state.compilationPending, state.nextStep); ``` When `compilation_pending` is `true`, Zep has not finished the learning run. Wait, and then check again. The `next_step` field tells you what Zep needs before it can compile a Skill, for example more verified runs. The value `Learning is ready.` does not show that Zep admitted a Skill. To find the admitted Skills, search for Skills. If you set `compilation_mode` to `manual`, Zep does not start a learning run automatically, even when `next_step` is `Learning is ready.`. ## Search for Skills Search before the next task in the same task family. The response contains a signed `search_id` and the matching Skills. Each result contains the Skill text in `markdown`. **`Python`** ```python Python results = client.agent.skill.search( agent_uuid=agent_uuid, query="customer reports a duplicate charge", task_family="billing.support", limit=3, ) search_id = results.response.search_id for skill in results.items: print(skill.name, skill.maturity) print(skill.markdown) ``` **`TypeScript`** ```typescript TypeScript const results = await client.agent.skill.search(agentUuid, { query: "customer reports a duplicate charge", taskFamily: "billing.support", limit: 3, cursor: null, }); const searchId = results.response.searchId!; for (const skill of results.data) { console.log(skill.name, skill.maturity); console.log(skill.markdown); } ``` Put the `markdown` of the applicable Skill in the agent prompt for the new task. ## Record the Skill use Create a new Trajectory for the new task. When the agent uses a Skill, record the use with the `search_id` and the new Trajectory. **`Python`** ```python Python next_trajectory = client.agent.trajectory.create( agent_uuid=agent_uuid, objective="Resolve a duplicate charge question for invoice 2077", task_family="billing.support", ) skill = results.items[0] use = client.agent.skill.use.create( agent_uuid=agent_uuid, skill_uuid=skill.uuid_, search_id=search_id, trajectory_uuid=next_trajectory.uuid_, usage="used", ) ``` **`TypeScript`** ```typescript TypeScript const nextTrajectory = await client.agent.trajectory.create(agentUuid, { objective: "Resolve a duplicate charge question for invoice 2077", taskFamily: "billing.support", }); const skill = results.data[0]; const use = await client.agent.skill.use.create( agentUuid, skill.uuid!, { searchId, trajectoryUuid: nextTrajectory.uuid!, usage: "used" }, ); ``` Capture and close the new Trajectory as before. Then add the outcome of the Skill use. Zep takes the verification strength from the Trajectory of the Skill use. **`Python`** ```python Python client.agent.skill.use.add_outcome( agent_uuid=agent_uuid, skill_uuid=skill.uuid_, use_uuid=use.uuid_, outcome="succeeded", ) ``` **`TypeScript`** ```typescript TypeScript await client.agent.skill.use.addOutcome( agentUuid, skill.uuid!, use.uuid!, { outcome: "succeeded" }, ); ``` ## Next steps * [Capture Trajectories](/agent-skills/capture-trajectories) describes event types, retries, and gaps. * [Configure learning and admission](/agent-skills/learning-and-admission) describes member review and the admission gates. * [Retrieve Skills and record use](/agent-skills/retrieve-skills) describes filters, the Agent context endpoint, and the Context MCP Server. > Record a verified task attempt, then retrieve the Skill that Zep compiles from it