以编程方式使用文档

LangSmith Deployment 可运行任何框架。对于非基于 Deep Agents、LangChain 或 LangGraph 构建的代理,请使用 deployments-wrap-sdk 包(Google ADK)或 LangGraph Functional API 进行部署(支持 Claude Agent SDK、Strands、CrewAI、AutoGen 和其他库)。

支持的框架

以下框架在本指南中提供了端到端示例。每个示例从 agent.py 导出兼容 LangGraph 的图,可由 Agent Server 提供服务:

Claude Agent SDK Strands Agents CrewAI AutoGen

Functional API 工作原理

当运行请求到达 Agent Server 用于 Functional API 包装的代理时:

  1. 平台使用运行输入和同一线程上先前轮次的任何保存状态(作为 @entrypoint-decorated agent 参数传入)调用你的 previous 函数。
  2. 入口点调用你的 @task装饰函数,该函数将请求委托给框架代理(Claude Agent SDK、Strands、CrewAI、AutoGen 或其他库)。
  3. 入口点返回 entrypoint.final(value=..., save=...)。其中 value 是本轮的响应; save 是检查点状态,用作下一轮的 previous
  4. Agent Server 持久化检查点,在支持时流式传输部分输出,并在配置了追踪时记录跟踪。

此模式保留了框架的执行语义,同时为你提供标准 Agent Server 功能:持久运行、多线程持久化、流式端点以及 LangSmith 可观测性。

前提条件

无论使用何种框架,你需要:

  • * Python 3.10+(适用于 Functional API 框架,Strands Agents 支持 Python 3.9+)
  • * A LangSmith API 密钥

通用部署模式

每个框架都遵循相同的步骤。在每个步骤内的标签页中选择你的技术栈,将代码片段组合到一个模块中(例如 agent.py),并将 @entrypoint装饰的函数导出为名为 agent端到端示例 部分展示了可复制完整文件。

Install dependencies

为您的框架安装 Python 包以及 LangGraph 和 LangSmith。

Claude Agent SDK

对于 Claude Agent SDK:

pip install "langsmith[claude-agent-sdk]" langgraph "langgraph-cli[inmem]"

在您的环境中设置 ANTHROPIC_API_KEY 。有关 Anthropic API 密钥,请参阅 Claude 控制台.

Strands Agents

对于 Strands Agents:

pip install strands-agents strands-agents-tools langgraph "langsmith[strands-agents]" "langgraph-cli[inmem]"

如果您使用 Amazon Bedrock 作为模型提供程序,请配置 AWS 凭证。

CrewAI

对于 CrewAI:

pip install crewai langgraph langsmith opentelemetry-instrumentation-crewai opentelemetry-instrumentation-openai "langgraph-cli[inmem]"

在您的环境中设置 LLM 提供程序凭证(例如 OPENAI_API_KEY 如果您使用 OpenAI 支持的模型)。

AutoGen

对于 AutoGen:

pip install autogen-agentchat autogen-ext langgraph langsmith opentelemetry-instrumentation-openai "langgraph-cli[inmem]"

在您的环境中设置 OPENAI_API_KEY (或您的模型提供程序凭证)。

Define your agent

使用您选择的框架构建您的代理,其方式与在 LangSmith 之外完全相同。

Claude Agent SDK

from claude_agent_sdk import ClaudeAgentOptions

options = ClaudeAgentOptions(
    model="claude-sonnet-4-6",
    system_prompt="You are a helpful assistant.",
)

Strands Agents

from strands import Agent

strands_agent = Agent(
    system_prompt="You are a helpful assistant.",
    model="us.anthropic.claude-sonnet-4-20250514-v1:0",
)

CrewAI

from crewai import Agent as CrewAgent, Crew, Task

researcher = CrewAgent(role="Researcher", goal="Research a topic", backstory="Expert researcher.")
crew = Crew(
    agents=[researcher],
    tasks=[Task(description="{topic}", agent=researcher, expected_output="A short report.")],
)

AutoGen

from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient

assistant = AssistantAgent(
    name="assistant",
    model_client=OpenAIChatCompletionClient(model="gpt-4o"),
)

Wrap with the Functional API

通过 @entrypoint装饰的函数名为 agent来公开您的代理。在其中,使用 @task 作为调用框架的工作单元。使用 entrypoint.final() 来返回响应并在同一线程的多次交互中保持对话历史。

Claude Agent SDK

from claude_agent_sdk import ClaudeSDKClient
from langgraph.func import entrypoint, task

@task
async def invoke_claude(prompt: str) -> str:
    async with ClaudeSDKClient(options=options) as client:
        await client.query(prompt)
        chunks: list[str] = []
        async for message in client.receive_response():
            chunks.append(str(message))
        return "\n".join(chunks)

@entrypoint()
async def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    prompt = history[-1]["content"]
    response = await invoke_claude(prompt)
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(
        value=[new_message],
        save=operator.add(history, [new_message]),
    )

Strands Agents

from langgraph.func import entrypoint, task
from strands.types.content import Message

@task
def invoke_strands(messages: list[Message]):
    result = strands_agent(messages)
    return [result.message]

@entrypoint()
def agent(messages: list[Message], previous: list[Message] | None = None):
    messages = operator.add(previous or [], messages)
    response = invoke_strands(messages).result()
    return entrypoint.final(value=response, save=operator.add(messages, response))

CrewAI

from langgraph.func import entrypoint, task

@task
def run_crew(topic: str) -> str:
    return str(crew.kickoff(inputs={"topic": topic}))

@entrypoint()
def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    response = run_crew(history[-1]["content"]).result()
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(value=[new_message], save=operator.add(history, [new_message]))

AutoGen

from langgraph.func import entrypoint, task

@task
async def invoke_autogen(prompt: str) -> str:
    result = await assistant.run(task=prompt)
    return result.messages[-1].content

@entrypoint()
async def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    response = await invoke_autogen(history[-1]["content"])
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(value=[new_message], save=operator.add(history, [new_message]))

Configure tracing

将框架的本机追踪转发到 LangSmith。在应用程序启动时调用追踪设置一次,在创建或调用代理之前。

Claude Agent SDK

from langsmith.integrations.claude_agent_sdk import configure_claude_agent_sdk

configure_claude_agent_sdk()

有关完整设置详情,请参阅 追踪 Claude Agent SDK 应用程序.

Strands Agents

设置您的 LangSmith API 密钥 和项目名称。如果您使用 Amazon Bedrock,还要配置 AWS 凭证。

from langsmith.integrations.strands_agents import setup_langsmith_telemetry

setup_langsmith_telemetry()

有关完整设置详情,请参阅 追踪 Strands Agents 应用程序.

CrewAI

将 LangSmith span 处理器注册到 CrewAI 和 OpenAI 插桩器中:

from langsmith.integrations.otel import OtelSpanProcessor
from opentelemetry import trace
from opentelemetry.instrumentation.crewai import CrewAIInstrumentor
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider

current_provider = trace.get_tracer_provider()
if isinstance(current_provider, TracerProvider):
    tracer_provider = current_provider
else:
    tracer_provider = TracerProvider()
    trace.set_tracer_provider(tracer_provider)

tracer_provider.add_span_processor(OtelSpanProcessor())
CrewAIInstrumentor().instrument(tracer_provider=tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)

有关完整设置详情,请参阅 追踪 CrewAI 应用程序.

AutoGen

将 LangSmith span 处理器注册到 OpenAI 插桩器中:

from langsmith.integrations.otel import OtelSpanProcessor
from opentelemetry import trace
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(OtelSpanProcessor())
trace.set_tracer_provider(tracer_provider)
OpenAIInstrumentor().instrument()

有关完整设置详情,请参阅 追踪 AutoGen 应用程序.

端到端示例

以下示例将代理定义、Functional API 包装、追踪设置以及 agent 符号的导出组合在一个 agent.py 文件中。选择您框架对应的标签页。

Claude Agent SDK

from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from langgraph.func import entrypoint, task
from langsmith.integrations.claude_agent_sdk import configure_claude_agent_sdk

configure_claude_agent_sdk()

options = ClaudeAgentOptions(
    model="claude-sonnet-4-6",
    system_prompt="You are a helpful assistant.",
)

@task
async def invoke_claude(prompt: str) -> str:
    async with ClaudeSDKClient(options=options) as client:
        await client.query(prompt)
        chunks: list[str] = []
        async for message in client.receive_response():
            chunks.append(str(message))
        return "\n".join(chunks)

@entrypoint()
async def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    prompt = history[-1]["content"]
    response = await invoke_claude(prompt)
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(
        value=[new_message],
        save=operator.add(history, [new_message]),
    )

Strands Agents

from langgraph.func import entrypoint, task
from langsmith.integrations.strands_agents import setup_langsmith_telemetry
from strands import Agent
from strands.types.content import Message

setup_langsmith_telemetry()

strands_agent = Agent(
    system_prompt="You are a helpful assistant.",
    model="us.anthropic.claude-sonnet-4-20250514-v1:0",
)

@task
def invoke_strands(messages: list[Message]):
    result = strands_agent(messages)
    return [result.message]

@entrypoint()
def agent(messages: list[Message], previous: list[Message] | None = None):
    messages = operator.add(previous or [], messages)
    response = invoke_strands(messages).result()
    return entrypoint.final(value=response, save=operator.add(messages, response))

CrewAI

from crewai import Agent as CrewAgent, Crew, Task
from langgraph.func import entrypoint, task
from langsmith.integrations.otel import OtelSpanProcessor
from opentelemetry import trace
from opentelemetry.instrumentation.crewai import CrewAIInstrumentor
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider

current_provider = trace.get_tracer_provider()
if isinstance(current_provider, TracerProvider):
    tracer_provider = current_provider
else:
    tracer_provider = TracerProvider()
    trace.set_tracer_provider(tracer_provider)

tracer_provider.add_span_processor(OtelSpanProcessor())
CrewAIInstrumentor().instrument(tracer_provider=tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)

researcher = CrewAgent(role="Researcher", goal="Research a topic", backstory="Expert researcher.")
crew = Crew(
    agents=[researcher],
    tasks=[Task(description="{topic}", agent=researcher, expected_output="A short report.")],
)

@task
def run_crew(topic: str) -> str:
    return str(crew.kickoff(inputs={"topic": topic}))

@entrypoint()
def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    response = run_crew(history[-1]["content"]).result()
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(value=[new_message], save=operator.add(history, [new_message]))

AutoGen

from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from langgraph.func import entrypoint, task
from langsmith.integrations.otel import OtelSpanProcessor
from opentelemetry import trace
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(OtelSpanProcessor())
trace.set_tracer_provider(tracer_provider)
OpenAIInstrumentor().instrument()

assistant = AssistantAgent(
    name="assistant",
    model_client=OpenAIChatCompletionClient(model="gpt-4o"),
)

@task
async def invoke_autogen(prompt: str) -> str:
    result = await assistant.run(task=prompt)
    return result.messages[-1].content

@entrypoint()
async def agent(messages: list[dict], previous: list[dict] | None = None):
    history = operator.add(previous or [], messages)
    response = await invoke_autogen(history[-1]["content"])
    new_message = {"role": "assistant", "content": response}
    return entrypoint.final(value=[new_message], save=operator.add(history, [new_message]))

每个示例都有两个要点:

  1. **导出 @entrypoint装饰的函数作为 agent** 在模块作用域。Agent Server 在提供图服务时导入此符号。
  2. **返回 entrypoint.final() 带有 save 参数** 以便对话状态在同一线程的不同轮次之间保持。

项目布局

可部署项目需要以下文件:

my-agent/
├── agent.py              # exports the agent graph
├── langgraph.json        # Agent Server config
├── pyproject.toml        # Python dependencies
└── .env                  # Provider credentials and LangSmith variables

langgraph.json 指向 Agent Server 导出的符号:

Claude Agent SDK

{
  "$schema": "https://langgra.ph/schema.json",
  "dependencies": ["."],
  "graphs": {
    "claude_agent": "./agent.py:agent"
  },
  "env": ".env"
}
[project]
name = "my-claude-agent"
version = "0.0.1"
requires-python = ">=3.10"
dependencies = [
    "langsmith[claude-agent-sdk]>=0.3.0",
    "langgraph>=0.4.0",
]
LANGSMITH_API_KEY=your-langsmith-api-key
LANGSMITH_TRACING=true
LANGSMITH_PROJECT=my-claude-agent
ANTHROPIC_API_KEY=your-anthropic-api-key

Strands Agents

{
  "$schema": "https://langgra.ph/schema.json",
  "dependencies": ["."],
  "graphs": {
    "strands_agent": "./agent.py:agent"
  },
  "env": ".env"
}
[project]
name = "my-strands-agent"
version = "0.0.1"
requires-python = ">=3.9"
dependencies = [
    "strands-agents>=0.1.0",
    "strands-agents-tools>=0.1.0",
    "langsmith[strands-agents]>=0.3.0",
    "langgraph>=0.4.0",
]
LANGSMITH_API_KEY=your-langsmith-api-key
LANGSMITH_TRACING=true
LANGSMITH_PROJECT=my-strands-agent
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.smith.langchain.com/otel/v1/traces
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=your-langsmith-api-key,Langsmith-Project=my-strands-agent
AWS_REGION=your-aws-region
AWS_PROFILE=your-aws-profile

CrewAI

{
  "$schema": "https://langgra.ph/schema.json",
  "dependencies": ["."],
  "graphs": {
    "crewai_agent": "./agent.py:agent"
  },
  "env": ".env"
}
[project]
name = "my-crewai-agent"
version = "0.0.1"
requires-python = ">=3.10"
dependencies = [
    "crewai>=0.100.0",
    "langgraph>=0.4.0",
    "langsmith>=0.3.0",
    "opentelemetry-instrumentation-crewai>=0.1.0",
    "opentelemetry-instrumentation-openai>=0.1.0",
]
LANGSMITH_API_KEY=your-langsmith-api-key
LANGSMITH_PROJECT=my-crewai-agent
OPENAI_API_KEY=your-openai-api-key

AutoGen

{
  "$schema": "https://langgra.ph/schema.json",
  "dependencies": ["."],
  "graphs": {
    "autogen_agent": "./agent.py:agent"
  },
  "env": ".env"
}
[project]
name = "my-autogen-agent"
version = "0.0.1"
requires-python = ">=3.10"
dependencies = [
    "autogen-agentchat>=0.4.0",
    "autogen-ext>=0.4.0",
    "langgraph>=0.4.0",
    "langsmith>=0.3.0",
    "opentelemetry-instrumentation-openai>=0.1.0",
]
LANGSMITH_API_KEY=your-langsmith-api-key
LANGSMITH_PROJECT=my-autogen-agent
OPENAI_API_KEY=your-openai-api-key

安装依赖项

从您的项目目录:

pip install -e .

启用追踪

使用特定于框架的 .env 模板在 项目布局中。Agent Server 在设置 "env": ".env" 时加载此文件在 langgraph.json.

设置 LANGSMITH_PROJECT 以及您的框架提供商凭据在该文件中。对于 Claude Agent SDK 和 Strands Agents,还要设置 LANGSMITH_TRACING=true。对于 CrewAI 和 AutoGen,追踪在 agent.py 中通过 OtelSpanProcessor() 和框架检测器启用,因此设置 LANGSMITH_API_KEYLANGSMITH_PROJECT only.

追踪 显示代理调用、工具调用和 LLM 交互在 LangSmith UI中。有关特定于框架的追踪选项,请参阅 配置追踪.

本地运行

使用 LangGraph CLI:

langgraph dev

这在以下地址提供代理服务 http://127.0.0.1:2024 并打开 LangSmith Studio。使用以下方式发送请求 curl:

Claude Agent SDK, CrewAI, AutoGen

# Create a thread
THREAD=$(curl -s -X POST http://127.0.0.1:2024/threads \
  -H "Content-Type: application/json" -d '{}' | python -c "import sys, json; print(json.load(sys.stdin)['thread_id'])")

# Run the agent and wait for the final response
curl -s -X POST "http://127.0.0.1:2024/threads/$THREAD/runs/wait" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "ASSISTANT_ID",
    "input": [{"role": "user", "content": "Hello"}]
  }'

Strands Agents

# Create a thread
THREAD=$(curl -s -X POST http://127.0.0.1:2024/threads \
  -H "Content-Type: application/json" -d '{}' | python -c "import sys, json; print(json.load(sys.stdin)['thread_id'])")

# Run the agent and wait for the final response
curl -s -X POST "http://127.0.0.1:2024/threads/$THREAD/runs/wait" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "ASSISTANT_ID",
    "input": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "Hello"}
        ]
      }
    ]
  }'

替换 ASSISTANT_ID 为您对象中的图键 langgraph.json graphs 。例如,如果您的配置是 "graphs": {"claude_agent": "./agent.py:agent"},使用 claude_agent;如果您的配置是 "graphs": {"strands_agent": "./agent.py:agent"},使用 strands_agent.

部署到 LangSmith

代理在本地运行后,使用以下方式部署 langgraph deploy:

langgraph deploy --name my-agent

关于环境配置、部署类型和修订管理,请参阅 部署到云端。关于自托管设置,请参阅 自托管部署。关于仅使用 Docker 托管而无需控制平面,请参阅 独立部署.