当前位置: 首页 > news >正文

基于Amazon Bedrock构建AI智能体:从提示词工程到工具调用的实践指南

1. 项目概述从零开始用Amazon Bedrock构建你的第一个AI智能体如果你对生成式AI充满好奇看着ChatGPT、Midjourney这些工具觉得神奇但又觉得它们像是“黑盒子”不知道如何将其能力整合到自己的应用或工作流中那么你找对地方了。今天我们不谈那些遥不可及的算法也不讲复杂的模型训练我们就从一个最实际的问题出发如何亲手搭建一个能理解你、并为你完成特定任务的AI智能体这个问题的答案就藏在Amazon Bedrock里。简单来说Bedrock不是一个单一的AI模型而是一个“AI模型超市”兼“开发工具箱”。它把Anthropic的Claude、Meta的Llama、Cohere的Command等业界顶尖的大语言模型LLM以及图像生成模型以API服务的形式提供给你。你不需要操心动辄数百GB的模型文件怎么下载也不用担心需要价值数万美元的GPU来运行更不用从零开始学习如何调优一个万亿参数的大模型。Bedrock让你能像调用任何其他云服务一样直接使用这些强大的AI能力。本教程的目标非常明确带领一位完全的初学者从写下第一个提示词Prompt开始步步为营最终构建出一个能自动处理任务的AI智能体。我们将使用Bedrock中最易上手的Claude模型因为它以强大的逻辑推理和指令遵循能力著称非常适合新手。整个旅程你将亲身体验如何将一段简单的文本对话升级为一个可以集成到网站、内部系统或自动化脚本中的“智能员工”。无论你是开发者、产品经理、业务分析师还是创业者这篇手把手的指南都将为你打开一扇通往AI应用开发的大门。2. 核心概念与Bedrock环境初探在开始敲代码之前我们必须先统一“语言”理解几个核心概念并准备好我们的“数字工作台”——AWS环境。2.1 关键概念解析提示词、模型与智能体提示词Prompt这是你与AI模型沟通的全部指令。你可以把它想象成给一位非常聪明但缺乏背景知识的实习生下达的工作说明。一个糟糕的提示词如“总结一下”模型可能不知所云。而一个好的提示词会遵循“角色-任务-上下文-格式”的结构例如“你是一位专业的科技文章编辑请将下面这篇关于云计算的博客草稿总结成一份不超过200字的要点列表面向CEO阅读突出成本与效率收益。”大语言模型LLM如Claude、Llama它们是经过海量文本训练而成的“大脑”能够理解提示词并生成连贯、相关的文本回复。在Bedrock中你通过选择不同的模型来获得不同的“性格”和能力倾向比如有些更擅长创意写作有些更精于代码生成。AI智能体AI Agent这是我们的终极目标。一个智能体不仅仅是能回答问题的聊天机器人。它是一个具备目标导向、能自主规划步骤、调用工具API、并持续执行直到完成任务的系统。例如一个“智能客服工单处理Agent”在收到用户描述的问题后会自主决定先调用知识库API搜索解决方案若未找到则调用创建工单API并自动填写分类、优先级和问题摘要。Amazon Bedrock扮演的角色就是让构建这样的智能体变得可行。它提供了模型API、知识库集成、以及工作流编排能力将复杂的AI系统工程简化为可配置、可组合的服务。2.2 AWS环境准备与Bedrock启用首先你需要一个AWS账户。如果还没有可以去AWS官网注册新用户通常有一定额度的免费资源。登录AWS管理控制台后请按以下步骤操作区域选择在控制台右上角选择一个已支持Amazon Bedrock服务的区域例如“美国东部弗吉尼亚北部us-east-1”或“亚太地区新加坡ap-southeast-1”。这是关键一步Bedrock并非在所有区域开放。搜索并进入Bedrock在控制台顶部的服务搜索栏中输入“Bedrock”并进入该服务。模型访问请求首次进入Bedrock你可能会看到模型列表显示为“未授予访问权限”。出于合规和负责任AI的考虑AWS默认不开放所有模型。你需要手动申请访问。点击“模型访问”或类似标签页找到你想要的模型例如“Anthropic Claude 3 Sonnet”点击“请求模型访问”。申请理由可以填写“学习与测试AI智能体开发”通常几分钟到几小时内就会获批。创建IAM用户与密钥安全最佳实践绝对不建议直接使用根账户的密钥进行开发。我们应该创建一个具有编程访问权限的IAM用户。在AWS控制台搜索“IAM”。在“用户”页面点击“创建用户”。输入用户名例如bedrock-tutorial-user。在“选择凭证类型”中勾选“访问密钥 - 编程访问”。在权限设置中点击“直接附加现有策略”搜索并选择AmazonBedrockFullAccess策略为简化教程我们授予完整权限。在生产环境中应根据最小权限原则创建自定义策略。完成用户创建后务必立即下载或复制保存生成的“访问密钥ID”和“秘密访问密钥”。这串密钥对只会显示一次丢失后需要重新生成。本地环境配置在你的开发机器上安装AWS CLI并通过aws configure命令输入上一步获得的密钥、区域如us-east-1和默认输出格式如json。这将为后续的SDK调用提供认证凭证。注意保管好你的秘密访问密钥如同保管密码。切勿将其提交到Git等代码仓库中。一个常见的做法是使用环境变量或AWS的密钥管理服务来安全地处理它们。3. 第一步与Claude进行第一次对话现在让我们真正开始与AI对话。我们将使用AWS SDK for Python (Boto3) 来调用Bedrock API。如果你更熟悉JavaScript/Node.js其逻辑也完全相通。3.1 安装依赖与基础调用脚本首先确保你的Python环境已安装boto3库。在终端中运行pip install boto3接下来创建一个名为first_conversation.py的文件写入以下代码import json import boto3 from botocore.config import Config # 创建Bedrock运行时客户端明确指定区域 bedrock_runtime boto3.client( service_namebedrock-runtime, region_nameus-east-1, # 请替换为你申请模型的区域 configConfig(read_timeout300) # 设置较长的超时时间因为模型推理可能需要时间 ) # 定义我们的第一个提示词 prompt Human: 你好Claude。请用中文简单介绍一下你自己并告诉我你最擅长做什么。 Assistant: # 构造请求体这里我们使用Claude模型约定的消息格式 body json.dumps({ anthropic_version: bedrock-2023-05-31, max_tokens: 1000, messages: [ { role: user, content: [{type: text, text: prompt}] } ] }) # 指定模型ID model_id anthropic.claude-3-sonnet-20240229-v1:0 try: # 调用模型 response bedrock_runtime.invoke_model( bodybody, modelIdmodel_id ) # 解析响应 response_body json.loads(response.get(body).read()) # Claude的响应在 content 字段中 output_text response_body[content][0][text] print(Claude 的回答) print(output_text) except Exception as e: print(f调用失败: {e})运行这个脚本 (python first_conversation.py)你应该会收到Claude一段礼貌的自我介绍。恭喜你你已经成功通过代码调用了世界顶级的AI模型这看似简单的一步是后面所有复杂应用的基础。3.2 理解请求与响应消息格式与参数让我们拆解一下上面代码中的关键部分bedrock-runtime客户端我们使用它来调用模型的“推理”功能即发送提示词并获取回复。请求体Body这是与模型沟通的核心协议。不同模型的请求体格式可能不同。对于Claude我们使用了Anthropic Messages API格式。其中max_tokens: 限制模型回复的最大长度约等于单词数。设置一个合理的值可以控制成本Bedrock按输入输出总Token数计费和响应时间。messages: 一个包含对话历史的列表。每条消息都有role“user”或“assistant”和content。这种结构使得进行多轮对话变得非常容易。模型ID每个模型在Bedrock中都有唯一的ID。你可以在Bedrock控制台的“Playground”或文档里找到所有可用的模型ID。实操心得在开发初期强烈建议使用Bedrock控制台内置的Playground。它提供了一个交互式界面让你可以可视化地调整提示词、系统指令System Prompt、温度Temperature等参数并立即看到效果而无需反复修改和运行代码。调试好提示词后再将配置迁移到代码中效率倍增。4. 进阶构建一个任务规划与执行智能体现在我们不再满足于单次问答。我们要创建一个能处理复杂任务的智能体。假设我们想构建一个“旅行规划助手”它的任务是根据用户模糊的需求生成一个结构化的旅行计划。4.1 设计系统提示词与任务拆解智能体的“大脑”和“性格”由系统提示词System Prompt决定。它会在用户对话开始前被注入模型设定上下文、角色和行为准则。创建一个新文件travel_agent.py我们先定义核心的系统提示词SYSTEM_PROMPT 你是一个专业、细心且富有创见的旅行规划专家名为“途悦助手”。你的核心职责是帮助用户制定详细、可行且个性化的旅行计划。 你必须遵循以下工作流程 1. **需求澄清**用户最初的需求可能很模糊如“我想去个暖和的地方玩几天”。你必须通过提问主动澄清以下关键信息 - 旅行时间几月、周末/工作日、具体天数 - 出发城市/国家 - 旅行预算范围经济/舒适/奢侈 - 旅行者类型独自/情侣/家庭/朋友是否有老人小孩 - 兴趣偏好自然风光/城市人文/美食购物/冒险运动/休闲放松 - 任何特殊要求如签证、无障碍设施、宠物友好 2. **计划生成**在获得足够信息后生成一份结构化的旅行计划必须包含 - **目的地建议**给出1-3个具体目的地选项并简述推荐理由。 - **每日行程**按天编排包含上午、下午、晚上的活动建议活动之间预留合理的交通和休息时间。 - **预算估算**对机票、住宿、餐饮、门票、交通进行分项粗略估算并给出总预算区间。 - **行前准备清单**列出签证、衣物、药品、必备APP等物品。 - **备选方案**为可能出现的天气变化或突发情况如景点关闭提供备选活动。 3. **输出格式**你的最终计划请用清晰的Markdown格式输出并使用适当的标题##、###和列表来组织内容使其易于阅读。 请记住在用户未提供完整信息前不要急于生成完整计划。优先通过提问来收集信息。每次回复请保持友好、热情且专业的口吻。 这个系统提示词定义了智能体的角色、工作流程、输出规范。一个好的系统提示词是智能体成功的一半。4.2 实现多轮对话与状态管理智能体需要记住对话历史。我们将实现一个简单的对话循环。import json import boto3 from botocore.config import Config class TravelPlanningAgent: def __init__(self): self.bedrock_runtime boto3.client(bedrock-runtime, region_nameus-east-1) self.model_id anthropic.claude-3-sonnet-20240229-v1:0 self.conversation_history [ { role: system, content: [{type: text, text: SYSTEM_PROMPT}] } ] def add_user_message(self, text): 添加用户消息到历史记录 self.conversation_history.append({ role: user, content: [{type: text, text: text}] }) def get_agent_response(self): 调用模型获取助手回复并自动将回复加入历史 # 构建请求体这次我们发送整个对话历史 body json.dumps({ anthropic_version: bedrock-2023-05-31, max_tokens: 2000, messages: self.conversation_history }) try: response self.bedrock_runtime.invoke_model( bodybody, modelIdself.model_id ) response_body json.loads(response.get(body).read()) assistant_message response_body[content][0][text] # 将模型的回复也加入历史以维持对话上下文 self.conversation_history.append({ role: assistant, content: [{type: text, text: assistant_message}] }) return assistant_message except Exception as e: return f抱歉规划助手暂时出了点问题: {e} def run_conversation(self): 运行一个简单的命令行对话循环 print(途悦旅行规划助手已启动请输入您的旅行需求例如我想在国庆节期间出去玩输入退出结束。) print(- * 50) while True: user_input input(\n您: ) if user_input.lower() in [退出, exit, quit]: print(感谢使用途悦助手祝您旅途愉快) break self.add_user_message(user_input) print(\n助手正在思考...) response self.get_agent_response() print(f\n途悦助手: {response}) # 运行智能体 if __name__ __main__: agent TravelPlanningAgent() agent.run_conversation()运行这个脚本你就可以在终端里与你的旅行规划智能体对话了。它会按照系统提示词的要求先向你提问澄清需求待信息齐全后生成一份详细的Markdown格式旅行计划。注意事项这个简单的状态管理conversation_history在单次会话中有效。对于Web应用你需要为每个用户会话单独维护一个历史记录对象通常存储在数据库或缓存中如Redis。同时历史记录会消耗Token成本会随对话轮次增加过长的历史也可能触及模型的上下文窗口限制Claude 3 Sonnet约20万Token。对于超长对话需要考虑摘要历史或采用更高级的“记忆”管理策略。5. 从对话到智能体集成外部工具与知识真正的智能体不仅能说还能“做”。它需要能调用外部工具API来获取实时信息或执行操作。例如我们的旅行助手如果能查询实时天气、机票价格或酒店空房计划将更具实用性。Bedrock通过“工具调用Tool Use”功能来支持这一点。5.1 为Claude定义可用的工具我们将为智能体增加两个工具get_weather获取天气和search_flights搜索航班。首先我们需要以模型能理解的格式描述这些工具。更新TravelPlanningAgent类的初始化部分定义工具列表self.tools [ { name: get_weather, description: 根据城市名称和日期查询该地点的天气预报信息。, input_schema: { type: object, properties: { city: { type: string, description: 城市名称例如北京、东京、纽约 }, date: { type: string, description: 查询的日期格式为YYYY-MM-DD。默认为未来三天内。 } }, required: [city] } }, { name: search_flights, description: 根据出发地、目的地和日期搜索航班选项。, input_schema: { type: object, properties: { departure_city: { type: string, description: 出发城市机场代码或名称例如PEK北京首都 NYC纽约 }, arrival_city: { type: string, description: 到达城市机场代码或名称 }, departure_date: { type: string, description: 出发日期格式为YYYY-MM-DD } }, required: [departure_city, arrival_city, departure_date] } } ]5.2 实现工具调用与响应处理循环现在我们需要修改get_agent_response方法使其能够处理模型提出的工具调用请求。这涉及到一个循环模型可能返回普通文本也可能返回一个“我想调用某个工具”的请求我们需要执行工具并将结果返回给模型让它继续思考。def get_agent_response(self): 调用模型处理可能的工具调用请求 max_turns 5 # 防止无限循环限制工具调用轮次 for turn in range(max_turns): # 构建请求这次包含工具定义 body json.dumps({ anthropic_version: bedrock-2023-05-31, max_tokens: 2000, tools: self.tools, messages: self.conversation_history }) try: response self.bedrock_runtime.invoke_model(bodybody, modelIdself.model_id) response_body json.loads(response.get(body).read()) # 检查响应内容 for content_block in response_body[content]: if content_block[type] text: # 普通文本回复直接返回 assistant_message content_block[text] self.conversation_history.append({ role: assistant, content: [{type: text, text: assistant_message}] }) return assistant_message elif content_block[type] tool_use: # 模型请求使用工具 tool_name content_block[name] tool_input content_block[input] tool_call_id content_block[id] print(f\n[助手决定调用工具: {tool_name} 参数: {tool_input}]) # 执行对应的工具函数 tool_result self.execute_tool(tool_name, tool_input) # 将工具执行结果作为新的消息追加到历史中供模型继续使用 self.conversation_history.append({ role: assistant, content: [content_block] # 包含工具调用请求 }) self.conversation_history.append({ role: user, content: [{ type: tool_result, tool_use_id: tool_call_id, content: tool_result }] }) # 工具调用后跳出本次回复进入下一轮循环让模型基于工具结果继续思考 break else: # 如果循环正常结束没有break说明没有工具调用直接返回文本 # 这里需要处理可能没有文本块的情况理论上不会发生 return 未收到有效回复。 except Exception as e: return f调用过程出错: {e} return 工具调用轮次过多已终止。 def execute_tool(self, tool_name, tool_input): 模拟执行工具并返回结果。在实际应用中这里应调用真实的API。 if tool_name get_weather: city tool_input.get(city, 未知城市) date tool_input.get(date, 近期) # 模拟API返回 return f模拟数据{date}城市{city}的天气预计为晴朗气温20-28摄氏度微风。适宜出行。 elif tool_name search_flights: dep tool_input.get(departure_city) arr tool_input.get(arrival_city) date tool_input.get(departure_date) # 模拟API返回 return f模拟数据找到从{dep}到{arr}在{date}的航班。最早一班为08:00起飞经济舱价格约1200元起。 else: return f错误未知工具 {tool_name}现在当你再次运行智能体并提到具体目的地和日期时它可能会主动说“让我先为您查询一下那里的天气情况。” 随后在后台它会调用get_weather工具获取模拟的天气数据并基于此数据优化它的旅行建议例如“天气晴朗我建议您增加户外活动”。实操心得工具调用是构建实用智能体的关键。在设计工具时描述description和参数模式input_schema必须清晰准确这直接决定了模型能否正确理解和使用它。初期可以先使用模拟函数Stub快速验证逻辑待流程跑通后再替换为真实的第三方API如航司、天气服务商或内部系统接口。6. 生产级考量安全、成本与部署一个能在实验环境运行的智能体与一个能投入生产使用的服务之间还存在一些必须跨越的鸿沟。6.1 安全与内容过滤生成式AI可能产生不受控的输出。Bedrock提供了内置的内容安全过滤器。你可以在调用invoke_model时在请求体中配置guardrailIdentifier来应用预定义的护栏策略或者在Bedrock控制台中创建自定义护栏过滤暴力、仇恨、性暗示或隐私信息等内容。# 在请求体中可添加护栏配置假设你已创建了护栏并获取了其ID body json.dumps({ anthropic_version: bedrock-2023-05-31, max_tokens: 1000, messages: [...], guardrail: { identifier: your-guardrail-id, version: DRAFT # 或具体的版本号 } })此外对于处理用户输入永远要遵循最小权限原则。智能体调用的工具API其权限应被严格限制。例如一个“邮件总结助手”不应该有权限通过工具发送邮件。6.2 成本监控与优化Bedrock按Token输入输出计费不同模型单价不同。Claude 3 Sonnet比Haiku贵但能力更强。优化成本的方法包括缓存Caching对相同或相似的提示词和上下文缓存模型的输出结果避免重复计算。提示词工程精简你的系统提示词和用户输入去除不必要的修饰语。设置Token上限合理设置max_tokens避免模型生成冗长无关的内容。使用更经济的模型对于简单任务可以使用Claude 3 Haiku这类更轻量、更便宜的模型。启用Bedrock的按请求跟踪在AWS Cost Explorer中你可以通过标签或使用Bedrock的计量功能详细监控每个应用、每个模型的调用成本。6.3 部署模式与架构建议一个简单的生产架构可能如下前端一个Web应用如React/Vue或聊天界面。后端API使用AWS Lambda无服务器函数或Amazon ECS/Fargate容器服务来运行我们上面编写的智能体逻辑。Lambda非常适合突发、无状态的对话请求。会话状态管理使用Amazon DynamoDBNoSQL数据库或ElastiCacheRedis来存储每个用户会话的conversation_history。键可以是user_id:session_id。工具API集成在Lambda函数或单独的微服务中实现调用真实天气、航班、酒店等第三方API的逻辑。使用AWS Secrets Manager安全地存储API密钥。异步处理对于耗时的任务如生成长篇报告可以让智能体发起一个异步工作流通过Amazon Step Functions进行编排完成后通过WebSocket或轮询通知前端。6.4 常见问题与排查技巧实录在实际操作中你几乎一定会遇到下面这些问题。这里是我的实战记录问题现象可能原因排查步骤与解决方案调用API返回AccessDeniedException1. IAM用户/角色没有Bedrock权限。2. 未在目标区域申请模型访问。3. 凭证配置错误。1. 检查IAM策略是否已附加AmazonBedrockFullAccess或相应权限。2. 登录Bedrock控制台确认当前区域下目标模型状态为“已授予访问权限”。3. 运行aws sts get-caller-identity确认当前CLI凭证身份和区域。模型响应慢或超时1. 提示词过长或max_tokens设置过高。2. 模型负载高。3. 网络延迟。1. 优化提示词减少不必要内容。设置合理的max_tokens。2. 在boto3.client初始化时增加read_timeout和connect_timeout参数。3. 考虑使用响应更快的模型变体如Haiku或启用流式响应以提升感知速度。模型输出不符合预期胡言乱语或拒绝回答1. 系统提示词定义不清或冲突。2. 温度Temperature参数过高导致随机性大。3. 对话历史混乱包含矛盾信息。1. 在Playground中反复调试系统提示词确保指令清晰、无歧义。使用“思考链”Chain-of-Thought风格提示词引导模型。2. 在请求体中尝试添加temperature: 0.5值越低输出越确定越高越有创造性。3. 清理或重置对话历史。对于长对话尝试让模型自己总结之前的上下文。工具调用不触发或参数错误1. 工具描述不够清晰。2. 输入模式Schema定义太严格或太宽松。3. 模型当前上下文不足以决定调用工具。1. 用更详细、具体的语言重写工具description说明何时、为何使用此工具。2. 检查input_schema确保required字段合理properties的描述能帮助模型理解参数格式如“日期格式为YYYY-MM-DD”。3. 在用户消息中提供更明确的、包含工具所需参数的信息。成本增长过快1. 对话历史未清理每次请求Token数累积。2. 频繁调用大模型处理简单任务。1. 实现对话历史摘要功能当历史达到一定长度让模型生成一个简短摘要然后用摘要替换旧历史。2. 引入路由逻辑简单查询如FAQ先用关键词匹配或小模型处理复杂任务再交给Claude等大模型。最后再分享一个小技巧在开发初期不要急于追求完美的智能体。采用“快速迭代”的方式先构建一个能跑通核心流程的最小可行产品MVP比如一个能进行三轮对话并调用一次工具的智能体。然后带着这个MVP去找目标用户哪怕是同事试用收集反馈。你会发现最大的挑战往往不是技术实现而是如何设计提示词和工具让智能体的行为更符合用户的直觉和预期。这个过程本身就是一个与AI协作、不断学习和调优的旅程而这正是构建AI应用最迷人的部分。
http://www.gsyq.cn/news/1408787.html

相关文章:

  • 构建有记忆的AI支持代理:基于会话状态追踪与动态升级的工程实践
  • 2026年 沈阳一站式注册公司榜单:小规模/一般纳税人/无地址注册与创业全流程解析 - 品牌企业推荐师(官方)
  • 避坑指南:在Unity中为Windows构建包实现窗口比例锁定时,你可能会遇到的5个问题及解决方法
  • 【RT-DETR实战】081、关键点检测与目标检测联合任务探索:当RT-DETR遇上多任务推理
  • MapLibre GL JS第5课:显示卫星地图
  • 从Simulink模型到C代码:嵌入式实时系统开发实战
  • 从Linux到SPDK:NVMe Namespace的创建、绑定与高性能存储实践
  • 2026年5月热门的南京洁净室翻新公司有哪些厂家推荐榜,净化板修复/无尘车间翻新/GMP车间维护/洁净室密封优化厂家选择指南 - 海棠依旧大
  • RIS极化自适应:基于CBC的动态分集与波束赋形切换算法
  • p-Bit非理想特性对组合优化与概率逻辑计算的影响与设计指南
  • Python核心语法分类详解:从入门到精通
  • 2026现阶段广西农业轮胎市场格局与优质服务商综合指南 - 2026年企业资讯
  • 贝叶斯网络中四种近似推理方法 CS188 Note15 学习笔记
  • AI原生网站构建:智能体与MCP工具协同架构实战
  • 13 - 异常处理
  • 2026年上海/贵阳门窗厂家推荐榜单:系统门窗、平开/推拉门窗品质与工艺深度解析 - 品牌企业推荐师(官方)
  • Redis Lua脚本深度解析
  • Redis主从复制深度解析
  • 深度解析RePKG:5个实战场景与架构设计原理
  • 避坑指南:Unity打包Windows可执行文件后,窗口自由缩放与比例锁定的完整配置流程
  • 学术创作提速新思路:okbiye 智能论文撰写模块,适配高校全品类论文创作需求
  • 分布式缓存策略:提升应用性能和扩展性
  • 空间尺度不匹配难题:基于块聚合与INLA的高效贝叶斯空间分解模型
  • Linux内核调试实战:用tracepoint、perf和bpftrace三件套精准定位性能瓶颈
  • Win10系统下3ds Max 2021完整安装与激活指南(附百度网盘资源)
  • 别再让数据冗余拖慢你的模型!用Python手把手教你粗糙集属性约简(附完整代码)
  • 2026必刷Java面试八股文整理公开!
  • 2026年广告物料制作厂家推荐榜:写真/KT板/PVC板/雕刻/条幅/车贴/喷绘加工优质品牌深度解析 - 品牌企业推荐师(官方)
  • 企业AI落地关键:推理可视化让可解释性从“加分项”变“必需品
  • 使用Nodejs与Taotoken构建一个轻量级AI助手后端服务