크론 작업 사용하기

크론 작업 사용하기

어시스턴트를 스케줄에 따라 실행하는 것이 유용한 상황은 많아요.

예를 들어 매일 실행되어 그날의 뉴스 요약 이메일을 보내는 어시스턴트를 만든다고 가정해요. 크론 작업을 사용해 어시스턴트를 매일 오후 8시에 실행할 수 있어요.

LangSmith Deployment는 사용자 정의 스케줄로 실행되는 크론 작업을 지원해요. 사용자는 스케줄, 어시스턴트 및 일부 입력을 지정해요. 그 후 지정된 스케줄에 따라 서버는:

  • 지정된 어시스턴트로 새 스레드를 생성
  • 지정된 입력을 그 스레드로 전송

참고로 이는 매번 동일한 입력을 스레드로 전송해요.

LangSmith Deployment API는 크론 작업을 만들고 관리하기 위한 여러 엔드포인트를 제공해요. 자세한 내용은 API 참조를 참고하세요.

때로는 사용자 상호작용을 기반으로 그래프를 실행하고 싶지 않고 스케줄에 따라 실행하길 원할 수 있어요 — 예를 들어 그래프가 팀의 주간 할 일 목록 이메일을 작성해 보내길 원할 때요. LangSmith Deployment는 Crons 클라이언트를 사용해 자체 스크립트를 작성하지 않고도 이를 수행할 수 있게 해줘요. 그래프 작업을 스케줄링하려면 그래프를 실행할 시기를 클라이언트에 알리기 위해 크론 표현식을 전달해야 해요. Cron 작업은 백그라운드에서 실행되며 그래프의 일반적인 호출을 방해하지 않아요.

모든 크론 스케줄은 UTC로 해석돼요. 스케줄을 지정할 때 원하는 실행 시간을 UTC로 변환했는지 확인하세요.

출처: 문서

본문

설정

먼저 SDK 클라이언트, 어시스턴트 및 스레드를 설정해요:

Python:

from langgraph_sdk import get_client

client = get_client(url=<DEPLOYMENT_URL>)
# Using the graph deployed with the name "agent"
assistant_id = "agent"
# create thread
thread = await client.threads.create()
print(thread)

Javascript:

import { Client } from "@langchain/langgraph-sdk";

const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// Using the graph deployed with the name "agent"
const assistantId = "agent";
// create thread
const thread = await client.threads.create();
console.log(thread);

cURL:

curl --request POST \
    --url <DEPLOYMENT_URL>/assistants/search \
    --header 'Content-Type: application/json' \
    --data '{
        "limit": 10,
        "offset": 0
    }' | jq -c 'map(select(.config == null or .config == {})) | .[0].graph_id' && \
curl --request POST \
    --url <DEPLOYMENT_URL>/threads \
    --header 'Content-Type: application/json' \
    --data '{}'

출력:

{
'thread_id': '9dde5490-2b67-47c8-aa14-4bfec88af217',
'created_at': '2024-08-30T23:07:38.242730+00:00',
'updated_at': '2024-08-30T23:07:38.242730+00:00',
'metadata': {},
'status': 'idle',
'config': {},
'values': None
}

스레드의 크론 작업

특정 스레드와 연결된 크론 작업을 만들려면 다음과 같이 작성할 수 있어요:

Python:

# This schedules a job to run at 15:27 (3:27PM) UTC every day
cron_job = await client.crons.create_for_thread(
    thread["thread_id"],
    assistant_id,
    schedule="27 15 * * *",
    input={"messages": [{"role": "user", "content": "What time is it?"}]},
)

Javascript:

// This schedules a job to run at 15:27 (3:27PM) UTC every day
const cronJob = await client.crons.create_for_thread(
  thread["thread_id"],
  assistantId,
  {
    schedule: "27 15 * * *",
    input: { messages: [{ role: "user", content: "What time is it?" }] }
  }
);

cURL:

curl --request POST \
    --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/crons \
    --header 'Content-Type: application/json' \
    --data '{
        "assistant_id": <ASSISTANT_ID>,
    }'

더 이상 유용하지 않은 Cron 작업은 반드시 삭제하는 것이 중요해요. 그렇지 않으면 LLM에 원치 않는 API 요금이 쌓일 수 있어요! 다음 코드로 Cron 작업을 삭제할 수 있어요:

Python:

await client.crons.delete(cron_job["cron_id"])

Javascript:

await client.crons.delete(cronJob["cron_id"]);

cURL:

curl --request DELETE \
    --url <DEPLOYMENT_URL>/runs/crons/<CRON_ID>

무상태(stateless) 크론 작업

다음 코드를 사용해 무상태 크론 작업을 만들 수도 있어요. 무상태 크론 작업은 각 실행마다 새 스레드를 만들어요:

Python:

# This schedules a job to run at 15:27 (3:27PM) UTC every day
cron_job_stateless = await client.crons.create(
    assistant_id,
    schedule="27 15 * * *",
    input={"messages": [{"role": "user", "content": "What time is it?"}]},
)

Javascript:

// This schedules a job to run at 15:27 (3:27PM) UTC every day
const cronJobStateless = await client.crons.create(
  assistantId,
  {
    schedule: "27 15 * * *",
    input: { messages: [{ role: "user", content: "What time is it?" }] }
  }
);

cURL:

curl --request POST \
    --url <DEPLOYMENT_URL>/runs/crons \
    --header 'Content-Type: application/json' \
    --data '{
        "assistant_id": <ASSISTANT_ID>,
    }'

다시 말하지만, 작업이 끝나면 작업을 삭제하는 것을 잊지 마세요!

Python:

await client.crons.delete(cron_job_stateless["cron_id"])

Javascript:

await client.crons.delete(cronJobStateless["cron_id"]);

cURL:

curl --request DELETE \
    --url <DEPLOYMENT_URL>/runs/crons/<CRON_ID>

무상태 크론의 스레드 정리

이 기능에는 LangGraph API 버전 0.5.18 이상과 Python SDK 0.3.2 이상, 또는 JavaScript SDK 1.4.0 이상이 필요해요.

무상태 크론이 트리거될 때마다 새 스레드가 생성돼요. on_run_completed 파라미터를 사용해 런이 완료된 후 해당 스레드에 무슨 일이 일어날지 제어하세요:

  • "delete" (기본값): 런이 완료된 후 스레드를 자동으로 삭제해요.
  • "keep": 나중에 검색할 수 있도록 스레드를 보존해요. 이러한 스레드는 직접 정리할 책임이 있어요. 권장 방법은 애플리케이션에 TTL 추가하는 방법을 참고하세요.

예시: 나중에 검색하기 위해 스레드 유지하기

Python:

# Create a stateless cron that keeps threads after execution.
# Configure checkpointer.ttl in langgraph.json to auto-delete old threads.
# See: https://docs.langchain.com/langsmith/configure-ttl
cron_job = await client.crons.create(
    assistant_id,
    schedule="27 15 * * *",
    input={"messages": [{"role": "user", "content": "Daily report"}]},
    on_run_completed="keep"
)

# You can later retrieve the runs and their results
runs = await client.runs.search(
    metadata={"cron_id": cron_job["cron_id"]}
)

Javascript:

// Create a stateless cron that keeps threads after execution.
// Configure checkpointer.ttl in langgraph.json to auto-delete old threads.
// See: https://docs.langchain.com/langsmith/configure-ttl
const cronJob = await client.crons.create(
  assistantId,
  {
    schedule: "27 15 * * *",
    input: { messages: [{ role: "user", content: "Daily report" }] },
    onRunCompleted: "keep"
  }
);

// You can later retrieve the runs and their results
const runs = await client.runs.search({
  metadata: { cron_id: cronJob["cron_id"] }
});

cURL:

# Create a stateless cron that keeps threads after execution.
# Configure checkpointer.ttl in langgraph.json to auto-delete old threads.
# See: https://docs.langchain.com/langsmith/configure-ttl
curl --request POST \
    --url <DEPLOYMENT_URL>/runs/crons \
    --header 'Content-Type: application/json' \
    --data '{
        "assistant_id": "<ASSISTANT_ID>",
        "schedule": "27 15 * * *",
        "input": {"messages": [{"role": "user", "content": "Daily report"}]},
        "on_run_completed": "keep"
    }'

더 알아보기 (Learn more)