和文件对话智能体(LLM Agent)


llm is killing the competition

和文件对话智能体(Chat with Files LLM Agent)

这是我很早之前就想做的项目,大致的设想、技术调研都做过一些,但没有实际动手实现。最近 Cursor 的 Plan 模式也一直没有很好的场景体验和验证,今天就把两件事情一起做了。完成的那一刻,我甚至提不起“了解具体实现”的兴趣。这个项目实现的过程太过于丝滑,以至于我现在对于技术和工程师职业本身都有了一种幻灭感。我在这个项目里起到的作用是什么?整个过程,就像我这个地球土著,向已经占领了太阳系的三体人,献祭了微不足道的 10 美刀,然后那位无所不知无所不能的三体人,不带任何情绪地实现了我的愿望。

本文不会详细介绍实现细节,我们一起欣赏神赐的艺术吧。

实现信息

工具信息

Cursor 版本:2.4.31,Plan 模式,Claude 4.6 Opus Thinking 模型

提示词

框架使用 next 全栈+langchain,数据库选型使用 sqlite(@sqliteai/sqlite-wasm,用来支持向量)。前端使用 shadcnui + tailwindcss,整体用 typescript。注意所有的依赖包联网使用最新稳定版。 以上是技术选型偏好,需要做的事情是搭建一个“Chat with files”Agent,这个智能体可以和本地的 纯文本文件、pdf、docx、pptx、xlsx、csv、sqlite 等文件格式“对话”,总结文件内容、生成内容简介的 markdown 或脑图,对于数据类文件(xlsx、csv、sqlite 等),还可以根据数据内容生成分析洞见,以可视化结果呈现。请完成这个 Agent 项目

以下是 chat_with_files_agent_534f5f9e.plan.md 文件内容

Chat with Files Agent 项目搭建计划

技术栈

  • 框架: Next.js 16.x (App Router, Turbopack)
  • LLM: OpenRouter API (通过 @langchain/openai 的 ChatOpenAI + 自定义 baseURL)
  • AI 框架: LangChain JS v1.x (@langchain/core, @langchain/openai, @langchain/community)
  • 数据库: LibSQL (@libsql/client) -- SQLite 分支,原生支持向量搜索,兼容 SQLite 协议
  • UI: shadcn/ui + Tailwind CSS v4
  • 可视化: Recharts 3.x (图表) + markmap-lib/markmap-view (脑图)
  • 语言: TypeScript 全栈

架构概览

项目目录结构

src/
├── app/
│   ├── layout.tsx              # 根布局
│   ├── page.tsx                # 主页 (Chat 界面)
│   ├── globals.css             # 全局样式
│   └── api/
│       ├── chat/route.ts       # 对话 API (流式)
│       ├── upload/route.ts     # 文件上传 API
│       └── files/route.ts      # 文件列表/删除 API
├── components/
│   ├── ui/                     # shadcn/ui 组件
│   ├── chat/
│   │   ├── chat-interface.tsx  # 聊天主界面容器
│   │   ├── message-list.tsx    # 消息列表
│   │   ├── message-item.tsx    # 单条消息 (含 markdown/图表/脑图渲染)
│   │   ├── chat-input.tsx      # 输入框 + 发送按钮
│   │   └── file-upload.tsx     # 文件拖拽上传区域
│   ├── visualization/
│   │   ├── chart-renderer.tsx  # Recharts 图表渲染
│   │   └── mindmap-renderer.tsx# markmap 脑图渲染
│   └── markdown-renderer.tsx   # Markdown 渲染 (react-markdown)
├── lib/
│   ├── db.ts                   # LibSQL 数据库初始化
│   ├── vector-store.ts         # 向量存储封装
│   ├── llm.ts                  # OpenRouter LLM 初始化
│   ├── agent.ts                # LangChain Agent 定义
│   ├── loaders/
│   │   ├── index.ts            # 统一加载器入口 (按扩展名分发)
│   │   ├── text-loader.ts      # 纯文本 (.txt, .md 等)
│   │   ├── pdf-loader.ts       # PDF (pdf-parse)
│   │   ├── docx-loader.ts      # DOCX (officeparser)
│   │   ├── pptx-loader.ts      # PPTX (officeparser)
│   │   ├── xlsx-loader.ts      # XLSX (xlsx/sheetjs)
│   │   ├── csv-loader.ts       # CSV (@langchain/community)
│   │   └── sqlite-loader.ts    # SQLite (better-sqlite3)
│   └── tools/
│       ├── file-search.ts      # 文件内容搜索工具 (RAG 检索)
│       ├── file-summary.ts     # 文件总结工具
│       ├── mindmap-gen.ts      # 脑图生成工具
│       └── data-analysis.ts    # 数据分析 + 可视化工具
├── hooks/
│   └── use-chat.ts             # Chat 状态管理 Hook
└── types/
    └── index.ts                # 类型定义

核心模块设计

1. LLM 配置 (src/lib/llm.ts)

通过 @langchain/openaiChatOpenAI 连接 OpenRouter:

import { ChatOpenAI } from "@langchain/openai";
 
export function createLLM(model?: string) {
  return new ChatOpenAI({
    model: model || process.env.DEFAULT_MODEL || "openai/gpt-4o",
    apiKey: process.env.OPENROUTER_API_KEY,
  }, {
    baseURL: "https://openrouter.ai/api/v1",
  });
}

环境变量 .env.local 中配置 OPENROUTER_API_KEYDEFAULT_MODEL

2. 向量存储 (src/lib/vector-store.ts)

使用 @langchain/communityLibSQLVectorStore:

import { LibSQLVectorStore } from "@langchain/community/vectorstores/libsql";
import { OpenAIEmbeddings } from "@langchain/openai";
import { createClient } from "@libsql/client";
  • 本地文件模式:url: "file:./data/vectors.db"
  • Embedding 模型同样走 OpenRouter 或单独配置

3. 文件加载器 (src/lib/loaders/)

统一入口根据文件扩展名选择对应加载器:

  • TXT/MD: 直接读取 fs + RecursiveCharacterTextSplitter
  • PDF: @langchain/communityPDFLoader (依赖 pdf-parse)
  • DOCX: @langchain/communityDocxLoader (依赖 officeparser)
  • PPTX: @langchain/communityPPTXLoader (依赖 officeparser)
  • XLSX: 使用 xlsx (SheetJS) 解析为表格数据,再转为文本文档
  • CSV: @langchain/communityCSVLoader
  • SQLite: 使用 better-sqlite3 读取 schema + 表数据,转为文本文档

4. Agent 工具集 (src/lib/tools/)

LangChain Agent 配备以下工具:

  • file_search: 基于向量检索的文件内容搜索,用于回答关于文件内容的问题
  • file_summary: 生成文件内容摘要 (Markdown 格式)
  • mindmap_generator: 将文件内容生成 markmap 格式的脑图 Markdown
  • data_analyzer: 针对数据类文件 (XLSX/CSV/SQLite),执行数据分析并返回 Recharts 可视化配置 JSON

5. 对话 API (src/app/api/chat/route.ts)

  • 使用 LangChain 的流式输出 (streamEvents)
  • 支持多轮对话 (维护 conversation history)
  • Agent 根据用户意图自动选择工具

6. 前端 UI 组件

  • ChatInterface: 主聊天界面,左侧文件列表 + 右侧对话区
  • FileUpload: 拖拽上传 + 文件格式验证
  • MessageItem: 支持渲染纯文本、Markdown、Recharts 图表、markmap 脑图
  • ChartRenderer: 根据 Agent 返回的图表配置渲染 Recharts 图表 (Bar, Line, Pie, Scatter 等)
  • MindmapRenderer: 根据 Markdown 内容渲染交互式脑图

主要依赖包

核心框架:

  • next (16.x), react (19.x), typescript (5.x)

AI / LangChain:

  • langchain (1.x), @langchain/core (1.x), @langchain/openai (1.x), @langchain/community (0.3.x), @langchain/textsplitters (latest)

数据库:

  • @libsql/client (0.17.x) -- 服务端向量存储
  • better-sqlite3 + @types/better-sqlite3 -- 读取用户上传的 SQLite 文件

文件解析:

  • pdf-parse -- PDF 解析
  • officeparser -- DOCX/PPTX 解析
  • xlsx -- Excel 解析
  • csv-parse -- CSV 解析备选

UI:

  • shadcn/ui (通过 CLI 安装)
  • tailwindcss (v4), react-markdown, remark-gfm, rehype-highlight

可视化:

  • recharts (3.x) -- 图表
  • markmap-lib, markmap-view -- 脑图

工具:

  • uuid -- ID 生成
  • zod -- Schema 验证

实现过程元信息

name: Chat With Files Agent
overview: 基于 Next.js 16 全栈框架搭建 "Chat with Files" 智能体应用,使用 LangChain + OpenRouter 实现多 LLM 切换,LibSQL 提供向量存储,支持多种文件格式的对话、总结、脑图生成和数据可视化分析。
todos:
  - id: init-nextjs
    content: 初始化 Next.js 16 项目 (create-next-app + TypeScript + Tailwind + App Router),配置 shadcn/ui
    status: completed
  - id: install-deps
    content: 安装所有依赖包:LangChain 全家桶、@libsql/client、better-sqlite3、文件解析库、可视化库等
    status: completed
  - id: setup-db
    content: 实现 LibSQL 数据库初始化 (src/lib/db.ts) 和向量存储封装 (src/lib/vector-store.ts)
    status: completed
  - id: setup-llm
    content: 实现 OpenRouter LLM 配置 (src/lib/llm.ts),支持通过环境变量切换模型
    status: completed
  - id: impl-loaders
    content: 实现所有文件加载器 (text/pdf/docx/pptx/xlsx/csv/sqlite),统一入口按扩展名分发
    status: completed
  - id: impl-tools
    content: 实现 Agent 工具集:file_search、file_summary、mindmap_generator、data_analyzer
    status: completed
  - id: impl-agent
    content: 实现 LangChain Agent (src/lib/agent.ts),整合工具集和 RAG 管道
    status: completed
  - id: impl-api
    content: 实现 API Routes:/api/chat (流式对话)、/api/upload (文件上传)、/api/files (文件管理)
    status: completed
  - id: impl-ui-chat
    content: 实现前端聊天 UI:ChatInterface、MessageList、ChatInput、FileUpload 组件
    status: completed
  - id: impl-ui-viz
    content: 实现可视化组件:ChartRenderer (Recharts)、MindmapRenderer (markmap)、MarkdownRenderer
    status: completed
  - id: integrate-test
    content: 端到端集成:连接前后端,测试文件上传 -> 对话 -> 可视化完整流程
    status: completed
  - id: env-config
    content: 创建 .env.example 和 README 文档,说明配置和使用方法
    status: completed
isProject: false

实现过程

Cursor 工作的过程和它自己规划的一样,只有一点点小波折:首先是 npm 依赖包的版本问题。大模型直接规划的 dependencies 里存在不少过期的依赖包,以及一些有冲突的模块。这些目前还是手动修复和执行安装的。剩余大概经历了三次左右的 debug 和微调过程,大概过程就是拿到报错输出,丢给 Cursor,修复后调试通过。整个过程加起来不超过半小时。Cursor 完成了所有的项目搭建和集成,还帮我选用了更好的技术栈,之后我就拿到了开箱即用的“和文件对话智能体”了。

实现结果展示

chat with files agent

项目代码可以查看 github:zero/chat-with-files-agent

后续以及一些碎碎念

前面的很多说法多少有点夸张了。之所以这么夸张地表达,其实是因为这个 Demo 项目实现过程带来的巨大的焦虑感。当然,这个项目仍然只是一个 Demo,有不少问题是需要进一步去迭代和完善的:

  • 首先是数据文件分析的准确性问题。目前所有的数据分析,尤其可视化结果,都是基于大模型理解,而非准确的数据查询。要生产级可用,还需要做 NL2SQL 的实现,以及生成过程、生成结果的检验
  • 其次,还有很多体验细节上的问题。譬如文件上传后的管理、基于文件问答记录的管理、对话输入和输出的交互优化等等
  • 还需要解决一系列安全、部署、监控、运维等方面的问题等

但无论如何,这已经展示了非常可观的应用能力,距离上线使用,也已不远。而这最后的步骤,继续用 Cursor 去迭代的话,可以预见也是很快且没有门槛的。而这么一个完成度颇高的项目,自始至终,也就花费 10 美元以及 1 小时不到的时间而已。

从 23 年开始,大模型的浪潮开始席卷全球。最开始大家有一些对未知的恐慌,对新鲜事物的好奇。再接着经历了一段“原来只是玩具”的调侃和看轻。等到关键几篇论文的落地、Agent 的诞生和发展,慢慢地大模型开始在创意内容、生产力等领域开始发挥越来越多的作用。24 年和 25 年都说是“Agent 元年”,事实上到 26 年的现在,曾经我觉得有点武断的“今天所有的软件都值得用大模型重做一遍”这句话,正在逐渐成为现实。甚至不止,脑力劳动被替代的比例真的越来越高,现在已经太高了。为今之计,唯有像哪里看过的调侃那样,“做 AI 的带路党”,充分拥抱,充分利用,顺势而为。


评论 (0)

登录后即可发表评论