如何在LangServe API及Playground中实现图片+文本聊天功能
实现LangServe图片+文本双向聊天API方案
1. 扩展输入结构支持图片与文本
先定义支持双输入类型的数据模型,替代原纯文本输入,适配LangServe的Pydantic校验机制:
from langchain_core.messages import HumanMessage from pydantic import BaseModel, Field from typing import Optional, Union import base64 class ChatInput(BaseModel): text: Optional[str] = Field(default=None, description="用户输入文本") image_base64: Optional[str] = Field(default=None, description="上传图片的Base64编码") class ChatResponse(BaseModel): reply: str = Field(description="LLM回复内容")
2. 实现图片OCR解析逻辑
封装easyocr的图片识别函数,全局初始化模型避免重复加载:
import easyocr import io from PIL import Image from fastapi import UploadFile # 全局初始化OCR模型(按需选择语言) ocr_reader = easyocr.Reader(['ch_sim', 'en']) def process_image(image_source: Union[UploadFile, io.BytesIO]) -> str: if isinstance(image_source, UploadFile): image = Image.open(io.BytesIO(image_source.file.read())) else: image = Image.open(image_source) # 执行OCR识别并拼接文本 ocr_result = ocr_reader.readtext(image) return "\n".join([text for (_, text, _) in ocr_result])
3. 改造聊天链支持混合输入
将纯文本聊天链扩展为可处理图片+文本的混合输入:
from langchain.chat_models import ChatOpenAI from langchain.chains import ConversationChain from langchain.memory import ConversationBufferMemory # 初始化LLM与会话内存 llm = ChatOpenAI(temperature=0) memory = ConversationBufferMemory() conversation_chain = ConversationChain(llm=llm, memory=memory, verbose=True) async def chat_handler(input_data: Union[str, ChatInput]) -> str: # 处理纯文本输入 if isinstance(input_data, str): return conversation_chain.predict(input=input_data) # 处理图片+文本混合输入 user_text = input_data.text or "" extracted_text = "" if input_data.image_base64: # 解码Base64图片并执行OCR image_bytes = base64.b64decode(input_data.image_base64) extracted_text = process_image(io.BytesIO(image_bytes)) # 拼接输入内容传递给LLM full_input = f"{user_text}\n\n图片识别内容:\n{extracted_text}" if extracted_text else user_text return conversation_chain.predict(input=full_input)
4. 配置LangServe路由与Playground适配
挂载聊天API路由
from fastapi import FastAPI, UploadFile, File from langserve import add_routes app = FastAPI(title="支持图片的LLM聊天API") # 添加支持混合输入的聊天路由 add_routes( app, chat_handler, input_type=Union[str, ChatInput], output_type=str, playground_type="chat", ) # 可选:单独提供图片上传测试端点 @app.post("/upload-image") async def direct_image_upload(file: UploadFile = File(...), text: Optional[str] = None): extracted_text = process_image(file) full_input = f"{text}\n\n图片识别内容:\n{extracted_text}" if text else extracted_text return {"reply": conversation_chain.predict(input=full_input)}
给Playground添加图片上传功能
原生LangServe Playground不支持图片上传,可通过两种方式适配:
- 快速方案:基于上述
/upload-image端点,编写简单前端页面(含文件上传框+文本输入框),提交时调用接口。 - 定制方案:替换LangServe默认Playground模板,在页面中添加图片上传组件,将图片转为Base64后调用聊天接口。可通过FastAPI挂载静态文件实现:
在from fastapi.staticfiles import StaticFiles app.mount("/static", StaticFiles(directory="static"), name="static")static/playground.html中添加文件上传逻辑,将图片编码为Base64后传入ChatInput模型。
5. 关键优化点
- 全局初始化easyocr模型,避免每次请求重复加载模型,提升性能。
- 添加异常捕获:处理图片解码失败、OCR识别出错等场景,返回友好提示。
- 会话内存管理:确保图片识别的内容被纳入上下文,支持多轮连贯聊天。
- 图片格式校验:限制上传文件为JPG/PNG等常见格式,避免无效输入。
内容的提问来源于stack exchange,提问作者DevPy
相关产品推荐
相关产品推荐

