SDK로 컨텍스트 관리하기
SDK로 컨텍스트 관리하기
LangSmith SDK를 사용해 Context Hub의 에이전트 및 스킬 저장소(repo)를 프로그래매틱하게 푸시, 풀, 나열, 삭제하는 방법을 알려드릴게요.
LangSmith Python 및 TypeScript SDK를 사용해 Context Hub의 에이전트 저장소와 스킬 저장소를 프로그래매틱하게 관리합니다. CI에서 새 버전을 푸시하고, 실행 시 최신 또는 고정된 커밋을 풀해 에이전트에 컨텍스트를 주입하며, 존재 확인, 저장소 나열·검색, 더 이상 필요 없는 것 삭제에 추가 메서드를 사용합니다.
참고: Context Hub 메서드는
langsmith>=0.7.35(Python)와langsmith>=0.5.23(TypeScript)이 필요합니다.
출처: 문서
본문
설정
-
패키지 설치:
pip install -U langsmithuv add langsmithyarn add langsmith -
환경 변수 구성. 환경에
LANGSMITH_API_KEY가 이미 설정되어 있다면 이 단계를 건너뜁니다. 그렇지 않으면 LangSmith에서 Settings > API Keys > Create API Key로 하나 만든 뒤 환경 변수로 설정합니다:export LANGSMITH_API_KEY="lsv2_..."
참고: Python async: 이 페이지에 표시된 모든 메서드는
AsyncClient(langsmith에서 import)에서도 동일한 시그니처로 사용할 수 있습니다 — 각 호출을await하면 됩니다. TypeScript SDK는 기본적으로 async입니다. 별도 async 클라이언트는 없습니다.
에이전트 푸시
새 에이전트 저장소를 만들거나 기존 저장소의 새 버전을 커밋합니다. 저장소가 아직 없으면 제공한 메타데이터(description, readme, tags, is_public)로 생성됩니다. 이미 존재하면 해당 필드는 명시적으로 전달될 때만 패치됩니다.
메서드는 LangSmith UI의 새 커밋을 가리키는 URL을 반환합니다:
from langsmith import Client
from langsmith.schemas import FileEntry
client = Client()
url = client.push_agent(
"email-assistant",
files={
"AGENTS.md": FileEntry(
content="You are an email triage assistant.",
),
"tools.json": FileEntry(content='{"tools": []}'),
},
description="Triages and drafts replies to incoming email.",
tags=["email", "productivity"],
is_public=False,
)
print(url)
import { Client } from "langsmith";
const client = new Client();
const url = await client.pushAgent("email-assistant", {
files: {
"AGENTS.md": {
type: "file",
content: "You are an email triage assistant.",
},
"tools.json": { type: "file", content: '{"tools": []}' },
},
description: "Triages and drafts replies to incoming email.",
tags: ["email", "productivity"],
isPublic: false,
});
console.log(url);
스킬 푸시
push_agent와 동일한 표면이지만 스킬 저장소에 커밋합니다. 다른 에이전트가 의존할 수 있는 재사용 가능한 기능에 사용하세요:
from langsmith import Client
from langsmith.schemas import FileEntry
client = Client()
url = client.push_skill(
"deep-research",
files={
"SKILL.md": FileEntry(content="Conduct deep multi-step research."),
},
description="Multi-step web research with citations.",
tags=["research"],
)
print(url)
import { Client } from "langsmith";
const client = new Client();
const url = await client.pushSkill("deep-research", {
files: {
"SKILL.md": {
type: "file",
content: "Conduct deep multi-step research.",
},
},
description: "Multi-step web research with citations.",
tags: ["research"],
});
console.log(url);
다른 저장소에 연결
파일 내용을 인라인하는 대신 files의 항목은 다른 에이전트 또는 스킬 저장소에 대한 링크가 될 수 있습니다. 이를 통해 저장소 간에 내용을 복제하지 않고 컨텍스트를 구성할 수 있습니다. 예를 들어 공유 스킬에 위임하는 에이전트.
commit_id를 생략하면 LangSmith는 이 커밋을 푸시할 때 해당 저장소의 최신 커밋에 연결합니다. 연결된 저장소가 나중에 업데이트되면 LangSmith는 그 업데이트를 참조하는 부모 저장소에 전파합니다.
from langsmith import Client
from langsmith.schemas import AgentEntry, FileEntry, SkillEntry
client = Client()
url = client.push_agent(
"email-assistant",
files={
"AGENTS.md": FileEntry(content="You are an email triage assistant."),
# Link to the deep-research skill repo. Omit commit_id to always
# resolve to the latest version, or pin it for reproducibility.
"skills/research": SkillEntry(repo_handle="deep-research"),
# Link to another agent repo.
"agents/scheduler": AgentEntry(repo_handle="calendar-agent"),
},
)
print(url)
import { Client } from "langsmith";
const client = new Client();
const url = await client.pushAgent("email-assistant", {
files: {
"AGENTS.md": { type: "file", content: "You are an email triage assistant." },
// Link to the deep-research skill repo. Omit commit_id to always
// resolve to the latest version, or pin it for reproducibility.
"skills/research": { type: "skill", repo_handle: "deep-research" },
// Link to another agent repo.
"agents/scheduler": { type: "agent", repo_handle: "calendar-agent" },
},
});
console.log(url);
푸시 파라미터
push_agent / pushAgent와 push_skill / pushSkill 모두 다음 파라미터를 수락합니다:
| Parameter | Type | Description |
|---|---|---|
identifier |
string |
The repo's identifier. |
files |
dict[str, Entry | None] |
Map of file path to Entry. Pass None / null to delete a path in this commit. |
parent_commit / parentCommit |
string (optional) |
Parent commit hash prefix for optimistic concurrency. Must be 8–64 characters when provided. If it doesn't match the latest commit, the API returns a 409 conflict. |
description |
string (optional) |
Repo description. Set on creation or patched on update. |
readme |
string (optional) |
Repo readme content. |
tags |
string[] (optional) |
Repo tags. |
is_public / isPublic |
boolean (optional) |
Whether the repo is publicly discoverable. |
에이전트 풀
에이전트 저장소의 스냅샷을 풀합니다. 기본적으로 최신 커밋이 반환됩니다. 특정 버전을 풀려면 version으로 커밋 해시 또는 태그를 전달하거나(또는 owner/name:version으로 식별자에 포함):
참고: 식별자 형식:
identifier인자는 세 가지 형태를 수락합니다:
name: 현재 워크스페이스 소유자에 대해 해석.owner/name: 완전 자격.owner/name:version: 특정 커밋 해시 또는 태그에 고정.선택적
version인자는 식별자에 포함된 버전을 재정의합니다. 둘 다 제공되지 않으면 최신 커밋이 반환됩니다.
from langsmith import Client
client = Client()
agent = client.pull_agent("email-assistant")
print(agent.commit_hash)
print(list(agent.files))
# Pull a specific commit.
pinned = client.pull_agent("email-assistant", version="7ca95573")
# Pull a tagged commit (for example, the production tag).
prod = client.pull_agent("email-assistant:production")
import { Client } from "langsmith";
const client = new Client();
const agent = await client.pullAgent("email-assistant");
console.log(agent.commit_hash);
console.log(Object.keys(agent.files));
// Pull a specific commit.
const pinned = await client.pullAgent("email-assistant", {
version: "7ca95573",
});
// Pull a tagged commit.
const prod = await client.pullAgent("email-assistant:production");
스킬 풀
스킬 저장소의 스냅샷을 풀합니다. pull_agent와 동일하게 동작하지만 SkillContext를 반환합니다:
from langsmith import Client
client = Client()
skill = client.pull_skill("deep-research")
print(skill.files["SKILL.md"].content)
import { Client } from "langsmith";
const client = new Client();
const skill = await client.pullSkill("deep-research");
const skillFile = skill.files["SKILL.md"];
if (skillFile.type === "file") {
console.log(skillFile.content);
}
풀 파라미터
pull_agent / pullAgent와 pull_skill / pullSkill 모두 다음 파라미터를 수락합니다:
| Parameter | Type | Description |
|---|---|---|
identifier |
string |
The repo's identifier. May include an inline version: owner/name:version. |
version |
string (optional) |
Commit hash or tag to pull. Overrides any version embedded in the identifier. |
pull_agent는 AgentContext를, pull_skill은 SkillContext를 반환합니다.
저장소 존재 확인
푸시하거나 풀기 전에 워크스페이스에 에이전트 또는 스킬 저장소가 존재하는지 확인하려면 이 메서드들을 사용하세요:
from langsmith import Client
client = Client()
if client.agent_exists("email-assistant"):
print("agent already exists")
if not client.skill_exists("deep-research"):
print("skill not found")
import { Client } from "langsmith";
const client = new Client();
if (await client.agentExists("email-assistant")) {
console.log("agent already exists");
}
if (!(await client.skillExists("deep-research"))) {
console.log("skill not found");
}
에이전트와 스킬 나열
두 유형의 저장소를 가시성, 보관 상태, 검색 쿼리의 선택적 필터로 나열합니다:
from langsmith import Client
client = Client()
# Python returns a paginated response.
result = client.list_agents(limit=20, query="email")
for repo in result.repos:
print(repo.repo_handle)
skills = client.list_skills(is_public=True)
import { Client } from "langsmith";
const client = new Client();
// TypeScript yields one repo at a time, auto-paginating.
for await (const repo of client.listAgents({ query: "email" })) {
console.log(repo.repo_handle);
}
for await (const skill of client.listSkills({ isPublic: true })) {
console.log(skill.repo_handle);
}
| Parameter | Type | Description |
|---|---|---|
limit |
int (Python only) |
Maximum number of repos to return per page. Defaults to 100. |
offset |
int (Python only) |
Number of repos to skip. Defaults to 0. |
is_public / isPublic |
boolean (optional) |
Filter to only public (or only private) repos. |
is_archived / isArchived |
boolean (optional) |
Filter by archived state. Defaults to False. |
query |
string (optional) |
Search query across repo handle, owner handle, description, and tags. |
참고: Python의
list_agents/list_skills는 명시적limit과offset이 있는 페이지네이션 응답 객체를 반환합니다. TypeScript의listAgents/listSkills는 소비할 때 페이지네이션을 자동으로 처리하는AsyncIterableIterator를 반환합니다.
에이전트 또는 스킬 삭제
경고: 이 작업은 영구적이며 되돌릴 수 없습니다. 저장소를 삭제하면 소유한 자식 파일 저장소도 제거됩니다.
워크스페이스에서 에이전트 또는 스킬 저장소를 삭제합니다:
from langsmith import Client
client = Client()
client.delete_agent("email-assistant")
client.delete_skill("deep-research")
import { Client } from "langsmith";
const client = new Client();
await client.deleteAgent("email-assistant");
await client.deleteSkill("deep-research");
더 알아보기
- Context Hub 사용 — Context Hub 소개.
- Python SDK — Python SDK 참조.