主题
使用 SDK 管理上下文
使用 LangSmith SDK 以编程方式推送、拉取、列出和删除 Context Hub 中的 agent 与 skill 仓库。
使用 LangSmith Python 和 TypeScript SDK,以编程方式管理 Context Hub 中的 agent repos 和 skill repos。从 CI 推送新版本,在运行时拉取最新或某个固定的提交以将上下文注入你的 agent,并使用更多方法来检查是否存在、列出和搜索仓库,以及删除你不再需要的内容。
NOTE
Context Hub 方法需要 langsmith>=0.7.35(Python)和 langsmith>=0.5.23(TypeScript)。
设置
- 安装软件包:
bash
pip install -U langsmithbash
uv add langsmithbash
yarn add langsmith配置环境变量。如果你的环境中已经设置了
LANGSMITH_API_KEY,请跳过此步。否则,请在 LangSmith 的 Settings > API Keys > Create API Key 中创建一个,然后将其设为环境变量:bashexport LANGSMITH_API_KEY="lsv2_..."
NOTE
Python 异步: 本页展示的所有方法也都可在 AsyncClient(从 langsmith 导入)上使用,签名相同——只需对每个调用 await 即可。TypeScript SDK 默认即为异步;没有单独的异步客户端。
推送一个 agent
创建一个新的 agent 仓库,或为现有仓库提交一个新版本。 如果该仓库尚不存在,它会以你提供的 元数据(description、readme、tags、is_public)创建。如果它已存在, 则仅在这些字段被显式传入时才对其打补丁。
该方法返回一个指向 LangSmith UI中新提交的 URL:
python
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)typescript
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);推送一个 skill
与 push_agent 的接口完全相同,但提交到一个 skill 仓库。 用它来为其他 agent 可以依赖的可复用能力进行提交:
python
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)typescript
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 中的一个条目可以是指向另一个 agent 或 skill 仓库的链接,这让你能够在不跨仓库重复 内容的情况下组合上下文。例如,一个将工作委派给共享 skill 的 agent。
如果你省略 commit_id,LangSmith 会在你推送此次提交时链接到该仓库的最新提交。如果被链接的仓库之后更新,LangSmith 会将该更新传播到引用它的父仓库。
python
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)typescript
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 都接受以下参数:
| 参数 | 类型 | 描述 |
|---|---|---|
identifier | string | 仓库的标识符。 |
files | dict[str, Entry | None] | 文件路径到 Entry 的映射。传入 None / null 以在此提交中删除一个路径。 |
parent_commit / parentCommit | string(可选) | 用于乐观并发控制的父提交哈希前缀。提供时必须为 8–64 个字符。如果它与最新提交不匹配,API 会返回一个 409 冲突。 |
description | string(可选) | 仓库描述。在创建时设置,或在更新时打补丁。 |
readme | string(可选) | 仓库 readme 内容。 |
tags | string[](可选) | 仓库标签。 |
is_public / isPublic | boolean(可选) | 仓库是否可被公开发现。 |
拉取一个 agent
拉取一个 agent 仓库的快照。默认返回最新提交;通过 version 传入提交哈希或标签(或将 owner/name:version 内嵌到标识符中)以拉取特定版本:
NOTE
标识符格式:identifier 参数接受三种形式:
name:针对当前工作区所有者解析。owner/name:完全限定。owner/name:version:固定到某个特定的提交哈希或标签。
可选的 version 参数会覆盖标识符中内嵌的任何版本。 如果两者都未提供,则返回最新提交。
python
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")typescript
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");拉取一个 skill
拉取一个 skill 仓库的快照。工作方式与 pull_agent 完全相同,但返回一个 SkillContext:
python
from langsmith import Client
client = Client()
skill = client.pull_skill("deep-research")
print(skill.files["SKILL.md"].content)typescript
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 都接受以下参数:
| 参数 | 类型 | 描述 |
|---|---|---|
identifier | string | 仓库的标识符。可包含一个内嵌版本:owner/name:version。 |
version | string(可选) | 要拉取的提交哈希或标签。会覆盖标识符中内嵌的任何版本。 |
pull_agent 返回一个 AgentContext;pull_skill 返回一个 SkillContext。
检查仓库是否存在
使用这些方法,在推送或拉取之前检查你的工作区中 是否存在某个 agent 或 skill 仓库:
python
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")typescript
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");
}列出 agent 和 skill
列出任一类型的仓库,带有针对可见性、归档状态和搜索查询的可选过滤器:
python
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)typescript
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);
}| 参数 | 类型 | 描述 |
|---|---|---|
limit | int(仅 Python) | 每页返回的最大仓库数。默认为 100。 |
offset | int(仅 Python) | 要跳过的仓库数。默认为 0。 |
is_public / isPublic | boolean(可选) | 只过滤公开(或只私密)仓库。 |
is_archived / isArchived | boolean(可选) | 按归档状态过滤。默认为 False。 |
query | string(可选) | 跨仓库 handle、所有者 handle、描述和标签的搜索查询。 |
NOTE
Python 的 list_agents / list_skills 返回一个带有显式 limit 和 offset 的分页响应对象,用于手动分页。TypeScript 的 listAgents / listSkills 返回一个 AsyncIterableIterator,会在你消费它时 自动处理分页。
删除一个 agent 或 skill
WARNING
此操作是永久性的,无法撤销。删除一个仓库也会 移除它所拥有的子文件仓库。
从你的工作区删除一个 agent 或 skill 仓库:
python
from langsmith import Client
client = Client()
client.delete_agent("email-assistant")
client.delete_skill("deep-research")typescript
import { Client } from "langsmith";
const client = new Client();
await client.deleteAgent("email-assistant");
await client.deleteSkill("deep-research");