跳至内容

IM 机器人

AICodeReviewer 可以通过自定义机器人 webhook 或飞书自建应用机器人发送聚合后的评审问题。 这些都是摘要 channel,接收汇总后的评审结果。在 outputs.routes 或按 workspace 的 outputs.summary 中配置路由。

  1. 打开目标群 → 设置 → 群机器人 → 添加机器人 → 自定义机器人
  2. 设置机器人名称和头像
  3. 复制 webhook URL(https://open.feishu.cn/open-apis/bot/v2/hook/...)
  4. 如果启用了签名校验(推荐),复制机器人设置里显示的签名密钥
  5. 点击保存
终端窗口
# 必填
export AICR_FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx"
# 仅当飞书机器人设置启用了签名校验时必填
export AICR_FEISHU_SECRET="your-signing-secret"
outputs:
channels:
- name: feishu-code-review
kind: feishu_bot
webhook_url_env: AICR_FEISHU_WEBHOOK # 持有 webhook URL 的环境变量
secret_env: AICR_FEISHU_SECRET # 机器人启用签名校验时必填
mention_author: true # @ 提交作者
mention_fallback: skip # 作者无法解析时的策略:"all" | "skip"
outputs:
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
rules:
# 把 P4 changelist 路由到飞书
- match:
trigger: p4-main
target_kind: commit
summary: [feishu-code-review]
# 把 GitHub push 评审路由到飞书。若不配置 summary 路由,有问题的 run
# 可能被记为跳过(skipReason="no_output_publisher")。
- match:
trigger: github
target_kind: push
summary: [feishu-code-review]

或者按 workspace 固定 channel:

workspaces:
instances:
p4-main:
source_repo:
trigger: p4-main
repo: "//depot/main"
outputs:
summary: [feishu-code-review]

当飞书机器人启用了签名校验,每个请求必须包含 timestamp 和 sign 字段。AICR 用 secret_env 指定的密钥自动计算签名:

string_to_sign = timestamp + "\n" + secret
signature = Base64(HMAC-SHA256(key=string_to_sign, message=""))

如果看到错误 19021: sign match fail,请确认 secret_env 的值与飞书机器人配置页显示的 签名密钥一致。

AICR 使用 JSON 2.0 schema(card.schema = "2.0",markdown 放在 card.body.elements 下)发送飞书卡片。在 2.0 下,行内代码、带语言解析的代码块、标题、 引用块和表格都能原生渲染。AICR 在分发前应用 toFeishuMarkdown()——它只做 Markdown 修复 和空行折叠,不会把标题降级为粗体或把表格降级为纯文本(那些 1.0 时代的转换反而会 破坏 2.0 渲染)。如果行内代码或代码高亮显示为字面反引号,请确认 channel dispatcher 走的是 2.0 schema 路径。

当 summary 路由同时在 issue 记录渠道(gitea_problem_issue、github_problem_issue 或 gitlab_problem_issue)落盘本次评审的完整报告时,飞书卡片改为链接该 issue, 而不是逐条重复问题。频道上的 issue_link_card(仅 feishu_bot/feishu_app) 选择卡片内容:

  • titles(默认):标题行、问题计数、逐条问题标题和完整报告链接
  • brief:只有标题行、问题计数和链接
  • full:标题行、完整问题区块和链接
outputs:
channels:
- name: feishu-code-review
kind: feishu_bot
webhook_url_env: AICR_FEISHU_WEBHOOK
issue_link_card: full # brief | titles(默认)| full

使用 feishu_app 以自建应用机器人身份发送报告。启用机器人能力、发布应用, 将机器人加入报告接收群和成员来源群;两个群可以不同。单聊接收人需要在应用可用范围内。 该集成本身只主动发送消息;为报告卡片启用「重新评审」按钮时,需要同一应用的 IM 连接启用事件回调(见评审卡片按钮)。

  1. 在开发者后台创建企业自建应用,进入 应用能力 → 添加应用能力,启用机器人。
  2. 进入 开发配置 → 权限管理 → API 权限,按下表搜索权限标识并开通。 AICR 使用 tenant_access_token,应开通应用身份权限,无需用户 OAuth 授权。
  3. 使用成员资料匹配时,在 权限管理 → 数据权限 → 通讯录权限范围 中加入成员来源群涉及的用户或部门。 群成员列表权限不会自动扩大通讯录权限范围,应用可用范围也不能代替通讯录权限范围。
  4. 在 应用发布 → 版本管理与发布 创建版本,配置应用可用范围,提交审核并确认生效。 后续修改权限或可用范围时,也需按控制台提示完成发布和管理员审核。
  5. 将机器人加入报告接收群;使用成员目录时,还需加入 member_directory.chat_id 指定的来源群。 机器人须有接收群的发言权限。单聊接收人须在应用可用范围内。

下表按 AICR 实际调用的接口选择权限。只使用 chat_id 或 open_id 发送报告时,仅需第一项;从群成员资料关联提交者时, 再开通群成员、通讯录接口和相应字段权限。

用途 权限标识 控制台权限名称 / 何时需要
主动发送报告 im:message:send_as_bot 以应用的身份发消息;所有 feishu_app 频道必需
拉取来源群成员 im:chat.members:read 查看群成员;配置成员目录且开启 mention_author 时需要
调用成员资料接口 contact:contact.base:readonly 获取通讯录基本信息;调用 GET /contact/v3/users/:user_id 补充资料时需要
姓名、英文名、别名 contact:user.base:readonly 获取用户基本信息;读取 name、en_name、nickname 时需要
邮箱 contact:user.email:readonly 获取用户邮箱信息;按 email 匹配时建议开通
企业邮箱 contact:user.employee:readonly 获取用户受雇信息;需要 enterprise_email 时开通
手机号 contact:user.phone:readonly 获取用户手机号;需要 mobile 时开通
用户 ID contact:user.employee_id:readonly 获取用户 user ID;需要读取 user_id 或配置 receive_id_type: user_id 时开通

接口调用权限和字段权限是两层检查;单独开通 contact:user.base:readonly 不能代替通讯录接口权限。 上表选用接口页列出的权限组合;若已有官方列出的替代权限,无需重复申请更宽权限。 默认使用 open_id 拉取群成员和生成 @,无需为了 @ 额外读取手机号或 user_id。 email 与 enterprise_email 的字段权限不同;后者还要求企业管理员已启用飞书邮箱服务。 如需完整获取本功能支持的资料,可申请表中全部权限,并确认用户资料本身已填写。

核对依据:官方发送消息、 获取群成员列表、 获取单个用户信息及 配置应用可用范围。 外部成员、不在通讯录授权范围内的成员,或未授权的敏感字段,可能无法补全; AICR 保留可用群内资料,匹配不确定时不 @。遇到 41050 优先检查通讯录权限范围, 230002 检查机器人是否在接收群,230013 检查单聊接收人的应用可用范围。

在服务端环境设置 AICR_FEISHU_APP_SECRET,再合并以下配置:

outputs:
channels:
- name: feishu-app-review
kind: feishu_app
app_id: cli_replace_me
app_secret_env: AICR_FEISHU_APP_SECRET
receive_id_type: chat_id
receive_id: oc_report_group
mention_author: true
mention_fallback: skip
guess_author: true
member_directory:
chat_id: oc_member_source_group
cache_ttl_seconds: 300
user_mappings:
"[email protected]": ou_replace_with_app_open_id
"alice-dev-workspace": ou_replace_with_app_open_id
routes:
default:
summary: [feishu-app-review]

app_id 和 receive_id 必填;app_secret_env 与明文 app_secret 二选一。 数据库配置中的明文凭据沿用现有加密存储和脱敏编辑流程。 receive_id_type 默认为 chat_id;open_id、user_id、union_id 和 email 用于指定个人接收人。base_url 默认为 https://open.feishu.cn,唯一备选值是 https://open.larksuite.com,无需添加 /open-apis。Open ID 在不同应用间不通用。

两种飞书渠道共享内置 feishu-summary.hbs、问题渲染、JSON 2.0 卡片和默认零问题策略 publish_if_summary。命名模板 templates.summary / templates.problem 优先; 工作区目录按渠道名、feishu_app.*、feishu_bot.*、通用模板的顺序查找, 因此已有 webhook 工作区模板也能用于应用报告。应用发送时将卡片序列化为 JSON 字符串, 放入消息接口的 content 字段。

设置 mention_author: true 后,AICR 分页读取 member_directory.chat_id, 再补充应用有权限读取的 name、en_name、nickname、email、enterprise_email、 mobile、open_id、user_id 和 union_id。只在内存保存这些字段;默认缓存 12 小时, cache_ttl_seconds 范围为 0–604800(7 天),0 表示不复用缓存。渠道值覆盖全局 outputs.author_resolution.directory_cache_ttl_seconds。新配置代次使用独立缓存。 两个 TTL 字段均支持静态文件与数据库配置,沿用文件来源的优先级与锁定规则。 临时网络、HTTP 429 或 HTTP 5xx 失败可沿用过期快照并记录诊断,每次后续调用重新刷新。 权限拒绝或成员列表不完整会清除快照;TTL 为 0 时不保留快照用于回退。没有可用快照时 报告不带 @ 照常发送。成员数据只供宿主发布链路与独立身份模型调用使用,评审 MCP 工具 不暴露成员列表。资料请求最多并发 4 个,单次请求超时 15 秒,刷新工作预算为 60 秒。

匹配时统一 Unicode 表示并忽略大小写,按以下优先级查找:

  1. 渠道内 user_mappings:作者邮箱、用户名、显示名或完整 P4 提交者 workspace 精确映射到当前应用的 open_id。配置目录时,映射目标必须在来源群中。
  2. P4 的 submitterWorkspace 按标点或空格分隔后匹配完整标识片段。 例如 build_alice_PC 匹配别名 alice,malice_PC 不匹配。 此步骤排除不足三个字符的短别名,至少两个汉字的中文姓名除外。 唯一的 workspace 匹配优先于 admin 等共享账号,即使账号命中其他成员的邮箱前缀; 其他 provider 跳过此步骤。
  3. 作者完整邮箱与个人邮箱或企业邮箱匹配。
  4. 用户名或显示名与中英文名、别名、邮箱本地部分、手机号或 ID 精确匹配。
  5. 所有规则均未匹配且 guess_author 开启时,使用独立 LLM 调用选择一个目录候选人, 或返回无法确定。

同一优先级出现多个候选时跳过 @,停止较弱规则和模型兜底;P4 workspace 有歧义时也如此。 即使配置了 mention_fallback: all 也不会转为 @ 所有人; 全局邮箱黑名单同样禁止 @。AICR 不使用 push 投递者或分析服务自己的 P4 workspace 猜测作者。 mention_author 默认为 false;未配置目录时,只有显式 user_mappings 能解析个人, 全局 Git 登录名映射不能当作飞书 ID。推荐使用 mention_fallback: skip,避免未匹配作者触发群提醒。

feishu_app 的 guess_author 默认开启。设为 false 会关闭 workspace 推测和模型兜底, 保留显式映射及邮箱、姓名、别名的精确匹配。mention_author 仍控制实际通知;关闭时不拉目录, 也不调用关联模型。Git 输出频道沿用平台原生作者解析。飞书 webhook 和企业微信 webhook 机器人没有成员目录能力,不执行模型关联。

对于别名 owent、工作邮箱 [email protected],P4 workspace owent_myrion-pc_6689、 独立 P4 用户名 owent,或 GitHub/Gitea 的同名用户及该邮箱,已有规则即可匹配,无需调用模型。 其他未匹配的信息可以使用独立模型组:

llm:
model_chain:
default:
- provider: your-existing-provider
model: your-review-model
role: heavy
directory-identity:
- provider: your-existing-provider
model: your-identity-model
role: light
author_resolution_model_chain: directory-identity
workspaces:
defaults:
author_resolution_model_chain: directory-identity
instances:
your-workspace:
author_resolution_model_chain: directory-identity

将模型组合并进现有配置。选择顺序为 workspace 实例 → workspace defaults → llm.author_resolution_model_chain → llm.default_model_chain,不会继承 workspace 的审查主链。 三个字段都支持静态文件和数据库管理。管理界面的 Model groups → Model chains 设置全局值, Workspaces 设置默认值及实例覆盖。沿用数据库优先级、重置和模型组引用校验; 报告发送前即使发布了新配置,运行中的任务仍使用接收时固定的配置版本。

专用身份提示词只向选定模型提供提交者身份线索、候选人的姓名、别名和邮箱; 不包含手机号、目录原生 ID、凭据、审查代码或报告。候选编号为临时值,程序校验其成员资格后生成 @。 目录资料不会进入主代码审查提示词或持久化报告状态。只有允许的候选且模型置信度为高时才接受; 重名、无法确定、无效输出、模型异常或超过 15 秒均跳过 @,报告照常发送, 即使配置 mention_fallback: all 也不会转成全员通知。 关联调用使用配置的回退链、重试、provider 限流及共享单次/每日预算。 候选超过 500 人或序列化输入超过 64,000 字符时,整体跳过模型分析,不截断候选列表。 完整字段路径见配置参考。

目录读取失败或成员列表受安全限制时,报告继续发送但不带 @。通讯录资料查询失败时, 保留可用群内字段,并记录不含个人资料的诊断。来源群匹配到的人可能不在报告接收群中; 实际 @ 效果仍取决于飞书的群成员和通知规则,需要在目标租户验收。

客户端缓存租户访问令牌,令牌被明确拒绝时刷新并重试一次。HTTP 错误、非零 API 状态码 或缺少消息回执均使发布失败。消息传输异常可能已完成投递。自动提交批次持久保存发送 身份,在首次尝试后最多 59 分钟内复用 UUID;SQLite/Redis 可跨重启保留身份。 UUID 过期或不确定请求发生变化时阻止重发。其他评审路径仅在内存中为令牌重试复用 UUID,不提供重启恢复。

  1. 打开目标群 → 群设置 → 群机器人 → 添加机器人
  2. 设置机器人名称和头像
  3. 复制 webhook URL(https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...)
  4. 点击保存
终端窗口
# 必填
export AICR_WECOM_WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx"

企业微信群机器人 webhook 不使用 HMAC 签名校验,无需 secret 环境变量。

outputs:
channels:
- name: wecom-ops
kind: wecom_bot
webhook_url_env: AICR_WECOM_WEBHOOK
mention_author: false # @ 提交作者
mention_fallback: skip # 作者无法解析时的策略:"all" | "skip"
no_problems: { action: suppress }
# mentioned_mobile_list: ["+86-13800138000"] # 可选:额外发送一条有界 text 提醒;
# 手机号提醒只存在于 text 消息类型
outputs:
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
rules:
# 把 P4 changelist 路由到企业微信
- match:
trigger: p4-main
target_kind: commit
summary: [wecom-ops]

企业微信群机器人消息支持部分 Markdown:标题、粗体、链接、行内代码和引用块可原生渲染。 表格会被拍平为纯文本行。 代码块会被保留。AICR 在分发前自动应用 toWeComMarkdown()。

报告保留每条问题的完整正文、建议和代码引用。企业微信 webhook Markdown 的上限是 4096 个 UTF-8 字节,仅超限时裁剪正文并注明,原生提醒保留。飞书 webhook 请求上限 为 20 KiB,应用卡片请求为 30 KiB,预算包含 JSON 转义与请求字段;报告链接、 提醒和卡片按钮保留。企业微信应用报告按 2048 字节分片。

没有通讯录 API 的 IM 频道(wecom_bot、feishu_bot、wecom_app)可以通过 严格 YAML/JSON 成员文件解析提交作者,并输出原生带类型的 @,而不是纯文本 @username:

outputs:
channels:
- name: wecom-group
kind: wecom_bot
webhook_url_env: AICR_WECOM_WEBHOOK
mention_author: true
member_directory:
source: file
path: ./private/im-members.yaml
directory_id: engineering-wecom
identity_scope: { kind: wecom_corp, id: ww_example }
watch: true # 父目录 watch,默认开启

成员文件应由运行时用户持有,目录权限为 0700,文件权限为 0600。 通过 deploy.sh 部署时,/app/data/private 对应宿主的 data/db/private; 部署权限修复保留该子树及 data/db/build 中任务备份的私有权限。

成员文件格式见配置参考;要点:

未配置目录的 webhook 只从显式 outputs.author_resolution.email_mappings 获取原生 提醒身份。VCS 登录名或飞书 ID 不能直接标识企业微信成员。P4 共用账号可用 author_mappings 将完整提交工作区映射到成员 key,或开启 guess_author 做无歧义 的工作区匹配。文件目录结果替换回退提醒,并在渲染前传入自定义 atMentions。 mention_author: false 关闭目录匹配与动态手机号提醒。

  • 匹配顺序:按触发器隔离的精确 vcs_accounts、显式 author_mappings、 再是确定性的姓名/邮箱——猜测默认关闭,频道显式 guess_author: true 才开启。
  • wecom_userid 成员内联渲染 <@userid>;wecom_mobile 成员额外发送一条 有界 text 提醒(手机号提醒只在 text 消息生效);飞书成员渲染带类型的 <at> 标签。
  • 整个文件校验通过才使用;否则报告照常发送但不去 @——损坏目录绝不回退 @all。每份报告固定一个目录快照,覆盖全部分片。
  • 文件路径相对主配置文件目录解析。allowed_root 缺省为该目录;解析 .. 和符号链接后, 文件必须仍在允许的根目录内。根目录外的绝对路径需要显式配置受信根。
  • 文件中的姓名、别名、邮箱除类型化 mention id 外不进入 payload、prompt 或日志。

wecom_app 渠道通过自建应用(message/send)把汇总报告发送给显式 成员、部门或标签,或发送到一个 appchat 应用群(appchat/send)。 凭据保存在 im.connections 条目中(明文秘密在数据库配置中密封; 推荐使用 app_secret_env):

im:
connections:
corp-review:
kind: wecom_app
corp_id: ww_example
agent_id: 1000002
app_secret_env: AICR_WECOM_APP_SECRET
outputs:
channels:
- name: wecom-app
kind: wecom_app
connection: corp-review
target:
kind: recipients # 成员/部门/标签
users: [alice_zhang]
- name: wecom-group
kind: wecom_app
connection: corp-review
target:
kind: appchat # 本应用创建的一个群
chat_id: exampleChat123

行为说明:

  • 报告为企业微信 Markdown,按 UTF-8 安全分片,每片至多 2048 字节; 每片有独立送达回执,已送达的分片不会重发。业务拒绝 (errcode != 0)会让渠道失败,而不是报告成功。
  • 只有明确的 token 错误码 40014/42001 会刷新一次 token 并重试一次; 超时保持结果 unknown,绝不盲发。
  • appchat 目标要求群由同一应用创建且应用可见范围包含根部门—— 环境不允许该范围时 appchat 保持未验证,请使用 recipients。
  • IM 连接的消息命令与评审按钮另行配置 (见管理 IM 连接与命令绑定)。

评审卡片按钮(飞书应用与企业微信应用)

Section titled “评审卡片按钮(飞书应用与企业微信应用)”

当满足以下全部条件时,feishu_app / wecom_app 输出渠道发出的报告会附带一个 重新评审按钮:

  • 飞书:输出渠道的 app_id 对应一个启用了事件回调的 im.connections 飞书连接, 且为群聊(receive_id_type: chat_id)目标;
  • 企业微信:输出渠道引用的连接启用了回调,且目标为显式收件人 (target.kind: recipients;只有配置了回调的应用才能发送可回调卡片, appchat 群消息没有卡片类型)。卡片在 Markdown 报告分片之后单独发送, 按钮的 task_id 与 key 都只携带动作 ID;
  • 两种平台都要求存在一个启用 review 命令的命令绑定,其 conversations 覆盖报告会话(飞书为接收群,企业微信为单聊),且 repositories 注册了 被评审的仓库。

按钮只携带服务端预发行的不透明动作 ID(24 小时有效)。点击时服务端校验 真实操作人、平台消息/任务标识、会话与绑定授权后创建新的评审请求;同一按钮重复 点击返回原请求编号,转发到其他会话的卡片、被撤权的绑定和过期动作都会被拒绝。 发送回执未落库的动作保持待绑定状态,不会被回调自报来源激活。企业微信 webhook、appchat 等不支持回调的渠道不显示按钮。

发布恢复复用原动作 ID 与已确认消息,不为已确认发送重新发行按钮。 动作在消费或过期前保留发行快照供追溯;点击产生的新请求使用点击时的当前配置快照。 缺少持久的点击时快照时,动作不被消费。

接收消息命令(回调与长连接)

Section titled “接收消息命令(回调与长连接)”

除主动发送报告外,IM 连接还可以接收群内 @机器人 的消息命令。当前支持三种 接收模式,配置在 im.connections 中按连接选择:

im:
connections:
# 企业微信 AI 机器人 —— 事件回调模式
wecom-airobot:
kind: wecom_aibot
corp_id: ww_example
callback:
enabled: true
token_env: AICR_WECOM_AIBOT_TOKEN # 回调 Token
encoding_aes_key_env: AICR_WECOM_AIBOT_AES # 回调 EncodingAESKey
# 企业微信 AI 机器人 —— 长连接模式(无需公网回调 URL)
wecom-airobot-lc:
kind: wecom_aibot
corp_id: ww_example
aibot_id: "https://open.work.weixin.qq.com/..." # 机器人的 bot_id
secret_env: AICR_WECOM_AIBOT_LC_SECRET # 机器人的 Secret
# 飞书自建应用 —— 事件回调模式(平台侧「将事件发送至开发者服务器」)
feishu-app:
kind: feishu_app
app_id: cli_example
app_secret_env: AICR_FEISHU_APP_SECRET
tenant_key: "xxxx"
callback:
enabled: true
verification_token_env: AICR_FEISHU_VERIFY_TOKEN
encrypt_key_env: AICR_FEISHU_ENCRYPT_KEY
# 飞书自建应用 —— 长连接模式(平台侧「使用长连接接收事件」):
# 不配置回调(或 enabled: false),服务端用 app_id+app_secret 主动建连
feishu-app-lc:
kind: feishu_app
app_id: cli_example
app_secret_env: AICR_FEISHU_APP_SECRET

回调模式的平台侧回调 URL 均为 https://<服务地址>/callbacks/im/<连接id>, 例如 https://aicr.example.com/callbacks/im/wecom-airobot。配置保存时平台会 发起 URL 验证 challenge,服务端按协议回包;之后每条 @机器人 消息先验签 解密、持久化入箱,再处理命令。

当前支持的命令语法(aicr 前缀,群内 @机器人 后发送):

  • aicr help — 所有接收模式都会即时回复命令帮助。企业微信回调模式按官方 被动回复协议在回调响应体里回加密的流式消息(msgtype: "stream"、 finish: true;直接回 markdown 会被平台忽略);企业微信长连接通过 aibot_respond_msg 回复;飞书通过消息 API 回复。
  • 查询命令(只读,同样走绑定授权;列表只显示当前授权绑定中的仓库, 除非该绑定启用 allow_all_repositories): aicr projects(项目列表)、aicr reviews [别名](近期评审)、 aicr commits <别名> [分支] / aicr prs <别名> [分支](近期会触发评审的 提交/PR-MR)、aicr detail <别名> <修订> / aicr prdetail <别名> <PR号> (评审详情:状态、模型、输入/输出/缓存命中的 token、请求数、成本、耗时, 仅保留近期记录)、aicr queue(排队任务含计划开始时间)、 aicr running(进行中评审)。 对绑定注册的仓库,查询按工作区、来源触发器和仓库引用共同匹配; 同一工作区和仓库的其他触发器记录不在该绑定的查询范围内。
  • aicr chat-id / aicr review <repo> <revision> / aicr status <id> / 取消命令 — 需要配置启用的 im.command_bindings。授权按“操作人、会话、连接、命令” 四个维度判定,操作人支持两种形态任一命中:精确 principal ({type, id})或范围匹配器——部门(含子部门)、标签(承载 角色/用户组语义)、职位、自定义字段、飞书群成员/部门/职务,以及 any(任意已认证操作人)。每个匹配器可加 expires_at 实现临时授权, 到期自动失效。范围匹配依赖服务端目录快照(企业微信需要一个启用的 wecom_app 连接提供通讯录,AI 机器人的加密 userid 自动转换), 目录不可用时该维度不授权(fail-closed),精确 principal 不受影响。 绑定可开启 allow_all_repositories:仓库别名除绑定注册表外,还能按 workspace id 或仓库全名匹配已接入的项目(aicr projects 列出的条目), 免去逐仓库注册。 被拒绝的命令会把操作人与会话标识回显给发送者(仅该会话内可见)—— 群白名单引导由此闭环:在群里 @机器人发一次命令,从拒绝回复中取群 id 加入绑定的 conversations 即可(企业微信 AI 机器人的群没有查询 API)。

取消命令(写操作,需在绑定的 commands 中显式加入 cancel):

  • aicr cancel <repo> <revision> — 取消指定仓库中匹配修订前缀(提交 哈希前若干位)或精确数字修订号的进行中/排队中评审任务。
  • aicr cancel <repo> before <时长> — 取消指定仓库在指定时间之前入队 的任务;时长格式 <n><m|h|d>(分钟/小时/天),如 2h、30m、3d。 也支持带明确时区的 ISO 时间,如 2026-09-01T00:00:00+08:00。
  • aicr cancel before <时长> — 不限定仓库,取消当前绑定授权范围内 指定时间之前入队的任务(绑定开启 allow_all_repositories 时为全部仓库)。

取消覆盖 auto-commit 排队批次(终态关闭并释放流)、正在 执行的批次(先持久化取消再中止执行,已发布的输出不回滚)、IM 评审请求 (终态 rejected,向原请求会话发送取消通知)以及遗留的进行中运行 记录(标记为 cancelled)。带别名的形式要求该别名在绑定注册表中 (或经 allow_all_repositories 解析);取消范围始终不超过绑定授权的 仓库集合。即使开启 allow_all_repositories,显式别名也只取消该仓库。 活动 webhook 与管理端重评也可通过实时运行注册表中止;取消阻止后续发布, 已经发送的输出不会撤回。 窗口外等待的延期评审也会被持久化删除。

aicr review 持久化请求及配置快照后,服务端工作器校验固定修订,并在共享的 workspace 并发限制下执行评审。Git 需要配置仓库中可达的完整提交哈希;SVN 和 P4 需要正整数修订号。同一活动 workspace、仓库和修订号的重复请求会复用已有评审, 不占用新请求配额。aicr status 仅向原操作人、原连接和原会话返回请求状态, 且状态命令绑定仍须允许该仓库。执行中断的评审按阶段恢复:分析阶段的崩溃在持久 退避后有界重试(当前默认最多 3 次恢复尝试,超出记为失败);分析完成后中断的发布按 持久 checkpoint 仅恢复发布,不会重复调用模型;无法证明送达状态的发布中断标记为 publication_unknown,服务端不会自动再次发布。终态通知发回请求会话; 企业微信长连接模式复用已订阅的连接,并等待平台发送回执。 所有发布操作均失败或缺少发布通道时,请求记为失败;部分发布成功时记为部分成功。 非法发布检查点不能授权重发;检查点超过 1 MiB 或持久化失败时停止后续发送, 保留最后有效恢复状态。Git 提交作者来自持久化的 VCS 元数据,聊天操作人单独记录。 传输失败和无法证明送达保留 publication_unknown;明确收件人拒绝记为失败,已知部分送达记为部分成功。

长连接模式由服务端在 aicr serve 启动时按连接表主动建立连接(断线自动 重连),不依赖回调 URL,也不需要 callback 配置:企业微信 AI 机器人用 官方 WebSocket 协议(aibot_id+secret),飞书用官方 SDK 长连接 (app_id+app_secret)。两种企业微信模式各自对应一个独立的机器人实体 (各自有自己的 bot_id/凭据),可以并存;飞书的回调与长连接在平台侧互斥, 按开发者后台选择的事件接收方式配置对应连接。

IM channel 类型共享输出通道配置中记录的通用输出 channel 字段。 与 IM 机器人最相关的字段:

字段 含义
webhook_url_env webhook 渠道:持有机器人 webhook URL 的环境变量名
secret_env feishu_bot:持有签名密钥的环境变量名
mention_author 为 true 时,可解析的情况下 @ 提交作者
mention_fallback 作者无法解析时的策略:all(@ 所有人)或 skip
no_problems 该 channel 的零问题策略(publish / suppress / publish_if_summary)

关于路由、target-kind 匹配和零问题策略,见输出通道和 输出通道配置。

仪表盘的配置页签为 IM 集成提供两个实体页面:IM 连接与IM 命令绑定。 连接保存协议身份与凭据(wecom_app、wecom_aibot 或 feishu_app); 命令绑定引用某个连接,并定义哪些带类型的操作人、会话与命令可以发起评审。 在抽屉中输入的明文凭据会在持久化边界密封,之后不再回显; 删除或改名仍被绑定或频道引用的连接时,发布边界会原子地拒绝。

这两个页面管理草稿配置:报告发送与三种接收模式(企业微信 AI 机器人 事件回调/长连接、飞书应用事件回调)已生效,aicr help 即时应答;评审 命令(review/status)需启用命令绑定后才会执行,绑定默认停用。im.* 字段合同见配置字段参考。