第36期 | 实战4:AI助手应用

📅 2026/6/27 4:02:53
第36期 | 实战4:AI助手应用
第36期 | 实战4AI助手应用 今天你将学会从零开发一个完整的 AI 助手应用对话 知识库 工具调用整合模块四前三期的所有知识到一个产品级项目实现完整的数据流用户输入 → RAG搜索 → Agent调用 → 流式展示理解项目级开发中的架构决策和代码组织 核心知识项目概览TechAssist AI 助手我们要做一个「技术文档 AI 助手」——用户可以聊天提问基础对话上传文档到知识库RAGAgent 自动搜索知识库 调用工具回答Agent 交互功能清单功能描述对应期数基础对话ChatGPT 风格聊天界面第33期流式响应逐字渲染 AI 回复第32期Markdown 渲染代码块、表格、链接第33期知识库管理上传文档 分片预览第34期RAG 问答基于真实文档回答 引用来源第34期Agent 交互思考过程 工具调用展示第35期显示模式切换精简/详细/实时第35期项目架构设计tech-assist/ ├── app/ │ ├── layout.tsx — 全局布局侧边栏 主内容区 │ ├── page.tsx — 馊页对话界面 │ └── api/ │ │ ├── ai/ │ │ │ ├── chat/route.ts — 基础聊天接口SSE流式 │ │ │ ├── rag/route.ts — RAG聊天接口搜索回答来源 │ │ │ └── agent/route.ts — Agent接口思考工具回答 │ │ └── knowledge/ │ │ │ ├── upload/route.ts — 文档上传接口 │ │ │ ├── list/route.ts — 文档列表接口 │ │ │ └── search/route.ts — 知识库搜索接口 │ └── knowledge/ │ └── page.tsx — 知识库管理页面 ├── features/ │ ├── chat/ — 聊天模块Store Components │ ├── knowledge/ — 知识库模块 │ └── agent/ — Agent 模块 ├── lib/ │ ├── ai-client.ts — AI API 客户端非流式流式Agent流 │ ├── agent-stream-parser.ts — Agent SSE 流解析器 │ ├── ai-errors.ts — 错误处理 │ └── utils.ts — 工具函数 ├── components/ │ └── ui/ — shadcn/ui 组件 │ └── layout/ │ ├── Sidebar.tsx — 侧边栏对话历史列表 知识库入口 │ └── Header.tsx — 顶部导航 └── types/ └── index.ts — 全局类型定义核心数据流设计场景1基础对话用户输入 → ChatStore.addMessage(userMsg) → aiClient.chatStream(messages) → SSE流 → 逐token追加 → ChatStore.updateLastAssistantMessage → UI渲染场景2RAG 问答用户输入 → ChatStore.addMessage(userMsg) → aiClient.ragChat(messages) → 后端向量搜索 构建RAG Prompt LLM → SSE流(content sources) → 前端逐token追加 最后展示SourceReference → UI渲染场景3Agent 问答用户输入 → AgentStore.addMessage(userMsg) → aiClient.agentChat(messages) → 后端思考 → 工具调用 → 观察结果 → 再思考 → 最终回答 → SSE流 → 前端AgentStreamParser 解析 → 逐type追加 → AgentMessage渲染 → UI渲染全局状态管理// store/appStore.tsinterfaceAppState{// 侧边栏状态sidebarOpen:boolean;conversations:Conversation[];activeConversationId:string|null;// 知识库状态documents:Document[];// 显示模式agentDisplayMode:compact|detailed|live;// Token 使用追踪tokenUsage:TokenUsage;}interfaceConversation{id:string;title:string;// 自动从第一条消息生成mode:chat|rag|agent;messages:Message[];createdAt:string;updatedAt:string;}侧边栏对话历史管理// components/layout/Sidebar.tsx export function Sidebar() { const { conversations, activeConversationId, sidebarOpen } useAppStore(); return ( aside className{w-64 border-r bg-gray-50 transition-all ${sidebarOpen ? : w-0} dark:bg-gray-900} {/* 新建对话按钮 */} div classNamep-4 button classNamew-full rounded-lg border px-4 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-800 新建对话 /button /div {/* 对话模式选择 */} div classNamepx-4 mb-2 div classNameflex gap-1 button classNamepx-3 py-1 text-xs rounded bg-blue-500 text-white对话/button button classNamepx-3 py-1 text-xs rounded bg-gray-200 text-gray-600知识库问答/button button classNamepx-3 py-1 text-xs rounded bg-gray-200 text-gray-600Agent/button /div /div {/* 对话历史列表 */} div classNamepx-4 space-y-1 overflow-y-auto {conversations.map((conv) ( button key{conv.id} onClick{() setActiveConversation(conv.id)} className{w-full text-left px-3 py-2 rounded text-sm truncate ${conv.id activeConversationId ? bg-gray-200 dark:bg-gray-700 : hover:bg-gray-100 dark:hover:bg-gray-800}} {conv.title} /button ))} /div {/* 知识库入口 */} div classNamemt-auto p-4 border-t Link href/knowledge classNameflex items-center gap-2 text-sm text-gray-500 hover:text-gray-700 BookOpen size{16} / 知识库管理 span classNametext-xs text-gray-400{documents.length} 份文档/span /Link /div /aside ); }对话模式切换根据用户选择的模式chat/rag/agent主内容区渲染不同的界面// app/page.tsx export function HomePage() { const { activeConversationId } useAppStore(); const conversation useAppStore(state state.conversations.find(c c.id activeConversationId) ); if (!conversation) return EmptyState /; switch (conversation.mode) { case chat: return ChatInterface /; case rag: return RAGChatInterface /; case agent: return AgentInterface /; } }完整项目搭建步骤Step 1创建 Next.js 项目pnpmcreate next-app tech-assist--typescript--tailwind--appcdtech-assistpnpmaddopenai zustand react-markdown remark-gfm lucide-reactpnpmadd-Dtypes/reactStep 2搭建目录结构mkdir-pfeatures/chat/store features/chat/componentsmkdir-pfeatures/knowledge/store features/knowledge/componentsmkdir-pfeatures/agent/store features/agent/componentsmkdir-papp/api/ai app/api/knowledgemkdir-plib components/layout components/ui typesStep 3实现核心模块按照 32-35 期学到的知识逐模块实现lib/ai-client.ts— AI API 客户端第32期lib/ai-errors.ts— 错误处理第32期lib/agent-stream-parser.ts— Agent SSE 解析第35期features/chat/— 聊天模块第33期features/knowledge/— 知识库模块第34期features/agent/— Agent 模块第35期app/api/— 后端接口第32-35期components/layout/— 布局组件Step 4集成测试每个模块完成后立即测试聊天模块发送消息 → 流式渲染 → Markdown 正常知识库模块上传文档 → 搜索 → 引用展示Agent 模块提问 → 思考/工具/回答完整流程产品级细节1. 对话标题自动生成// 对话标题从第一条消息的前 20 个字生成consttitlemessages[0]?.content.slice(0,20)(messages[0]?.content.length20?...:);2. 对话持久化// 在 appStore 中 persist 对话历史exportconstuseAppStorecreateAppState()(persist((set,get)({...}),{name:tech-assist-storage,partialize:(state)({conversations:state.conversations,documents:state.documents,tokenUsage:state.tokenUsage,}),}));3. 模型切换// 在设置面板中切换模型 Select value{selectedModel} onValueChange{setSelectedModel} SelectItem valuegpt-4o-miniGPT-4o Mini快速/低成本/SelectItem SelectItem valuegpt-4oGPT-4o精确/高成本/SelectItem /Select4. Token 使用量展示// 在 Header 中展示今日 Token 使用量 span classNametext-xs text-gray-400 今日: {tokenUsage.totalTokens} tokens | ¥{tokenUsage.totalCost.toFixed(2)} /span常见误区误区1先写完所有功能再测试应该每个模块完成后立即测试。集成 5 个模块后发现 Bug → 很难定位问题出在哪个模块。误区2所有功能共用一个 Store聊天/知识库/Agent 有不同的数据结构。每个模块有自己的 Store全局状态只在 appStore 中管理共享数据。误区3不做持久化用户刷新页面后对话历史全没了——这是灾难性体验。用 Zustand persist 持久化关键数据。 AI协作实战实战场景用 AI 协作开发整个项目我给 AICursor Composer的总任务描述我要开发一个 AI 技术助手应用 TechAssist包含三个核心模式 1. 基础对话ChatGPT风格聊天 2. 知识库问答RAG搜索文档 引用来源 3. Agent问答思考过程 工具调用展示 请先列出完整的项目文件清单和每个文件的核心职责 然后逐模块实现每个模块完成后我会测试验证。 参考 .cursorrules 中的项目规范。AI 列出的文件清单50 文件核心文件 12 个Store/Client/Layout/API组件文件 18 个Chat/Knowledge/Agent/UI类型/工具 5 个配置文件 3 个我的执行策略不是让 AI 一次性生成 50 个文件而是先让它生成文件清单 → 我确认按模块逐个生成 → 每个模块完成后我运行测试发现问题时追加修改指令 → 逐个修正5 轮 Composer 交互后的结果所有核心模块代码生成完毕2 个 Bug 在测试中发现并修正流式解析遗漏 DONE 标记、Agent 消息类型缺少 thinking总耗时约 2 小时 vs 预估手写时间 8-10 小时学到了什么大型项目的 AI 协作关键是分模块逐步执行——不要一次性让 AI 生成所有代码。每个模块独立测试后再整合Bug 更容易定位。 动手练习练习1简单搭建项目骨架创建 Next.js 项目 安装依赖 搭建目录结构 实现 appStore 基础状态管理。先不实现具体功能确保骨架能运行。练习2中等实现核心对话功能实现 ChatInterface ChatStore aiClient SSE流式渲染用户输入 → 流式显示 AI 回复Markdown 渲染正常自动滚动到底部停止生成按钮练习3挑战实现完整的三模式应用按本期项目架构完整实现三种模式基础对话模式RAG 知识库问答模式Agent 交互模式侧边栏对话历史管理持久化存储Token 使用量追踪 本期要点三种模式统一架构chat/rag/agent 共用 ChatInput MarkdownRenderer各自有不同的 SSE 解析和消息渲染模块化 StorechatStore / knowledgeStore / agentStore 各管各的appStore 只管全局共享数据分模块逐步实现大项目不要一次性让 AI 生成所有代码——逐模块生成 独立测试产品级细节对话标题自动生成、持久化存储、模型切换、Token 追踪——这些是「能用」和「好用」的区别侧边栏是入口对话历史 模式切换 知识库入口用户的所有操作从这里开始 下期预告下一期进入 AI 绘画前端——图片生成界面、参数调节、历史管理。你将学会如何设计一个让用户轻松生成 AI 图片的 Web 界面。如果你没有苹果电脑需要上传ios到APPStore可以访问以下网站iPA上传工具 - IPA解析与AppStore提交