零服务器部署 AI 应用:Lambda + Bedrock 全流程实战记录
é›¶æœåŠ¡å™¨éƒ¨ç½² AI 应用:Lambda + Bedrock å
¨æµç¨‹å®žæˆ˜è®°å½•
折è
¾äº†ä¸¤å¤©ï¼Œç»ˆäºŽæŠŠä¸€å¥— Serverless AI 应用跑通了。从 Lambda 函数到 Bedrock 模型调用,踩了ä¸å°‘å‘,这里完整记录下æ¥ã€‚
为什么è¦ç”¨ Serverless æž AI
说实è¯ï¼Œä¸€å¼€å§‹æˆ‘也没想用 Lambda。我们团队有个需求——åšä¸€ä¸ªå†
部知识问ç”å·¥å
·ï¼Œç”¨å¤§æ¨¡åž‹æ¥å›žç”技术问题。最åˆçš„æƒ³æ³•是起个 EC2 è·‘ FastAPIï¼Œä½†ç®—äº†ä¸‹æˆæœ¬ï¼š
- 24 å°æ—¶æŒ‚ç€ EC2:就算用 t3.medium,一个月也è¦å‡ å美金
- 实é™
使用率:工作时间大概 8 å°æ—¶ï¼Œå‘¨æœ«åŸºæœ¬æ²¡äººç”¨ - 真æ£åœ¨å¤„ç†è¯·æ±‚的时间:å¯èƒ½ä¸€å¤©åŠ èµ·æ¥å°±å‡ 分钟
è¿™ä¸ªåˆ©ç”¨çŽ‡ä¹Ÿå¤ªä½Žäº†ã€‚åŽæ¥æƒ³åˆ° Lambda——按调用次数收费,没请求就是 $0,完美符åˆè¿™ä¸ªåœºæ™¯ã€‚
æŠ€æœ¯æž¶æž„é•¿ä»€ä¹ˆæ ·
整个链路å
¶å®žä¸å¤æ‚:
用户 → API Gateway → Lambda → Bedrock (Claude) → 返回结果
用到的亚马逊云科技æœåŠ¡ï¼š
- API Gateway:HTTP å
¥å£ï¼Œå¤„ç†è·¯ç”±å’Œè®¤è¯ - Lambda:业务逻辑,Python 3.12 runtime
- Bedrock:调用 Claude 3.5 Sonnet 模型
- IAM:æƒé™æŽ§åˆ¶ï¼ŒLambda 需è¦
bedrock:InvokeModelæƒé™
第一æ¥ï¼šå†™ Lambda 函数
å
ˆæŠŠæ ¸å¿ƒé€»è¾‘跑通。新建一个 lambda_function.py:
import json
import boto3
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
def lambda_handler(event, context):
# ä»Žè¯·æ±‚ä¸æ‹¿åˆ°ç”¨æˆ·é—®é¢˜
body = json.loads(event.get('body', '{}'))
question = body.get('question', '')
if not question:
return {
'statusCode': 400,
'body': json.dumps({'error': '问题ä¸èƒ½ä¸ºç©º'})
}
# 调用 Bedrock Claude
response = bedrock.invoke_model(
modelId='anthropic.claude-3-5-sonnet-20241022-v2:0',
contentType='application/json',
accept='application/json',
body=json.dumps({
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': 2048,
'messages': [
{
'role': 'user',
'content': question
}
]
})
)
result = json.loads(response['body'].read())
answer = result['content'][0]['text']
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({'answer': answer})
}
这段代ç å°±åšäº†ä¸‰ä»¶äº‹ï¼š
- 从 API Gateway ä¼ è¿‡æ¥çš„ event 里拿问题
- 调 Bedrock 的 Claude 模型
- 把回ç”返回去
第二æ¥ï¼šé
ç½® IAM æƒé™
Lambda 执行角色需è¦è¿™ä¸¤ä¸ªæƒé™ï¼š
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
这里有个å‘——Bedrock 模型的 ARN æ ¼å¼è·Ÿå
¶ä»–æœåŠ¡ä¸å¤ªä¸€æ ·ï¼Œè´¦å·é‚£æ®µæ˜¯ç©ºçš„(两个冒å·ä¹‹é—´æ²¡ä¸œè¥¿ï¼‰ã€‚第一次é
的时候写æˆäº† arn:aws:bedrock:us-east-1:123456789:foundation-model/...,结果一直报 AccessDenied,查了åŠå¤©æ‰å‘现。
第三æ¥ï¼šAPI Gateway 集æˆ
用 HTTP APIï¼ˆä¸æ˜¯ REST API),更便宜更快:
# 创建 HTTP API
aws apigatewayv2 create-api \
--name ai-qa-api \
--protocol-type HTTP
# 创建 Lambda 集æˆ
aws apigatewayv2 create-integration \
--api-id YOUR_API_ID \
--integration-type AWS_PROXY \
--integration-uri arn:aws:lambda:us-east-1:ACCOUNT:function:ai-qa \
--payload-format-version 2.0
# 创建路由
aws apigatewayv2 create-route \
--api-id YOUR_API_ID \
--route-key "POST /ask"
踩å‘记录
å‘ 1:Lambda è¶
æ—¶
Lambda 默认è¶
时是 3 秒,但 Bedrock è°ƒ Claude 一次å“应å¯èƒ½è¦ 5-15 秒。第一次测试直接è¶
时了。
解决:把 Lambda è¶
æ—¶æ”¹æˆ 30 ç§’ã€‚åœ¨æŽ§åˆ¶å°æ”¹æˆ–è€
用 CLI:
aws lambda update-function-configuration \
--function-name ai-qa \
--timeout 30
å‘ 2:冷å¯åŠ¨å»¶è¿Ÿ
Lambda 冷å¯åЍ + Bedrock 首次调用,第一次请求å¯èƒ½è¦ç‰ 10+ 秒。åŽé¢å°±æ£å¸¸äº†ã€‚
解决方案:
- é
ç½® Provisioned Concurrency(预置并å‘ï¼‰ï¼Œä¿æŒå‡ ä¸ªå®žä¾‹å¸¸çƒ - 或è€
用 CloudWatch Events 定时 pingï¼Œä¿æŒå‡½æ•°æ¸©çƒ
aws lambda put-provisioned-concurrency-config \
--function-name ai-qa \
--qualifier prod \
--provisioned-concurrent-executions 2
å‘ 3:返回体大å°é™åˆ¶
API Gateway åŒæ¥å“åº”ä¸Šé™ 10MB,Lambda è¿”å›žä¸Šé™ 6MBã€‚ä¸€èˆ¬é—®ç”æ²¡é—®é¢˜ï¼Œä½†å¦‚果让模型生æˆé•¿æ–‡ï¼Œè¦æ³¨æ„这个é™åˆ¶ã€‚
å‘ 4:Bedrock 区域
䏿˜¯æ‰€æœ‰åŒºåŸŸéƒ½æ”¯æŒ Bedrockã€‚ç›®å‰ us-east-1 å’Œ us-west-2 模型最å
¨ã€‚å¦‚æžœä½ çš„ Lambda 在东京(ap-northeast-1),需è¦è·¨åŒºåŸŸè°ƒç”¨ Bedrock:
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
è·¨åŒºåŸŸè°ƒç”¨ä¼šå¢žåŠ 50-100ms 延迟,但对于 AI 应用æ¥è¯´è¿™ä¸ªå»¶è¿ŸåŸºæœ¬å¯ä»¥å¿½ç•¥ã€‚
æˆæœ¬å¯¹æ¯”
跑了一个月,实é™
æ•°æ®ï¼š
| 方案 | æœˆæˆæœ¬ |
|---|---|
| EC2 t3.medium 24/7 | ~$30 |
| Lambda + API Gateway | ~$3 |
Lambda 方案çœäº† 90%ã€‚å½“ç„¶ï¼Œå¦‚æžœä½ çš„ QPS 很高(比如æ¯ç§’上百次请求),Lambda å而å¯èƒ½æ›´è´µã€‚按需选择就好。
Lambda 计费逻辑:
- æ¯æœˆå‰ 100 万次请求å
è´¹ - ä¹‹åŽ $0.20/百万次
- å†
å˜æŒ‰ GB-秒计费:$0.0000166667/GB-ç§’
以 256MB å†
å˜ã€å¹³å‡æ‰§è¡Œ 5 ç§’æ¥ç®—:
- æ¯æ¬¡è°ƒç”¨æˆæœ¬ ≈ $0.0000208
- 一天 100 次 = $0.002
- 一个月 ≈ $0.06
Bedrock 调用费是å¦ç®—的(按 token 计费),这里ä¸å±•开。
进阶:æµå¼å“应
ç”¨æˆ·ç‰ 10 秒看到完整回ç”,体验ä¸å¥½ã€‚æ”¹æˆæµå¼å“应,边生æˆè¾¹è¿”回:
def lambda_handler(event, context):
body = json.loads(event.get('body', '{}'))
question = body.get('question', '')
response = bedrock.invoke_model_with_response_stream(
modelId='anthropic.claude-3-5-sonnet-20241022-v2:0',
contentType='application/json',
accept='application/json',
body=json.dumps({
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': 2048,
'messages': [{'role': 'user', 'content': question}]
})
)
# æµå¼å¤„ç†éœ€è¦ Lambda Response Streaming
chunks = []
for event_chunk in response['body']:
chunk = json.loads(event_chunk['chunk']['bytes'])
if chunk['type'] == 'content_block_delta':
chunks.append(chunk['delta']['text'])
return {
'statusCode': 200,
'body': json.dumps({'answer': ''.join(chunks)})
}
真æ£çš„æµå¼éœ€è¦é
åˆ Lambda Response Streaming(函数 URL + RESPONSE_STREAM)或 WebSocket API。上é¢çš„å†™æ³•åªæ˜¯æŠŠæµå¼æŽ¥æ”¶åˆ°çš„å†
容拼起æ¥ä¸€æ¬¡è¿”回,适åˆç®€å•场景。
总结
Lambda + Bedrock æ AI åº”ç”¨ï¼Œæ ¸å¿ƒä¼˜åŠ¿å°±ä¸€ä¸ªå—:çœã€‚çœé’±ï¼ˆæŒ‰è°ƒç”¨è®¡è´¹ï¼‰ã€çœå¿ƒï¼ˆä¸ç”¨ç®¡æœåŠ¡å™¨ï¼‰ã€çœæ—¶ï¼ˆå‡ 个文件就能部署)。
适åˆçš„场景:
- å†
部工å
·ã€é—®ç”机器人 - 低频调用的 AI 功能(比如æ¯å¤©å‡ 百次)
- 原型验è¯ã€å¿«é€Ÿä¸Šçº¿
ä¸é€‚åˆçš„场景:
- 高并å‘实时对è¯ï¼ˆWebSocket 场景建议用 ECS/EKS)
- éœ€è¦ GPU 推ç†çš„自定义模型
å¦‚æžœä½ ä¹Ÿåœ¨è€ƒè™‘æ€Žä¹ˆä½Žæˆæœ¬ä¸Šçº¿ä¸€ä¸ª AI 功能,Lambda + Bedrock å¯ä»¥è¯•试。
📌 完整代ç å’Œ CloudFormation æ¨¡æ¿æˆ‘放在文末,有需è¦çš„直接拿走。所有代ç 基于亚马逊云科技 Lambda Python 3.12 è¿è¡Œæ—¶æµ‹è¯•通过。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)