logo
0
2
WeChat Login
feat(ai): 支持从正文和评论中提取图片并作为独立image_url传给AI

ChatCompletion NPC

这是一个“嘴强王者”型 NPC。 它只有嘴,没有手,负责读上下文、回评论,不直接执行仓库里的实际改动。

一个基于 requests 的最小 Python 脚本:

  • 读取 CNB 触发事件
  • 拉取 issue / PR 正文和评论上下文
  • 按顺序拼接 messages
  • 把评论历史按 author.is_npc 映射为 system / user
  • 从正文和评论里抽取图片,单独作为 image_url 传给 AI
  • 调用 AI 流式接口
  • 将 AI 回复回写到 issue 评论
  • 打印 SSE 返回的 JSON 到 stderr

依赖

  • Python 3.10+
  • requests

安装依赖:

pip install -r requirements.txt

运行方式

直接运行:

python main.py

程序依赖环境变量。CNB_* 变量由平台注入,不在这里展开。

程序自己的环境变量

可选

  • NPC_BASE_URL
    • AI 接口地址
    • 不配置时,默认使用:
      • ${CNB_API_ENDPOINT}/${CNB_REPO_SLUG}/-/ai/
  • NPC_KEY
    • AI 接口鉴权
    • 不配置时,默认优先使用 CNB_TOKEN_FOR_AI,没有则回退到 CNB_TOKEN
  • CNB_NPC_NAME
    • 传给 AI 的 model 参数时会去掉开头的 :
  • CNB_NPC_PROMPT
    • 如果存在,会作为第一条 system 消息拼进 messages

事件支持

当前支持:

  • issue.comment@npc
  • pull_request.comment@npc

行为:

  1. 判断触发事件
  2. 拉取上下文评论
  3. 构造 messages
  4. 调用 AI 流式接口
  5. 把 AI 结果回写到 issue 评论

消息规则

评论上下文按以下规则构造:

  • author.is_npc == true -> system
  • 其他评论 -> user
  • 第一条 system 是 NPC 身份描述
  • 第二条 user 是 issue / pull 的原始正文
  • 后续评论按时间顺序进入消息列表
  • 评论内容会先去掉 @****(***) 这类片段
  • 评论或正文里的图片会从 Markdown / HTML 中拆出来,作为 image_url 单独传给 AI
  • user 消息会带上用户名,例如 alice: 你好

如果 CNB_NPC_PROMPT 存在,它会替换第一条 system

AI 输出格式

AI 接口只按流式方式处理。

程序会拆解流式响应,并提取:

  • 正文回复
  • 思考内容 / reasoning 内容
  • token 用量

写回 issue 时,思考内容会被格式化成引用块:

> 思考内容 正文回复

如果没有思考内容,就只写正文回复。

日志

程序会把 AI 流式返回的每条 SSE JSON 打印到 stderr

说明

这份脚本是按最小实现写的,没有额外框架和抽象,适合先跑通流程再迭代。