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

基于fastAPI--- 对接oss

1、解决如果上传文件或图片节省token

搭建服务端对接OSS

1设置 apikey

访问链接:https://ram.console.aliyun.com/overview?activeTab=workflow,进入RAM访问控制页面

创建好后点开用户进行权限配置

2、使用oss---创建桶

访问链接:https://oss.console.aliyun.com/overview,进入oss控制台,选择创建Bucket

输入名字其余默认

测试完后记得复原---实际开发不用关闭安全

最后,我们需要把阿里云OSS的API_KEY配置到环境变量中,也就是项目的.env文件内,格式如下:

# 阿里OSS OSS_ACCESS_KEY_ID= OSS_ACCESS_KEY_SECRET= OSS_BUCKET=tmp9527

3、智能体的最终修改

from langchain.chat_models import init_chat_model from langchain_tavily import TavilySearch from langchain.agents import create_agent import os from langgraph.checkpoint.sqlite import SqliteSaver import sqlite3 # 1.加载环境变量 from dotenv import load_dotenv load_dotenv() # 2.web搜索工具,使用tavily作为web搜索工具 web_search = TavilySearch( max_results=5, topic="general" ) # 3.多模态模型 model = init_chat_model( model="qwen3.5-plus", # 模型名称,这里选择qwen3.5-plus,这是一个多模态模型,支持图片、文本、音频、视频 model_provider="openai", base_url=os.getenv("DASHSCOPE_BASE_URL"), api_key=os.getenv("DASHSCOPE_API_KEY") ) # 4.初始化checkpointer # 连接sqlite connection = sqlite3.connect("../db/personal_chief.db", check_same_thread=False) # 初始化checkpointer checkpointer = SqliteSaver(connection) # 自动建表 checkpointer.setup() # 5.Agent系统提示词 system_prompt = """ 你是一名私人厨师。收到用户提供的食材照片或清单后,请按以下流程操作: 1.识别和评估食材:若用户提供照片,首先辨识所有可见食材。基于食材的外观状态,评估其新鲜度与可用量,整理出一份“当前可用食材清单”。 2.智能食谱检索:优先调用 web_search 工具,以“可用食材清单”为核心关键词,查找可行菜谱。 3.多维度评估与排序:从营养价值和制作难度两个维度对检索到的候选食谱进行量化打分,并根据得分排序,制作简单且营养丰富的排名靠前。 4.结构化方案输出:把排序后的食谱整理为一份结构清晰的建议报告,要包含食谱信息、得分、推荐理由、食谱的参考图片,帮助用户快速做出决策。 请严格按照流程,优先调用 web_search 工具搜索食谱,搜索不到的情况下才能自己发挥。 """ # 6.创建Agent agent = create_agent( model=model, # 模型 tools=[web_search], # 工具 checkpointer=checkpointer, # 记忆 system_prompt=system_prompt # 系统提示词 ) ================================================================================== # 流式对话 async def search_recipes(prompt: str, image: str, thread_id: str): """调用agent搜索食谱""" logger.info(f"[用户]: {prompt}, image: {image}, thread_id: {thread_id}") try: # 判断是否有图片,封装不同格式的消息 if not image or image.strip() == "": message = HumanMessage(content=prompt) else: message = HumanMessage(content=[ {"type": "image", "url": image}, {"type": "text", "text": prompt} ]) # 流式调用Agent for chunk, metadata in agent.stream( {"messages": [message]}, {"configurable": {"thread_id": thread_id}}, stream_mode="messages" ): if isinstance(chunk, AIMessageChunk) and chunk.content: yield chunk.content except Exception as e: logger.error(f"\n[错误]: {str(e)}") yield "信息检索失败,试试看手动输入食物列表?" # 清空会话 def clear_messages(thread_id: str): """清空会话""" logger.info(f"清空历史消息,thread_id: {thread_id}") checkpointer.delete_thread(thread_id) # 查询会话历史 def get_messages(thread_id: str) -> list[dict[str, str]]: """获取会话历史""" logger.info(f"获取历史消息,thread_id: {thread_id}") # 根据 thread_id 查询 checkpoint checkpoint = checkpointer.get({"configurable": {"thread_id": thread_id}}) # 如果不存在,返回空列表 if not checkpoint: return [] # 安全获取 messages channel_values = checkpoint.get("channel_values") if not channel_values: return [] messages = channel_values.get("messages", []) if not messages: return [] # 转换消息格式 result = [] for msg in messages: if not msg.content: continue if isinstance(msg, HumanMessage): result.append({"role": "user", "content": msg.content}) elif isinstance(msg, AIMessage): result.append({"role": "assistant", "content": msg.content}) return result

4、编写FastAPI

from fastapi import APIRouter from app.models.schemas import ChatRequest from fastapi.responses import StreamingResponse # StreamingResponse 异步调用 from app.agents.personal_chief import search_recipes, get_messages, clear_messages router = APIRouter() # 流式就是智能体返回一点就输出一点而不是全部返回才输出更加美观些 @router.post("/chat/stream") async def chat_endpoint(request: ChatRequest): """流式对话""" return StreamingResponse( search_recipes(request.message, request.image_url, request.thread_id), media_type="text/event-stream" ) @router.get("/chat/messages") async def get_chat_messages(thread_id: str): """获取历史消息""" messages = get_messages(thread_id) return {"messages": messages} @router.delete("/chat/messages") async def clear_chat_messages(thread_id: str): """清空历史消息""" clear_messages(thread_id) return {"success": True}
http://www.jsqmd.com/news/897182/

相关文章:

  • DOP值仿真与几何布局优化:从理论到实践
  • 【2026-05-25】丐版家旅
  • 多哈希PoW的ASIC抗性评估:从理论到硬件实现的深度剖析
  • AR 巡检落地难?看这 6 个案例
  • 2026青岛纹眉怎么选?多门店从业者,详解纹绣世家高人气原因 - 小艾信息发布
  • 2026年氢能计量流量计厂家品牌一览:国产与进口怎么选?氢能流量计知名厂家 - 流量计品牌
  • Obsidian插件汉化终极指南:三步实现中文界面,让笔记工具真正属于你
  • LeetDown技术解析:基于checkm8漏洞的iOS设备降级解决方案
  • ReentrantLock 公平锁 非公平锁底层实现原理
  • qmc-decoder:专业级QQ音乐加密格式转换工具,3步解锁你的音乐收藏
  • 从理论到实践:使用sklearn解锁神经网络反向传播的鸢尾花分类实战
  • 锋芒剪辑-dota2自动剪辑微信小程序
  • JiYuTrainer技术实现:Windows系统级进程控制与反监控机制解析
  • 情境感知与自适应学习:UTROLL/KANTEAM移动语言学习系统架构解析
  • 重庆黄金回收为什么别选小店?对比宝奢、典表,合扬优势更明显 - 合扬奢侈品交易中心
  • 什么是阻抗匹配?功率传输和防止信号反射的理由及原理
  • 新手入门指南使用 Python 快速调用 Taotoken 提供的各类大模型
  • 古典乐理教师集体沉默的真相(内部培训PPT流出):ChatGPT已能完成本科《和声学II》全部作业,但仅7.3%用户掌握“约束型提问法”
  • 从99.77%到99.8%:PyTorch CNN在MNIST上的超参数调优与模型微调实战
  • 领航元启GEO品牌内容战略与AI营销服务 - 资讯焦点
  • 测试岗缩编30%后,活下来的人都悄悄搭了这套系统
  • 青岛企业发生股权纠纷不用慌!青岛资深股权律师李杰:专注解决各类公司股权争议 - 资讯纵览
  • 基于LPC-FCN的轻量级触觉纹理识别:边缘计算中的高效解决方案
  • 腾讯文档裁员风波:大厂“降本增效”背后的技术团队生存法则
  • 基于SDR的5G智能手机八天线MIMO实时测试平台构建与验证
  • 大模型边缘部署新突破:混合精度与对数量化实现4比特以下高效压缩
  • Boss-Key:Windows办公隐私保护终极指南,一键隐藏窗口告别尴尬时刻
  • 面霸AI:用Multi-Agent让面试模拟卷死同行
  • 基于BLS熵与t-SNE的形状聚类:从网络熵到无监督分类的实践
  • 如何在Windows 10上免费运行Android应用:专业级跨平台解决方案