
1. 项目缘起从“人肉搜索”到“智能助理”的转变做销售的朋友或者管理过销售团队的人一定对下面这个场景不陌生客户在群里突然问了一个关于一年前某个项目的技术细节或者一个已经离职同事经手的特殊报价条款。你心里一咯噔赶紧在电脑里翻找从“销售合同”文件夹找到“项目资料”文件夹再到聊天记录里搜索关键词运气好十分钟能找到运气不好半小时过去客户可能已经等不及了。更别提那些散落在个人电脑、公司网盘、甚至已经失效的链接里的历史资料了。这种“手动翻资料”的痛不仅效率低下更直接影响客户体验和专业形象。我过去几年带销售团队这个问题几乎成了“顽疾”。我们尝试过建立共享知识库、强制要求归档但效果总是不尽如人意。要么是资料格式混乱PDF、Word、Excel、图片混在一起要么是归档不及时项目一结束大家就忙着下一个历史资料就“沉底”了。直到我开始接触“智能体”Agent和“大语言模型”LLM技术一个想法逐渐清晰能不能让一个“数字员工”7x24小时值守随时响应销售相关的档案查询和问答这就是“Agent Plan”项目的起点。简单来说这个项目的核心目标是构建一个能理解自然语言、能自动检索企业内部销售档案、并能基于档案内容生成准确回答的智能问答系统。它不是一个简单的关键词搜索工具而是一个具备一定“理解”和“推理”能力的智能助理。想象一下销售同事在飞书群里这个助理问一句“去年我们给XX公司做的智慧园区项目用的核心传感器型号和报价是多少”助理就能立刻从历史合同、技术方案书、报价单等文件中定位到相关信息并组织成一段清晰的回复。这背后涉及档案的数字化、向量化存储、语义理解、以及与企业通讯工具如飞书的无缝集成。2. 技术栈选型为什么是Codex Supabase 飞书要实现上述构想技术选型是关键。经过一番调研和对比我最终敲定了以Codex、Supabase和飞书为核心的技术栈。这个组合并非凭空而来而是基于实际需求、开发效率和成本控制综合权衡的结果。2.1 核心大脑为什么选择Codex作为LLM服务市面上LLM API很多为什么选Codex首先需要澄清这里的“Codex”并非特指某个单一产品。在项目初期我调研了多个提供类似Codex即代码生成与补全能力的模型服务以及更通用的聊天模型。最终我选择了一个支持Function Calling函数调用和长上下文的模型服务作为核心。原因如下成本与可控性相比于直接使用某些闭源商业模型的昂贵API一些开源的或性价比更高的模型服务在项目中我将其统称为“Codex服务”提供了更灵活的选择。我可以根据查询复杂度选择不同规格的模型有效控制成本。函数调用能力这是实现“智能体”行动力的关键。当用户问“查一下XX项目的合同”时模型需要理解这是一个“查询档案”的意图并结构化地提取出“项目名称XX”这个关键参数然后调用我预先定义好的“档案查询函数”。Codex类服务对函数调用的支持通常比较成熟和稳定。长上下文处理销售档案的答案往往需要模型综合多份文档的片段来生成。这就要求模型有足够长的上下文窗口能够同时接收用户问题、检索到的相关文档片段以及系统指令进行综合分析和回答。注意在实际部署中你可能会遇到类似“detail”“the ‘gpt-5.6-sol’ model is not supported...”这样的错误。这通常意味着你请求的模型名称在当前服务中不存在或已变更。解决方法是仔细查阅你所选用服务的官方文档确认可用的模型列表并在代码中修正模型名称参数。这提醒我们依赖外部API时版本管理和错误处理机制必不可少。2.2 记忆与检索为什么选择Supabase作为向量数据库档案检索的核心是“语义搜索”而不是“关键词匹配”。我们需要把每一段文档比如合同的一个条款、方案书的一页内容转换成数学向量Embedding然后存储起来。当用户提问时把问题也转换成向量在数据库里寻找“向量距离”最近的即语义最相似的那些文档片段。我选择Supabase主要基于以下几点开箱即用的向量搜索Supabase的PostgreSQL数据库原生支持pgvector扩展。这意味着我无需单独部署和维护一个像Milvus、Qdrant这样的专业向量数据库直接用熟悉的SQL和Supabase的客户端SDK就能完成向量的存储、索引和相似性查询。大大降低了运维复杂度。一体化后端服务Supabase不仅仅是数据库它还提供了身份认证Auth、实时订阅Realtime、存储Storage和边缘函数Edge Functions。我的智能体需要用户鉴权区分不同销售同事的查询权限档案文件需要存储这些功能Supabase都能一站式解决。用它的Edge Functions我甚至可以快速部署一个处理用户查询、调用Codex和向量检索的API服务端。开发效率与生态Supabase有优秀的JavaScript/TypeScript客户端与我的Node.js后端技术栈完美契合。其管理控制台也非常直观方便查看数据、调试查询。2.3 交互界面为什么深度集成飞书选择飞书作为主要交互界面几乎是国内企业场景下的必然选择。用户零学习成本销售团队每天都在用飞书沟通。将智能助理以“飞书机器人”的形式嵌入群聊或单聊用户无需安装新APP无需学习新界面直接像同事一样机器人提问即可交互路径最短。丰富的开放能力飞书开放平台提供了完善的机器人API、消息卡片、事件订阅等功能。我可以轻松实现接收消息监听群里机器人的消息。发送富文本回复不仅可以发文字还能用卡片形式结构化展示信息比如把查到的合同关键信息做成一个漂亮的卡片。主动通知结合其他系统当有新项目资料归档时机器人可以主动推送到相关群组。与企业数据打通很多公司的销售档案本身可能就存放在飞书云文档、多维表格里。飞书机器人可以通过权限认证直接访问这些资源为档案的自动收集和更新提供了便利。2.4 辅助工具链OpenViking与本地调试在开发过程中我还用到了OpenViking这类开源项目。它本质上是一个本地运行的、可视化的Agent开发与调试框架。你可以用它来快速搭建一个Agent的流程定义工具Tools并观察每一步的思考Chain of Thought和执行过程。在将智能体正式部署到飞书机器人之前我在本地用OpenViking模拟用户对话反复测试和优化提示词Prompt以及函数调用的逻辑这极大地提升了开发调试效率。至于codex cli,codex桌面版这些热词更多指的是Codex服务的命令行工具或本地客户端用于管理、测试模型服务在项目运维和脚本化任务中很有用。3. 系统架构与核心流程拆解整个系统的运行可以看作一个精心设计的流水线。下面这张图概括了从用户提问到获得答案的全过程用户 飞书机器人提问 ↓ 飞书开放平台 (接收事件) ↓ 我们的后端服务 (Supabase Edge Function / 自建API) ↓ ├── 步骤1: 身份验证 (验证飞书用户) ├── 步骤2: 意图理解与参数提取 (调用Codex) ├── 步骤3: 档案检索 (查询Supabase向量数据库) ├── 步骤4: 答案合成 (再次调用Codex结合检索结果) └── 步骤5: 返回富文本答案 (飞书消息卡片) ↓ 飞书开放平台 (发送消息) ↓ 用户在飞书收到答案3.1 第一步档案的数字化与向量化入库这是所有智能问答的基础所谓“Garbage in, garbage out”。我们的销售档案来源多样PDF合同、Word方案书、Excel报价单、甚至是聊天记录截图。文档解析与分块首先我们需要一个文档解析层。对于PDF/Word/Excel可以使用像pdf-parse、mammoth、xlsx等库提取纯文本。关键的一步是“分块”Chunking。不能把整个100页的PDF当成一个文本块那样检索精度会很低。我们需要按语义进行分块比如按章节、按段落。一个实用的策略是使用“递归字符文本分割器”设置一个合适的大小如500字和重叠区如50字保证语义的连贯性。生成向量嵌入对每一个文本块调用Codex服务的Embeddings API或专用的嵌入模型如text-embedding-3-small将其转换为一个高维向量例如1536维。这个向量就是这段文本的“数学指纹”。存入Supabase在Supabase中创建一张表至少包含以下字段id,content文本块内容embedding向量metadataJSON类型存储来源文件、页码、项目名称、创建时间等元数据。利用pgvector扩展对embedding字段创建ivfflat或hnsw索引以加速相似性搜索。实操心得元数据metadata的设计至关重要。后期检索时我们不仅可以根据向量相似度找内容还可以用元数据进行过滤。例如用户问“A项目的合同”我们可以在向量检索的同时加上WHERE metadata-project_name ILIKE %A%的条件让结果更精准。分块大小需要反复测试太小会失去上下文太大会引入噪声。3.2 第二步飞书机器人的接入与消息处理在飞书开放平台创建一个企业自建应用并添加机器人能力。核心配置包括权限申请需要“获取用户发给机器人的单聊消息”、“获取用户在群聊中机器人的消息”等消息权限。事件订阅订阅im.message.receive_v1事件。飞书服务器在收到用户机器人的消息后会向我们配置的“请求地址”Callback URL发送一个HTTP POST请求。安全验证飞书使用加密和Token进行验证。我们需要在服务端处理encrypt_key和verification_token确保请求来自飞书官方。这里容易踩坑特别是encrypt解密环节务必仔细对照官方文档的示例代码。我们的后端服务比如部署在Supabase Edge Function上就是这个“请求地址”。它接收到飞书的POST请求后进行飞书要求的解密和验证。解析出事件内容得到发送者ID、消息内容、聊天ID等。根据业务逻辑开始处理用户问题。3.3 第三步智能体Agent的思考与行动循环这是最核心的环节。我们的后端服务扮演着“智能体调度中心”的角色。初始化与上下文管理首先我们为当前对话创建一个会话上下文。如果用户是在一个群聊中连续提问我们需要有能力记住之前的对话历史通常将最近几轮QA存入数据库或缓存让模型理解指代关系比如“上一个项目”指的是什么。意图识别与工具调用将用户问题、可能的对话历史以及我们定义的“工具列表”一起发送给Codex模型。工具列表就是我们给智能体配备的“技能”例如search_sales_documents搜索销售档案。参数query搜索关键词project_name可选项目名过滤date_range可选时间范围。get_project_overview获取项目概要。参数project_id。calculate_quotation根据模板和参数计算报价如果需要。 模型会根据对话内容判断是否需要调用工具以及调用哪个工具并生成一个结构化的JSON输出包含工具名和参数。执行工具与检索后端收到模型的工具调用请求后执行对应的函数。对于最常用的search_sales_documents就是去查询Supabase向量数据库。-- 示例在Supabase中进行向量相似性搜索 SELECT content, metadata, 1 - (embedding ‘[用户问题的向量]’) AS similarity FROM sales_documents WHERE metadata-‘department’ ‘sales’ -- 可选用元数据过滤 ORDER BY embedding ‘[用户问题的向量]’ LIMIT 5; -- 返回最相似的5个片段这里是pgvector提供的余弦距离运算符值越小越相似。答案合成与回复将检索到的相关文本片段作为“参考依据”和原始用户问题再次发送给Codex模型指令是“请基于以下参考材料专业、准确地回答用户的问题。如果材料中没有明确答案请告知无法回答。” 模型会生成最终的回答文本。格式化与推送将回答文本封装成飞书支持的消息格式。为了体验更好我通常使用“交互式卡片”。可以设计一个卡片标题是问题摘要正文是详细回答底部还可以有按钮比如“查看源文档”、“关联项目”等。最后调用飞书的“回复消息”API将卡片发送到原聊天窗口。4. 实战部署与避坑指南理论很美好但部署上线时处处是坑。下面分享几个关键环节的实战经验和常见问题。4.1 Supabase向量搜索的优化与调试直接使用基础的向量搜索在数据量上去后可能会慢或者精度不够。索引选择pgvector支持ivfflat和hnsw索引。ivfflat创建快适合写入频繁的场景hnsw查询性能更好精度更高适合读多写少的场景。我们档案库更新不频繁所以选择了hnsw。CREATE INDEX ON sales_documents USING hnsw (embedding vector_cosine_ops);查询性能调优pgvector的hnsw索引有ef_search和m等参数可以调整权衡查询速度和召回率。在Supabase的SQL编辑器中直接执行SET hnsw.ef_search 100;可以在当前会话中调整。需要通过实验找到业务可接受的平衡点。混合搜索纯向量搜索有时会被“语义漂移”。结合关键词搜索BM25进行加权融合效果往往更好。Supabase支持全文搜索我们可以将content字段也做一份GIN索引查询时同时计算向量相似度和文本匹配度然后加权求和。这需要更复杂的查询语句但能显著提升复杂查询的准确性。4.2 飞书机器人配置的“天坑”飞书开发文档虽然全但细节魔鬼多。“请求地址”验证失败在事件订阅配置“请求地址”时飞书会立即发送一个带challenge参数的验证请求。你的服务端必须在收到后按照规定的算法涉及encrypt_key,timestamp,nonce,msg_encrypt原样返回challenge值。很多失败是因为解密或加密算法实现有误务必使用飞书官方提供的SDK或严格对照示例代码。权限与安全app_secret等敏感信息一定要保管好不要硬编码在客户端。在Supabase Edge Function中可以使用环境变量存储。另外飞书API调用有频率限制要做好请求的队列和重试机制。消息卡片更新如果你发送的消息卡片带有交互按钮当用户点击后你需要更新卡片状态。这里涉及“卡片回调”和“消息更新”接口。注意飞书对卡片的token有有效期且更新操作需要特定的权限。我曾在这里卡了很久最后发现是更新API的调用方式不对。4.3 Codex提示词工程与成本控制如何让Codex模型更好地理解销售场景并稳定地输出我们期望的格式系统指令System Prompt设计这是模型的“角色设定”。我的系统指令大致如下 “你是一个专业的销售档案助理精通公司所有产品和项目历史。你的职责是严格根据提供的参考资料回答用户关于销售合同、技术方案、报价等方面的问题。如果资料中没有明确答案你必须如实告知‘根据现有档案无法找到该信息’切勿编造。你的回答应简洁、专业、准确。当用户问题涉及查询具体档案时请使用‘search_sales_documents’工具。” 这个指令明确了角色、职责、知识边界和工具使用条件。处理模型“幻觉”即使有严格的指令模型有时仍会“自信地”编造答案。我们的防线是第一在答案合成阶段强制模型引用检索片段的原文例如要求它说“根据XX合同第Y条……”第二在后端对关键事实如金额、型号进行二次校验如果可能与原始数据库进行比对。成本控制Codex API按Token收费。为了省钱第一在检索阶段严格控制返回的文本片段数量和长度只返回最相关的部分第二在对话中对历史消息进行摘要压缩而不是全部发送第三对于简单、高频的查询如“公司官网是什么”可以设置缓存直接返回固定答案不走模型。4.4 档案库的持续更新与维护系统上线不是终点。新的销售项目每天都在产生新档案。自动化流水线理想状态是当销售在飞书多维表格或OA系统中完成一个项目的“结项”流程时自动触发一个工作流。这个工作流将项目相关的所有文档已签合同、最终版方案等收集起来调用文档解析和向量化服务自动入库。这需要与公司内部其他系统做集成。人工审核与修正自动化流水线可能出错如解析乱码。需要有一个后台管理界面允许管理员查看新入库的文档块进行校对、打标签或删除。Supabase Admin UI本身就是一个简单的管理后台也可以快速用其数据表视图搭建一个。数据清理定期清理过时或错误的档案。可以基于元数据中的“项目状态”如已终止或“归档时间”来制定清理策略。5. 效果评估与未来演进方向项目上线运行三个月后我们进行了一次内部调研。销售团队的反馈主要集中在几点一是查询速度很快平均响应时间在3秒内二是答案准确率在85%以上对于明确记录在案的信息基本都能找到三是使用习惯培养起来了大家遇到历史问题第一反应是机器人。当然也有不足对于非常模糊、需要深度推理的问题例如“为什么这个项目最后没成交”系统还无法给出令人满意的答案因为它只能基于现有文本做检索和总结缺乏真正的因果分析能力。基于此未来的演进方向可以有几个多模态能力目前主要处理文本。很多销售档案里有重要的架构图、设备照片。下一步可以集成多模态模型让AI也能“看懂”图片中的信息比如从产品彩页中识别型号和参数。工作流自动化从“问答”延伸到“执行”。例如销售问“创建一个类似XX项目的报价单”AI在检索到历史报价后可以自动调用公司的报价模板系统填充关键信息生成一个草稿而不仅仅是给出文字回答。预测与洞察通过对历史所有项目档案的分析AI是否可以发现一些规律比如哪些技术方案组合更容易中标哪些条款经常引发后续纠纷这需要更深入的数据分析和模型训练但价值巨大。这个“Agent Plan”项目让我深刻体会到AI不是要取代销售而是成为销售最得力的“副驾驶”。它把人类从繁琐的记忆和查找工作中解放出来让人能更专注于需要创造力、情感交流和复杂谈判的核心工作。技术实现的路径已经比较清晰关键在于对业务场景的深度理解以及像“绣花”一样细致的工程化落地能力。