亚马逊AWS官方博客

Amazon Bedrock 赋能所思科技内部飞书创新智能问答

关于所思科技

所思科技是一家致力于使用下一代技术打造全球化的娱乐产品的公司。旗舰产品《猛兽派对》测试版在 Steam 平台创造了中国游戏公司历史最佳记录,首发即突破 10 万在线人数,同时《猛兽派对》也是首款获得 TGA 最佳多人游戏,TGA 最佳家庭游戏提名的国产游戏。另外一款产品 SKYBOX 是亚洲首款获得 Google Daydream 全球推荐和在 Google IO 展会上展示的 VR 视频播放器。它在 VR 播放器分类中全球占有率第一,是 Oculus 的 First Launch Partner,也是小米 VR 一体机的 VR 视频播放器解决方案。

背景介绍

所思科技日常使用飞书作为办公软件。飞书是一款面向组织与企业级团队的协作平台,整合了聊天、视频会议、文档协作、任务管理、项目跟踪等多种核心功能,大幅提高了团队的工作效率。

如今,大规模语言模型(LLM)模型风靡全球,办公软件如何实现 AI 智能化也成为了行业先驱公司必修的一门课题。在这个课题上,所思科技继续选择与亚马逊云服务合作,看中了其全球领先的 LLM 模型 Claude。Claude 是 Anthropic 公司最新推出的新一代大型对话式 AI 助手,具备强大的自然语言处理能力。经过时间的积累,Claude 于 2024 年推出了第三代模型,其超长的上下文窗口(200k token)和领先的推理分析能力,使其作为企业级 AI 助理可以高效处理大量重复性办公任务,如会议记录整理、邮件分类回复、数据分析报告生成等,从而极大提升办公效率。

本文将介绍如何将这一先进的 AI 助手 Claude 无缝集成至飞书机器人,赋能企业数字化转型,打造智能高效的协作体验。

架构图

本文采用的架构图如下,并且使用完全 CDK 的搭建方式,保证开箱即用的体验。

架构解释

这是一个事件驱动的无服务器架构,利用 AWS Lambda、API Gateway、DynamoDB、SNS、Bedrock 等服务,实现了一个聊天机器人应用。整个流程如下:

  1. 用户在飞书用户端给 Bot 发送的消息通过飞书开发平台触发回调请求。
  2. 回调请求会通过 API Gateway 转发给 Lambda callback_handler 函数。
  3. 由于飞书要求回调接口必须在 3 秒内返回 http 200 状态码,但是 Bedrock Claude3 的响应返回时间可能会超过这个 3 秒的阈值,所以我们需要对 Bedrock 的调用方式改成异步方式。 即 Lambda callback_handler 函数会将用户消息发布到 SNS 主题,SNS 主题会触发 Lambda chat 函数跟 Bedrock 进行交互。
  4. Lambda chat 函数会从 DynamoDB 数据库中查询历史聊天记录,结合 Bedrock Claude 服务生成回复内容。
  5. 生成的回复消息会被保存到 DynamoDB 数据库中,作为新的聊天记录。
  6. 最终,回复消息会在 Lambda chat 直接调用飞书的 SDK 把回复消息发送给飞书开放平台,从而显示给用户。

项目实施

准备部分

创建应用

  1. 飞书开放平台创建一个应用
  2. 在凭证与基础信息中,找到 App Id 和 App Secret,并记下来
  1. 添加应用能力-选择机器人
  1. 进入事件与回调 查看并记下 Verification Token
  1. 配置事件订阅回调 API 接口, 这个接口是我们 CDK 部署完成之后,API gateway 的端点地址可以在 CloudFormation 堆栈中的输出变量里查询到

配置权限和回调事件

  1. 进入开发配置-权限管理,申请以下 6 项权限:
    这样机器人可以在私聊和群聊中接受用户的消息,并且下载消息中的图片。

  1. 进入事件与回调,添加以下 1 个事件:
    接收消息 v2.0

    最后,发布您的应用版本,并联系自己飞书管理员审批通过。如果已经在测试企业中开发,则无需发布即可获取权限进行测试。

Claude3 开通步骤

Claude3 开启方法很简单,只需要按照下面步骤操作即可:

  1. 从 AWS 的 Console 搜索栏中输入 Bedrock,然后跳转到对应页面
  2. 在侧边栏选中“Model Access”,这时你会看到一系列在 Bedrock 上可以开启的模型
  3. 如果从来没有申请过,状态是 Available to request
  4. 接下来点击 Manage Model Access,在 Claude 对应的模型打勾提交即可
  5. 完成上述步骤后,你还需要给予一个账号 bedrockfullaccess 权限,并且开通 此账号 AWS 的 AKSK,后面的配置文件需要使用

CDK 使用

目前项目已经开源, 地址为(注意在 bedrock 分支下的 v3-larkbot 目录下)https://github.com/aws-samples/aws-serverless-openai-chatbot-demo/tree/bedrock/v3-larkbot

大家 clone 下来项目后,便可以开始用 CDK 的方式来安装上述方案。关于 CDK 是什么,以及如何使用,大家可以参考文章

项目使用的是 nodejs 环境,其安装步骤十分简单。

# install via node package manager
npm install -g aws-cdk

# verify the cdk version
cdk version

配置

在执行 cdk deploy 之前,我们需要在 cdkstack 目录下创建 .env 文件,其内容如下:

# 项目相关设置
DB_TABLE=lark_messages
START_CMD=/rs
# 飞书相关设置
LARK_APPID={LARK_APPID}
LARK_APP_SECRET={LARK_APP_SECRET}
LARK_TOKEN={LARK_TOKEN}
LARK_ENCRYPT_KEY={LARK_ENCRYPT_KEY}
# AWS 相关设置
AWS_AK={AWS_AK}
AWS_SK={AWS_SK}
AWS_REGION_CODE={AWS_REGION_CODE}
AWS_BEDROCK_CLAUDE_SONNET=anthropic.claude-3-sonnet-20240229-v1:0
AWS_CLAUDE_MAX_SEQ=10
## claude 系统提示词
AWS_CLAUDE_SYSTEM_PROMPT=所有的回答用中文
## 多模态图片提示词
AWS_CLAUDE_IMG_DESC_PROMPT=描述下图片内容
## 每日用户最大对话数量
AWS_CLAUDE_MAX_CHAT_QUOTA_PER_USER=1000

注意:针对 AWS AK/SK 部分,大家可以专门开启一个调用 Bedrock Claude 模型的账号,然后用它的 AK/SK 填写降低暴露的风险。

核心代码

调用 bedrock-runtime api

需要注意的是:在 claude3 中由于多模态的引入,其 API 从以前的 completion 模式转换成了 message 格式。如果我们之前用的是 anthropic sdk,需要参考如何从 completion 模式转换到 message 模式

考虑到这部分的工作量,我们使用的是 aws bedrock-runtime api,它统一封装成了 invokeModel 接口,我们只需要将 payload 进行调整即可。依赖的 npm 库:https://www.npmjs.com/package/@aws-sdk/client-bedrock-runtime

export const invokeClaude3 = async (messages) => {
  const client = new BedrockRuntimeClient({ 
    region: aws_region_code,
    credentials: {
      accessKeyId: {aws_ak},
      secretAccessKey: {aws_sk},
    },
  });

  const payload = {
    anthropic_version: "bedrock-2023-05-31",
    messages: messages,
    temperature: 0.7,
    top_p: 0.9,
    max_tokens: 2048,
  };

  const command = new InvokeModelCommand({
    body: JSON.stringify(payload),
    contentType: "application/json",
    accept: "application/json",
    modelId: 'anthropic.claude-3-sonnet-20240229-v1:0',
  });

  try {
    const response = await client.send(command);
    const decodedResponseBody = new TextDecoder().decode(response.body);

    /** @type {ResponseBody} */
    const responseBody = JSON.parse(decodedResponseBody);
    console.log(responseBody)
    return responseBody;
  } catch (err) {
    if (err instanceof AccessDeniedException) {
      console.error(
        `Access denied. Ensure you have the correct permissions to invoke ${aws_llm}.`,
      );
    } else {
      throw err;
    }
  }
};

飞书图片处理

依赖的 npm 库:https://www.npmjs.com/package/@larksuiteoapi/node-sdk

对于机器人对话上传的图片部分,通常它会返回一个 image_key。如果直接通过 im.v1.images.get 方式来获取,会报错 400,显示 invalid paramter。要解决这个问题,需要通过 messageResource 的方法来获取图片,这里给出参考代码:

const getLarkfile = async(message_id, filekey, type) =>{
  let resp;
  # lambda 需要将文件放在/tmp 目录下
  const tempFileName = `/tmp/${Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)}.png`
  try{
    resp = await larkclient.im.messageResource.get({
      path: {
        message_id: message_id,
        file_key: filekey,
      },
      params: {
        type: type,
      },
    });
    # 将图片文件转成 base64,供 claude3 多模态使用
    await resp.writeFile(tempFileName)
    const base64String = toBase64(tempFileName);
    const contents = [
      {
          type: "image",
          source: {
          type: "base64",
          media_type: "image/png",
          data: base64String,
          }
      },
      {type: "text", text: aws_claude_img_desc_words}]; 
      return {role:'user', content:contents};
  } catch (err) {
    console.error(err);
  } finally {
    # 最后我们需要删除临时文件
    fs.unlinkSync(tempFileName);
  }
}

内置的功能

/rs 清除当前对话记录包括 system prompt

/tc 统计 token 的使用情况

/sp 更新 system prompt 提示词

场景测试

我们可以去 Anthropic prompt library 去找到一些提示词模版来测试。根据不同的场景,可以调用/sp + 提示词的方式来设置 system prompt。这里 system prompt 是一种为 Claude 提供上下文、说明和指导的方式,在向它提出问题或任务之前使用。通过使用系统提示,您可以为对话设置基调,指定 Claude 的角色、个性、语气或任何其他相关信息,以帮助它更好地理解和响应用户的输入。系统提示可以包括:

  • 任务说明和目标
  • 个性特征、角色和语气指导 – 用户输入的上下文信息
  • 创造力限制和风格指导
  • 外部知识、数据或参考资料
  • 规则、指导方针和防护措施
  • 输出验证标准和要求

图片内容描述:

小红书写手:

这次我们使用如下 PE 模版:

你是小红书爆款写作专家,请你用以下步骤来进行创作,首先产出5个标题(含适当的emoji表情),
其次产出1个正文(每一个段落含有适当的emoji表情,文末有合适的tag标签)
一、在小红书标题方面,你会以下技能:
1. 采用二极管标题法进行创作
2. 你善于使用标题吸引人的特点
3. 你使用爆款关键词,写标题时,从这个列表中随机选1-2个
4. 你了解小红书平台的标题特性
5. 你懂得创作的规则
二、在小红书正文方面,你会以下技能:
1. 写作风格
2. 写作开篇方法
3. 文本结构
4. 互动引导方法
5. 一些小技巧
6. 爆炸词
7. 从你生成的稿子中,抽取3-6个seo关键词,生成#标签并放在文章最后
8. 文章的每句话都尽量口语化、简短
9. 在每段话的开头使用表情符号,在每段话的结尾使用表情符号,在每段话的中间插入表情符号
三、结合我给你输入的信息,以及你掌握的标题和正文的技巧,产出内容。请按照如下格式输出内容,
只需要格式描述的部分,如果产生其他内容则不输出:
一. 标题
[标题1到标题5]
[换行]
二. 正文
[正文]
标签:[标签]

费用

固定部分

由于我们使用无服务器架构,其中 API Gateway 每 1 百万次调用费用仅为 $1,而 Lambda 每月有 400,000GB-秒和 1 百万次请求的免费额度,对于一般企业的日常内部使用,这部分服务产生的费用将非常低。

具体可以参考官网价格:

lambda 部分:https://aws.amazon.com/lambda/pricing/?nc2=type_a

api-gateway 部分:https://aws.amazon.com/api-gateway/pricing

Token 部分

Token 部分按输入和输出部分分别计算,例如使用 Claude-3-Sonnet,每输入 1000 token 的费率是 $0.003,每输出 1000 token 的费率是 $0.015。

具体可参考官网的价格页面:https://aws.amazon.com/bedrock/pricing/

客户点评

AWS CDK 让 Claude3 与飞书无缝衔接,开箱即用,部署简单。通过飞书直接与 AI 助手对话,让获取信息或完成任务更加快捷。同时 AWS CDK 带来的便利也可以根据企业的具体需求进行各种工作流的定制。AWS Bedrock 与飞书集成 Claude 是一种创新的解决方案,将人工智能与企业生产力工具相结合,为企业带来全新的协作体验和效率提升。

总结

本文提出了使用 AWS CDK 的方法来将 Claude3 集成到飞书机器人中,这种方案开箱即用,十分适合快速构建和无门槛体验。借助 AWS CDK,开发者可以通过编程的方式配置和管理云资源,实现 Claude3 与飞书机器人的无缝集成。

作为技术前沿的探索者,所思科技在此案例中以开放的心态利用飞书 + Claude3 的模式,使其同时具有了强大的办公能力与全球领先的 LLM 模型加持,可以满足其数字化,智能化办公的需求。相信在不久的将来,这种 AI+ 的工作模式会成为标配,它会极大地解放个人的生产力。不必整日为各种“paper work”或者重复流程化工作而烦恼。

参考链接

飞书开放平台文档

https://open.feishu.cn/?lang=zh-CN

AnthropicClaude 消息 API

https://docs.aws.amazon.com/zh_cn/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html

本篇作者

刘宗超

所思科技全栈开发工程师,负责多项业务应用的全栈开发。拥有多个产品从 0 到 1 的研发经验。在新兴技术领域有着浓厚的兴趣,致力于拥抱大模型时代带来的信息便捷与全新的工作流体验。

万曦

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案的咨询和架构设计。坚实的 AWS Builder 文化拥抱者。拥有超过 12 年的游戏研发经验,参与过数个游戏项目的管理和开发,对于游戏行业有深度理解和见解。

谢川

亚马逊云科技 GenAI 高级解决方案架构师,负责基于亚马逊云的生成式人工智能解决方案的设计,实施和优化。曾在通信,电商,互联网等行业有多年的产研经验,在数据科学,推荐系统,LLM RAG 等方面有丰富的实践经验,并且拥有多个 AI 相关产品技术发明专利。