提问背景 Question:
有一个问题,如何让ai能回忙起附件,附件总不能重发吧?
大模型附件上下文管理
让AI“记住”附件,而不是每次都重发,这确实是与大型语言模型(LLM)交互时一个非常实际且重要的问题。由于LLM本身是无状态的,且API调用通常按Token计费,每次都发送完整的附件数据既低效又昂贵。
最科学且常用的方法是:后端存储 + 引用 + 检索增强生成 (RAG)。
以下是详细的策略和考虑点:
1. 核心思想:一次上传,多次引用与描述
附件(图片、文档、PDF等)的原始数据只上传一次到您的后端存储。之后,当用户或AI需要引用该附件时,您的系统向AI发送的不是附件本身,而是关于该附件的**“引用”和“文本描述/摘要”**。
2. 实现步骤与技术栈
2.1. 后端文件存储
- 用户上传: 用户通过前端界面上传文件(图片、PDF、代码文件等)。
- 服务器接收并存储: 您的Go后端接收文件,将其保存到持久化存储中。推荐使用:
- 云存储服务: 例如AWS S3、Google Cloud Storage、Azure Blob Storage等,它们提供高可用、可扩展且经济的存储方案。
- 私有服务器存储: 如果规模较小或有特定合规要求,也可以存储在您自己的服务器上,但需考虑文件管理和备份。
- 生成唯一标识: 为每个上传的文件生成一个唯一的
attachment_id,并记录其存储路径(如S3 URL或服务器本地路径)。
2.2. 数据库元数据管理
您需要一个数据库表来存储附件的元数据。这可以是您的cms_article表的一个扩展,或者一个独立的user_attachments表。
推荐独立的 user_attachments 表:
CREATE TABLE user_attachments (
id INTEGER PRIMARY KEY, -- 唯一的附件ID
user_id INTEGER NOT NULL, -- 上传用户ID
file_name TEXT NOT NULL, -- 原始文件名
file_path TEXT NOT NULL, -- 存储路径或URL
file_type TEXT NOT NULL, -- 文件类型 (image/jpeg, application/pdf)
extracted_text TEXT, -- 从附件中提取的文本内容(关键!)
summary_text TEXT, -- 附件的摘要(如果extracted_text过长)
vector_embedding BLOB, -- 附件内容的语义向量(可选,用于高级RAG)
uploaded_at INTEGER NOT NULL,
-- ... 其他元数据,如大小、状态等
);
-- 并且,您的cms_article表或一个关联表需要能够引用这些附件
CREATE TABLE cms_article_attachments (
article_id INTEGER NOT NULL,
attachment_id INTEGER NOT NULL,
PRIMARY KEY (article_id, attachment_id),
FOREIGN KEY (article_id) REFERENCES cms_article(id),
FOREIGN KEY (attachment_id) REFERENCES user_attachments(id)
);
2.3. 附件内容预处理(提取与摘要)
这是让AI“记住”附件的关键步骤:
- 文本提取:
- 图片: 使用OCR(光学字符识别)服务(如Google Cloud Vision API、PaddleOCR等)从图片中提取文本。或者,如果AI模型支持多模态输入(如Gemini Pro Vision, GPT-4V),您可以将图片发送给这些模型以获取描述或回答特定问题,然后将这些描述作为
extracted_text保存。 - PDF/文档: 使用库或服务(如
go-textract、unipdf等)从PDF、Word文档中提取文本内容。 - 代码文件: 直接读取文件内容。
- 图片: 使用OCR(光学字符识别)服务(如Google Cloud Vision API、PaddleOCR等)从图片中提取文本。或者,如果AI模型支持多模态输入(如Gemini Pro Vision, GPT-4V),您可以将图片发送给这些模型以获取描述或回答特定问题,然后将这些描述作为
- 内容摘要: 如果提取的文本内容过长,使用LLM对
extracted_text进行摘要,生成summary_text。这个摘要可以在需要时放入AI的prompt中,以节省Token。 - 语义向量嵌入(可选,但推荐): 将
extracted_text或summary_text通过一个嵌入模型(Embedding Model)转换为高维向量(vector_embedding)。这对于后续的语义搜索和RAG非常有用。
这些预处理步骤可以在文件上传后异步进行,以避免阻塞用户请求。
2.4. 构建AI提示 (Prompt Engineering)
当用户发起对话时,如果提问涉及历史附件:
-
识别引用: 您的后端需要智能地识别用户对话中对附件的引用(例如:“看我上次发的图”,“关于那个PDF”,“检查一下那个代码”),或者前端明确指明当前对话关联的
attachment_id。 -
检索附件上下文: 根据识别到的
attachment_id,从user_attachments表中检索对应的summary_text或extracted_text。 -
注入到Prompt: 将检索到的文本内容(可能是摘要,也可能是部分原始文本)作为**“上下文”**注入到发送给LLM的Prompt中。
示例Prompt结构:
以下是用户提供的相关附件信息: [附件ID: attachment_123] 文件名: circuit_diagram.png 内容摘要: 这是一张电源电路图,包含R1、C2、U3等元件,输出端检测到短路。 用户问题: 请结合这张电路图,告诉我R1可能有什么问题?或者,如果AI模型支持
genai.Part中直接包含genai.FileData或genai.ImageURL(对于图像)并且它能够实际访问该URL,您也可以在Go中这样构建:// 假设你有附件的公共可访问URL imageURL :=