运行 vs 线程:何时使用哪一个
Source: Dev.to

Crewship 有两种执行已部署 crew 的方式:Run API 和 Thread API。如果你已经使用过该平台,你已经在使用 runs。Threads 是较新的、相对不那么明显的功能,我们经常被问到的一个问题是:什么时候该使用哪一种?
Runs 适用于一次性任务。Threads 适用于对话。这是简短版说明,下面的内容是详细版。
运行:默认方式
运行 是对你的 crew 的一次单独执行。你发送输入,它完成它的工作,你得到输出。每次运行都有自己的容器,彼此之间不共享任何内容,运行结束后环境会被销毁。
crewship invoke --input '{"topic": "AI agents in logistics"}'
或通过 API:
curl -X POST https://api.crewship.dev/v1/runs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"deployment_id": "dep_abc123", "input": {"topic": "AI agents in logistics"}}'
你会得到一个运行 ID。运行会经历 pending → running → succeeded/failed/canceled。你可以实时流式传输事件来观察你的代理工作,或者仅仅轮询获取结果。
无需设置、无需清理、无需管理状态。
何时适合使用运行
当你的 crew 的任务在一次执行中开始并结束时,使用运行是合适的选择:
- “写一篇关于 X 的博客文章”——输入进,内容出,完成。
- “分析此数据集并生成报告”——同样的流程。
- 对列表中的项目独立进行的批处理操作。
- 由 webhook 或 cron 调度触发的后台任务。
- 在更大工作流中,crew 作为管道的一个阶段。
常见模式:crew 不需要提出澄清性问题,也不需要记住上一次发生了什么。它接受输入并产生输出,这就是整个交互过程。
运行不能做的事
运行是 无状态 的。当一次运行结束后,它就不存在了。如果你使用相同的部署再次启动运行,它对之前的运行没有任何上下文。它不知道你五分钟前用稍有不同的输入运行过它,也不知道上一次的输出几乎正确但需要微调。
对于许多工作负载来说,这正是你想要的,但对某些情况来说,这可能是个问题。
Source: …
线程:当你需要记忆时
线程 是一个持久的对话上下文,范围限定在某个部署上。你只需创建一次,然后在需要时多次在其中运行你的 crew。每次运行都会获取线程当前的状态,运行结束后可以更新该状态。下次运行会从上一次结束的地方继续。
# 创建线程
crewship thread create dep_abc123
# 在其中运行
crewship invoke dep_abc123 --thread thr_xyz789 -i '{"message": "Research AI agents in healthcare"}'
# 后续 – crew 会记住第一条信息
crewship invoke dep_abc123 --thread thr_xyz789 -i '{"message": "Now focus on diagnostic applications"}'
通过 API:
# 创建线程
curl -X POST https://api.crewship.dev/v1/threads \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"deployment_id": "dep_abc123"}'
# 在其中运行
curl -X POST https://api.crewship.dev/v1/threads/thr_xyz789/runs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input": {"message": "Research AI agents in healthcare"}}'
线程通过 values 字段跟踪状态——这是一个 JSON 对象,crew 可以读取和写入。每次运行结束后,Crewship 会保存一个 检查点,为你提供状态随时间变化的完整历史记录。
线程生命周期
线程拥有自己的状态:
| 状态 | 含义 |
|---|---|
idle | 可接受新的运行请求 |
busy | 正在执行运行;在结束前新的运行请求会返回 409 错误 |
interrupted | 运行被中断 |
error | 上一次运行失败,但线程仍可接受新的运行请求 |
同一时间 只能 有一个运行在一个线程中执行。这种设计保证状态一致,防止并发运行相互覆盖更新。
何时使用线程
线程在以下需要上下文在交互之间保持的场景中表现出色:
- 对话式代理 – 聊天机器人或客服助理,每条用户消息都基于前一次交流。
- 迭代细化 – 例如,“生成营销计划”,然后“让预算部分更详细”,再“添加时间表”。每次运行都在前一次输出的基础上进行。
- 带有人类审批的多步骤工作流 – crew 进行调研、展示结果、等待用户指示,然后继续。线程保存中间状态,无需你手动管理。
检查点
每当线程内的运行结束时,Crewship 会创建一个检查点,记录当时线程的 values。你可以检索完整的检查点历史,以:
- 审计状态的演变过程。
- 如有需要,回滚到之前的状态。
- 通过检查过去的值来调试意外行为。
TL;DR
- Runs = 一次性、无状态的执行。用于孤立任务、批处理作业或任何不需要记住先前运行记录的情况。
- Threads = 有状态、顺序执行。用于对话、迭代工作或需要在多次调用之间保留上下文的工作流。
选择适合任务的工具,让 Crewship 处理繁重的工作!
检查点
Crewship 会保存检查点——线程当时状态的快照。
curl https://api.crewship.dev/v1/threads/thr_xyz789/history \
-H "Authorization: Bearer YOUR_API_KEY"
这为您提供审计轨迹。它对调试也很有用:如果团队的回复在第 5 回合出现偏差,您可以查看第 4 回合的检查点,以了解当时的状态。
线程元数据
Threads support a metadata field that’s separate from the conversation state. Use it for things like user IDs, channels, tags — anything you want to filter or search by later:
curl -X POST https://api.crewship.dev/v1/threads \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deployment_id": "dep_abc123",
"metadata": {
"user_id": "user_42",
"channel": "web",
"priority": "high"
}
}'
当你拥有数百个跨不同用户和使用场景的线程时,这一点尤为重要。
并排比较
| 特性 | 运行 | 线程 |
|---|---|---|
| State | None — each run is isolated | Persistent across runs via values |
| Lifecycle | pending → running → terminal | idle → busy → idle(循环) |
| Concurrency | Unlimited parallel runs | One run at a time per thread |
| History | Individual run records | Checkpoints after each run |
| Setup | None — just create a run | Create thread first, then run inside it |
| Cleanup | Automatic | Manual — delete thread when done |
| Cost profile | Predictable per run | Grows with conversation length |
其他平台如何处理
如果你使用过其他代理平台,你会注意到这种划分。OpenAI 的 Assistants API 曾经有 Threads 和 Runs——字面上就是相同的名称。它们后来改为 Responses API 和 Conversations,但概念完全相同:一个无状态的执行原语和一个可选的持久化层。
- LangGraph – 调用
graph.invoke()进行一次性执行。传入thread_id可获得持久化、检查点以及从任意点恢复的能力。 - CrewAI –
kickoff()是一次性执行;另有独立的对话模式提供多轮交互。
所有这些平台的模式都是:runs 是执行原语;threads(或其等价物)可选地将 runs 通过共享状态串联起来。只有在需要时才使用 threads。
那么应该使用哪一种?
一个问题可以帮助你大致判断:团队(crew)是否需要记住之前执行的内容?
| 答案 | 建议 |
|---|---|
| 否 | 使用 run。添加线程只会增加不必要的复杂性。 |
| 是 | 使用 thread。试图通过把之前的上下文塞进 run 输入来伪造有状态性会很快变得混乱,而且你会失去检查点、历史记录以及线程提供的并发保证。 |
指向线程的信号
- 用户将在一次会话中多次与团队交互。
- 团队的输出依赖于对话历史,而不仅仅是当前输入。
- 你需要一条审计轨迹来记录状态随时间的演变。
指向运行的信号
- 团队可以通过单一套输入完成任务。
- 你希望并行触发大量执行。
- 工作负载是由自动化系统触发,而不是由人发送消息。
开始使用线程
如果您一直在使用 runs 并想尝试 threads,部署上无需做任何更改。Threads 可与任何已部署的 crew 配合使用——包括 CrewAI、LangGraph Python 或 LangGraph JS。
# Create a thread
crewship thread create dep_abc123 --metadata '{"user_id": "demo"}'
# First turn
crewship invoke dep_abc123 --thread thr_xyz789 \
-i '{"message": "What can you help me with?"}'
# Second turn — crew receives context from the first
crewship invoke dep_abc123 --thread thr_xyz789 \
-i '{"message": "Tell me more about option 2"}'
# Check the history
crewship thread history thr_xyz789
完整的 API 参考请参阅threads 文档。
关于 runs、threads 或其他任何问题?请查看文档或通过以下方式联系我们。
