Linear Agent Session:交互模型与本工作区的三种接法
Developing the Agent Interaction
同组入口:Getting Started、Interaction Best Practices、Signals、OAuth actor authorization、MCP server、Assign and delegate issues、Agent platform。
AI 参与说明(Agent:Grok Bot (Blog)、Cursor):本文由 Grok Bot (Blog) 在 Cursor Cloud 中根据 2026-11-05 打开的 Linear 开发者文档、公开 GraphQL SDL,以及本仓已发布的派工约定整理。工作区侧只核对了「是否存在名为 Devin、Cursor 的 OAuth app 用户」和「Issue 的 delegate 能否指向他们」;没有读取 Agent Activity 流,也没有写入 webhook、token 或私有产品实现。系统提示中的模型名称为 Grok 4.7;完整模型标识、reasoning effort 与提供方未取得任务级运行记录。执行入口 Cursor Cloud。中文经 humanizer-zh 编辑。AI 协助只表示整理过程,不代表质量保证或作者身份。
阅读前先看这几个词
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| AgentSession | 代理会话 | Linear 为一次代理运行保存的生命周期,用户能看见它在干活、在等输入、出错或已结束 |
| AgentActivity | 代理活动 | 写进会话的一条记录,例如想法、工具调用、提问、最终回复或错误 |
| delegate | 受托代理 | Issue 上负责动手的代理;人仍可以是 assignee |
| assignee | 负责人 | Issue 的人类负责人,代理被委托时不占用这个字段 |
| promptContext | 提示上下文 | created webhook 里的格式化字符串,带上 Issue、评论和 guidance |
| externalUrls | 外部链接 | 挂在会话上的 {label, url} 列表,用来打开代理自己的页面或 PR |
| Agent Plan | 代理计划 | 会话级任务清单,技术预览;更新时整份替换 |
| actor=app | 应用身份 | OAuth 安装参数,让后续写入显示为应用,而不是安装者本人 |
| Linear MCP | Linear MCP | 官方远程 MCP,让已有助手读写 Issue、项目和评论 |
先说结论
Linear 把「工作区里的一个代理」和「某个助手临时调用 Linear API」分成两条路。前者是安装后的 OAuth app:被人 @ 或被设为 delegate 时创建 AgentSession,用 webhook 收指令,用 AgentActivity 把过程写回 Linear。后者是 Linear MCP 或普通 API:能建 Issue、改状态、贴评论,但调用者仍是当前授权身份,不会自动变成一套会话 UI。
本工作区的三种角色分属这两条路:
| 角色 | 在 Linear 里的身份 | 主路径 | 会不会进入 Agent Session |
|---|---|---|---|
| Devin | 已安装的 OAuth app 用户,Issue 可以把 delegate 设成它 | 公开实践是 Linear delegate,并可加标签派工 | 会。mention 或 delegate 会创建 AgentSession;这是原生会话 UI 的入口 |
| Grok Bot | 工作区用户列表里没有名为 Grok 的 app 用户 | Linear MCP:读写 Issue、评论和状态 | 不会。它不订阅 AgentSessionEvent,也不发射 AgentActivity |
| Cursor | 工作区里有名为 Cursor 的 OAuth app 用户,也有 Issue 把 delegate 设成它 | 已发布约定不走 delegate,而走 Cursor Cloud Agent API | 主路径不走。delegate 只说明它能被委托;本文没有读取那些 Issue 的活动流 |
flowchart TB
human["人<br/>负责人仍是 assignee"] --> issue["Linear Issue"]
issue -->|"delegate"| devin["Devin<br/>AgentSession"]
grok["Grok Bot<br/>Linear MCP"] -->|"小单:设 delegate"| devin
grok -->|"大单:Cloud Agent API"| cursor["Cursor Cloud<br/>实现并开 PR"]
cursor -->|"回写状态和链接"| issue
devin -->|"AgentActivity<br/>thought / action / response"| issue
图里的箭头是本仓已经写过的派工方向,加上 Linear 对 delegate 的产品定义。它不表示每一次历史 delegate 都留下了可读的活动记录。
AgentSession 记录一次运行
AgentSession tracks the lifecycle of an agent run. Linear creates one automatically when an agent is mentioned or delegated an issue. Session state is visible to users and updated from the last emitted activity; the agent does not have to set the state by hand. Agent session
交互指南列出六种用户可见状态:pending、active、error、awaitingInput、complete、stale。指南用它们表示正在工作、等待用户输入、出错或已经做完,但没有给出「某一种 AgentActivity 必然切到某一个状态」的对照表。下表只记录时间窗、恢复方式和指南里的用途。
| 状态 | 指南里的用途 | 本文能核对的条件 |
|---|---|---|
pending | 会话已建立,尚未表现为进行中 | mention 或 delegate 会自动创建;应用也可以主动创建 |
active | 用户看到代理正在工作 | 由最近一次 activity 自动更新;具体哪一条 activity 触发,指南没有逐项写明 |
awaitingInput | 等待用户输入 | 同上,指南把它列为可见状态,没有写死切换表 |
error | 出错 | 同上 |
complete | 工作结束 | 同上 |
stale | 会话变陈旧 | 第一次响应之后,后续 activity 最多还能在 30 分钟内继续发送,超时即 stale;再发一条 activity 可以恢复 |
另外两个容易和状态枚举混在一起的词:
- unresponsive 不是这六种状态之一。收到
created后,如果 10 秒内既没有 activity,也没有更新外部 URL,会话会显示为 unresponsive。设置externalUrls还可以避免一个新会话被标成 unresponsive。Session webhooks - 2026-11-05 的公开 GraphQL SDL 里,
AgentSessionStatus比指南多一个stopping。schema 注释只把它列进举例,没有定义进入和离开条件。本文不补这层语义。
externalUrls:面板和 PR 都挂在会话上
用 agentSessionUpdate 写入 externalUrls。每一项是 label 加 url,url 在数组内应唯一。整组替换走 externalUrls;只增删走 addedExternalUrls 或 removedExternalUrls。GitHub pull request 也放进这个数组,Linear 写明这会在以后打开和 PR 相关的能力。单数的 externalLink 已弃用。Session external URL
同一天的 SDL 有一处读模型差异:AgentSession.externalUrls 被标成弃用,读取侧的替代字段是 externalLinks;更新输入 AgentSessionUpdateInput 仍接受 externalUrls。写操作以开发者指南的 mutation 为准,读会话时同时看 externalLinks。
没有被点名时,可以自己开会话
代理没有被 mention 或 delegate,仍可以调用 agentSessionCreateOnIssue 或 agentSessionCreateOnComment 主动创建会话。Proactively creating sessions
Webhook:created 开工,prompted 续话
要收到这些事件,在 OAuth 应用里打开 Agent session events。AgentSessionEvent 只发给你自己的代理。接收端必须在 5 秒内返回。一旦订阅这个类别,客户就会在 Linear 里看到 Agent Session UI,包括只为调试而打开的情况。Session webhooks
action | 何时出现 | 代理应做什么 |
|---|---|---|
created | 新会话:用户 mention,或通过指派完成 delegate | 开一轮新循环。用 promptContext 组装上下文;结构化字段在 agentSession.issue、agentSession.comment、previousComments、guidance |
prompted | 用户往已有会话又发了一条消息 | 消息在 webhook 的 agentActivity.body。把它插入对话历史再继续 |
最佳实践把第一跳说得更具体:收到 created 后立刻发一条 thought,让用户知道提示已经收到。第一次响应必须在 10 秒内发出,否则显示 unresponsive。第一次响应之后,后续 activity 仍可在最多 30 分钟内发送,否则会话变为 stale;再发一条 activity 即可恢复。Recommendations
交互指南允许用「任意 activity」或「更新外部 URL」来满足这 10 秒;最佳实践推荐的第一跳是 thought。两边一起看:10 秒内要有可见动作,首选一条 thought。
sequenceDiagram
participant User as 用户
participant Linear as Linear
participant Agent as 代理
User->>Linear: mention 或 delegate
Linear->>Agent: AgentSessionEvent created
Note over Agent: 5 秒内确认 webhook
Agent->>Linear: thought,或更新 externalUrls
Note over Linear: 10 秒内没有这两件事则 unresponsive
User->>Linear: 后续消息
Linear->>Agent: AgentSessionEvent prompted
Agent->>Linear: 后续 AgentActivity
promptContext 与 guidance
promptContext 是一段带标签的字符串。结构化字段已经在 webhook 的其他属性里,这段字符串用来直接塞进模型提示。下面保留指南示例的标签和文字,只调整了缩进,并略去原文中的 <other-thread>:
<issue identifier="ENG-123">
<title>Fix accessibility on checkout page</title>
<description>Make it screen-reader friendly</description>
<team name="Engineering"/>
<label>bug</label>
<label>a11y</label>
<parent-issue identifier="QJT0-2">
<title>Parent Issue Title</title>
<description>Parent issue description</description>
</parent-issue>
<project name="Checkout flow">Faster checkout process</project>
</issue>
<primary-directive-thread comment-id="34f7a7e0-b3dc-4c88-9383-07cbf06b186f">
<comment author="John Doe" created-at="2026-01-08 16:33:12">
<user id="df3fc33e-32f3-4e65-bae7-6f8f36bdd55f">botcoder</user>
Please implement this
</comment>
</primary-directive-thread>
<guidance>
<guidance-rule origin="team" team-name="Engineering">Always follow coding standards</guidance-rule>
</guidance>
guidance 指工作区、父团队或团队上配置的说明,例如偏好的仓库或任务约束。产品文档写明:工作区 guidance 全局生效,团队 guidance 追加本团队说明;两者都存在时,团队优先。指引会传给代理,具体怎么执行取决于那个代理的实现。Guiding Agents
AgentActivity:五种代理可写的类型
代理用 agentActivityCreate(SDK 里是 createAgentActivity)往会话追加活动。服务端校验形状,不合法会拒绝。body 支持 Markdown。下面的 JSON 转写自活动载荷文档,本文没有在本环境执行。Activity content payload
type | 谁来写 | 作用 | 载荷要点 |
|---|---|---|---|
thought | 代理 | 想法或内部笔记 | body |
action | 代理 | 一次工具调用 | action、parameter;做完可带 result |
elicitation | 代理 | 向用户要澄清或确认 | body |
response | 代理 | 工作完成或给出最终结果 | body |
error | 代理 | 报告失败 | body |
prompt | 仅用户 | 后续提示,或回答 elicitation | 创建时会向代理发 prompted。代理不能生成这种类型 |
thought 示例:
{
"content": {
"type": "thought",
"body": "The user asked about the weather."
}
}
action 可以先报开始,再带结果。result 可用 Markdown:
{
"content": {
"type": "action",
"action": "Searched",
"parameter": "San Francisco Weather",
"result": "12°C, mostly clear"
}
}
elicitation、response、error 都是 type 加 body。指南里的 error 示例是 "Out of credits. [Pay up!](https://agent.com/pay)",只说明 Markdown 链接可用,不是推荐的产品文案。
创建时可以把活动标成 ephemeral。这种活动临时显示,下一条来自该代理的活动会替换它。只有 thought 和 action 可以标 ephemeral。
在正文里提及人或 Issue 时,写普通的 Linear URL,不要自造 mention 语法。例如指南中的 https://linear.app/linear/issue/LIN-123/docs-issue 会在 UI 里变成对那个 Issue 的提及。Adding mentions in Markdown
Signals 是活动上的可选修饰
signal 和 content 并列,告诉接收方怎么处理这条活动。和会话主循环相关的三条是:Signals
| Signal | 方向 | 适用类型 | 行为 |
|---|---|---|---|
stop | 人 → 代理 | prompt | 立即停止后续代码修改和 API 调用,再用 response 或 error 收尾 |
auth | 代理 → 人 | elicitation | Linear 临时展示账户关联链接;用户完成后,代理用 thought 继续 |
select | 代理 → 人 | elicitation | 给出选项。用户仍可以自由文本回复;选中的选项会变成普通 prompt,代理应用模型解释,不要假设返回值一定等于某个 value |
Agent Plan 是整份替换的清单
Agent Plan API 处于技术预览,后续可能变化。计划是会话级步骤数组,每步有 content 和 status:pending、inProgress、completed、canceled。代理可以随执行增删步骤,但更新时必须整份替换,不能只改一条的状态。写入仍用 agentSessionUpdate 的 plan 字段。Agent plans
mutation AgentSessionUpdate($agentSessionId: String!, $data: AgentSessionUpdateInput!) {
agentSessionUpdate(id: $agentSessionId, input: $data) {
success
}
}
变量里的 data.plan 是完整数组。这段 mutation 转写自指南,本文未执行。
认证:应用自己成为工作区成员
App authentication uses the normal OAuth2 flow. Add actor=app to the authorization URL so the install creates an app actor instead of acting as the installing user. A workspace admin must approve that install. actor=app supersedes actor=application. An app installed this way cannot also request the admin scope. Actor and scopes
提及和委托是两枚可选 scope,要写进 scope:
| Scope | 作用 |
|---|---|
app:assignable | 应用可以作为 Issue 的 delegate |
app:mentionable | 应用可以在 Issue、文档等编辑器里被提及 |
Assigning an issue to the app sets the delegate, not the assignee. A human keeps ownership while the agent acts on their behalf. 即使有 app:assignable,代理也不能成为项目成员或项目负责人。产品 FAQ 写明:Agents are not counted as billable seats in Linear. 提供代理的服务商可以另行收费。Delegating to agents、Are agents billable seats?
安装后用当前 token 查询 viewer { id },把这个 app user id 和 token 一起存。管理员可以随时改团队权限;订阅 Permission changes 时会收到 PermissionChange / teamAccessChanged。撤销应用时另有 OAuthApp / revoked。Installation
客户与 Initiative 还有 customer:read / customer:write、initiative:read / initiative:write。本工作区的派工不依赖这四枚 scope,这里只列边界。
最佳实践里值得先做的几件事
这些是 Linear 对代理交互的建议,不是本工作区已经逐条实现的清单。Interaction Best Practices
- 收到
created后马上发thought,并在 10 秒内发出。 - 人把 Issue 委托给你,且当前状态类型不是
started、completed、canceled时,把 Issue 挪到该团队started类型里position最小的那个状态。自动化委托则留在 triage,把指派留给人。 - 正在做实现、而
Issue.delegate还空着时,把自己设为 delegate。已经由自动化委托的,不要抢这个字段。 - 做完发
response;还要用户动作时发elicitation或error。Linear 会在评论线程里再自动挂一条评论。 - 重建对话时读 Agent Activities,不要靠可编辑的评论。评论可能在上次运行之后被改过;活动是当时的快照。
- 仓库不确定时,先调
issueRepositorySuggestions:你提交自己有权限的候选仓库,Linear 按 Issue、会话、guidance 以及关联 Issue、近期 PR 等信号返回带confidence的排序。仍然不确定,就用更短的列表做一次 elicitation,而不是猜一个仓库。
候选列表示例转写自指南,未在本环境执行:
query($issueId: String!, $agentSessionId: String!) {
issueRepositorySuggestions(
issueId: $issueId
agentSessionId: $agentSessionId
candidateRepositories: [
{ hostname: "github.com", repositoryFullName: "linear/linear-app" }
]
) {
suggestions { repositoryFullName hostname confidence }
}
}
Inbox Notifications 和 Permission changes 是可选 webhook,分别覆盖「被取消委托、评论被回应」和「团队权限变化」。核心循环仍然是 AgentSessionEvent。
本工作区已经怎么接
下面只使用本仓已经公开的派工约定,以及 2026-11-05 对工作区成员和 delegate 字段的核对。不写 webhook 地址、token、团队 slug,也不展开未在 Blog 公开的产品实现。
Devin:delegate 进原生会话
已发布的做法是:小而确定的单子通过 Linear delegate 派给 Devin,并可加标签;Grok Bot 看 PR 质量,偏弱再升级模型重做。见 Grok Bot 实践指南 里「Cursor 与 Devin 的派工通道」。
2026-11-05 的核对与这句话一致:工作区有名为 Devin 的 OAuth app 用户,并且存在 assignee 仍是人、delegate 为 Devin 的 Issue。按 Linear 的规则,这种委托会创建 AgentSession。本文没有打开这些会话的活动列表,所以不描述某一张单子上实际出现过哪些 thought 或 PR 链接。
Grok Bot:MCP 编排,不是一等代理
Grok Bot 在已发布闭环里负责编排:读 Linear、跑 Routine、把编码交给 Cursor Cloud,并把状态和链接写回 Issue。见 Cursor Cloud、Grok Bot 与 Linear。
这是 MCP 或等价 API 编排,不是自建 OAuth Agent。依据有两层:
- 2026-11-05 按名称检索工作区用户,没有名为 Grok 的 app 用户。没有 app 用户,就没有可被 mention 或 delegate 的 AgentSession 主体。
- 本文撰写时通过 Linear MCP 读取 Blog 项目中的既有议题,没有调用
agentActivityCreate,也没有订阅AgentSessionEvent。MCP 的读写落在当前授权身份上,Linear 不会因此打开一套代理会话。
官方 MCP 的读写入口是 https://mcp.linear.app/mcp;只读可以用 /mcp/readonly,或在标准端点只申请 read scope。它管理 Issue、项目、评论等对象,文档没有把它说成 Agent Activity 的发射器。MCP server
Cursor Cloud:安装了应用,主路径仍在会话外面
工作区里存在名为 Cursor 的 OAuth app 用户,也存在 delegate 为 Cursor 的 Issue。这说明 Cursor 应用具备可委托身份,有人委托时,Linear 会按代理规则创建会话。
已经写进 Blog 的日常派工不是这条路。Grok Bot 直接调用 Cursor Cloud Agent API,每次写明模型和参数,默认 Composer 2.5,难单换 Grok 模型,并统一关闭 fast。不走 Linear 的 assign / delegate,因为那条路设不了 fast;Linear 上只更新状态、贴链接。见同一篇 Grok Bot 实践指南。
因此:Cursor 可以出现在 Agent Session 里,当前编码主路径不依赖这套原语。本文没有读取被委托 Issue 的活动流,不把「delegate 曾经是 Cursor」写成「那些任务的对话都在 Session UI 里」。
什么时候自建 Linear Agent
If the integration mostly reads Linear data, or its writes should be attributed to individual teammates, keep it an integration. Build an agent when the product should show up as its own workspace member, with its own mentions, delegation, and action history. When to build an integration or agent
对照上面三种接法:
| 需求 | 更合适的做法 |
|---|---|
| 助手要建单、改状态、贴评论,过程归在人的授权下 | 继续用 Linear MCP 或 actor 为用户的 API。Grok Bot 属于这里 |
| 编码参数必须由调用方指定,Linear 委托界面传不了 | 保持外部 API 派工,再把状态和链接写回 Issue。Cursor Cloud 的 fast 开关属于这里 |
| 用户要在 Linear 里 @ 它、看 thought / action、在同一条会话里追问 | 做成 OAuth app,打开 Agent session events,按 5 秒确认和 10 秒首条 activity 实现。Devin 属于这里 |
| 只是想在调试时看 webhook | 先别订阅 AgentSessionEvent。一订阅,客户就会看到 Agent Session UI |
自建代理还要自己承担 unresponsive、stale、guidance 和仓库选择。MCP 编排省掉这套会话状态机,代价是 Linear 里没有一条以该应用为名的活动时间线。两条路可以并存:编排层用 MCP 派工,真正被用户点名的编码代理再进 AgentSession。本工作区现在就是这个形状。
关联阅读
- Cursor Cloud、Grok Bot 与 Linear:以 yindongliang.com 为例的开发测试与观测闭环:内容仓与站点仓上,编排、实现、视觉 QA 和观测怎样回填 Linear。本文不重复那条闭环。
- Grok Bot 实践指南:官方与社区最佳实践、使用方法与适用场景:delegate 派 Devin、API 派 Cursor 的日常规则写在这里。
参考资料
资料核对日为 2026-11-05。交互规则以当天打开的开发者页面为准;枚举差异以同一天的公开 SDL 为准。文中的 JSON、GraphQL 和 XML 均转写自这些页面,没有在本环境执行。