ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

老牌内容站AI化改造:RAG与Agent实战指南

老牌内容站AI化改造:RAG与Agent实战指南 很多传统互联网产品在 AI 浪潮面前都有同一个困惑模型能力很强可自己手头的存量业务该怎么结合最近雅虎计划借助 AI 工具重振雄风、CEO 兰佐内把“复古”视为最大优势的新闻恰好给这个问题提供了一个讨论样本老产品不需要推倒重来关键是找到 AI 与存量资产的结合点。本文不评价股价和商业策略只从工程角度拆解如果要给一个老牌内容站接入 AI 问答和 Agent 能力需要准备什么、代码怎么落、会遇到哪些坑。1. 背景雅虎为什么押注 AI以及“复古”优势的技术含义1.1 雅虎的“复古”转型信号雅虎是互联网早期门户时代的标志性产品旗下拥有新闻、财经、体育、邮箱、搜索等一批高频业务。过去十几年它在搜索引擎和移动互联网浪潮中逐渐掉队但并未消失反而保留了大量内容资产和稳定的垂直用户群。兰佐内担任 CEO 后雅虎的路线开始出现变化。公开信息显示雅虎计划借助 AI 工具重新激发产品活力而兰佐内认为“复古”本身就是雅虎区别于新一代互联网产品的最大优势。这里的“复古”并不是指技术栈落后而是指品牌积累的怀旧感、内容库和用户习惯。换句话说雅虎不是要变成一个全新的 AI 公司而是要成为“一个会用 AI 重新表达的老品牌”。这一判断在技术层面有清晰的映射老牌产品不缺数据和场景缺的是新的交互层。AI 问答、内容摘要、个性化推荐、智能体助手恰好可以把多年沉淀的内容库重新激活。1.2 存量产品 AI 化的技术挑战传统产品接入 AI 并不像“调用一个 API 画画图、聊聊天”那么简单。真正落地时通常要面对四个问题内容资产如何变成模型可用的知识用户问题如何匹配到最相关的站内内容大模型出现幻觉时如何兜底实时信息如何通过工具调用获取这四点在雅虎这类老门户业务里非常典型。它们已经有很多新闻、财经数据、赛事比分、邮箱信息等业务如果直接让大模型“凭空回答”结果大概率不可靠。只有把“检索 生成 工具调用”串起来才能做出真正能用的产品功能。所以本文选择“内容站 AI 助手”作为实战案例它是一个最小但完整的技术原型覆盖了传统内容产品 AI 化改造的核心链路。2. 核心概念AI 工具、RAG 与 Agent 的关系2.1 从“AI 工具”到“AI 助手”这里说的“AI 工具”不是指某个具体 App而是以大语言模型为基础、面向特定场景的能力封装。比如AI 问答用户输入问题系统返回答案。AI 摘要把长文章压缩成要点。AI 分类/推荐判断用户兴趣推荐相关内容。AI 内容生成根据素材打草稿、生成日报。它们都属于“AI 工具”的范畴。区别在于工具是单一能力AI 助手则是把多种能力组合起来围绕一个完整场景提供服务。2.2 RAG 是什么为什么老产品需要它RAG全称 Retrieval-Augmented Generation直译是“检索增强生成”。它的核心思路是模型回答问题时不直接靠自身记忆而是先从外部知识库检索相关文本再把检索结果拼进提示词让模型基于这些内容生成回答。为什么老产品需要 RAG因为老产品的核心资产是“私有内容”这些内容不在大模型的训练集里。模型可能知道雅虎这个品牌但不知道雅虎某篇财经报道的具体数据。RAG 可以解决这个问题可解释答案有站内内容作为依据。减少幻觉模型不是凭空编而是基于检索材料总结。数据私有外部模型不直接接触全部数据库只拿到检索后的片段。所以RAG 是存量内容产品接入 AI 的第一站。2.3 AI Agent 和普通问答的区别普通问答是“问一句、答一句”模型只根据自身知识或给定提示词回答。AI Agent 则更接近“能动手干活的小助手”。它不仅能回答还能使用工具、分步规划、观察结果后再回答。最简单的 Agent 流程如下用户提问。模型判断这个问题是否需要调用工具。如果需要模型输出一个“工具调用指令”。程序执行工具把结果返回给模型。模型结合工具结果生成最终回答。在雅虎这类内容站场景里Agent 的典型应用是用户问“今天有什么重要财经资讯”AI 先调用资讯检索工具再汇总生成一份早报用户问“我邮箱里有没有未读邮件”AI 调用邮箱接口再把结果整理成自然语言。这比固定流程的问答灵活得多。3. 环境准备与项目结构3.1 运行环境本文的示例项目以 Python 3.10 为基准操作系统不限Windows、macOS、Linux 都可以。代码依赖三个核心库openai调用大模型接口和 Embedding 接口。numpy计算向量余弦相似度实现最简单的语义检索。python-dotenv从.env文件读取 API 配置。这里需要说明一点文中示例使用 OpenAI 兼容接口实际项目里可以换成任何支持 OpenAI 协议的大模型服务比如本地部署模型、云厂商模型、国内开源模型等。具体模型名称和 base_url 请按你实际使用的服务商调整。版本不需要完全固定以pip实际安装到的最新稳定版为准。建议使用虚拟环境隔离依赖避免和系统环境冲突。3.2 项目初始化与依赖先在命令行创建项目目录和虚拟环境mkdir retro_ai_assistant cd retro_ai_assistant python -m venv venv source venv/bin/activateWindows 下激活命令使用venv\Scripts\activate然后安装依赖pip install openai numpy python-dotenv为了统一管理配置在项目根目录创建.env文件touch .env.env文件内容如下OPENAI_API_KEY你的_API_Key OPENAI_BASE_URLhttps://api.openai.com/v1 EMBEDDING_MODELtext-embedding-3-small CHAT_MODELgpt-4o-mini TOP_K3如果你使用的是国内模型服务把OPENAI_BASE_URL改成服务商提供的地址即可。模型名称也要改成对应服务支持的值。这里需要提醒不要把 API Key 提交到 Git 仓库.env应加入.gitignore。3.3 目录结构与说明示例项目采用极简结构方便理解每个文件的作用retro_ai_assistant/ ├── .env # API 配置 ├── requirements.txt # 依赖清单 ├── config.py # 读取配置 ├── ingest.py # 内容切片 向量化 保存索引 ├── assistant.py # 检索问答主程序 ├── agent_demo.py # Agent 工具调用演示 └── data/ └── articles.md # 演示用内容数据requirements.txt内容如下openai1.0.0 numpy1.24.0 python-dotenv1.0.0config.py负责统一读取环境变量import os from dotenv import load_dotenv load_dotenv() API_KEY os.getenv(OPENAI_API_KEY, ) BASE_URL os.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) EMBEDDING_MODEL os.getenv(EMBEDDING_MODEL, text-embedding-3-small) CHAT_MODEL os.getenv(CHAT_MODEL, gpt-4o-mini) TOP_K int(os.getenv(TOP_K, 3))这里的TOP_K代表检索时返回几条相关内容。数值太小可能漏信息太大则浪费 token先设置为 3 比较合适。4. 实战为内容站接入 AI 问答与智能体能力4.1 准备演示内容数据真实项目中内容来自 CMS、数据库、API 或爬虫。这里为了演示直接在data/articles.md里放几段模拟内容贴近一个“老牌内容站”的日常素材。文件路径data/articles.md## 互联网早期门户的流量密码 20 世纪末的门户网站依靠首页聚合新闻、搜索、邮箱和社群用一套入口逻辑解决了用户上网的第一步。雅虎是其中最具代表性的品牌之一因此积累了庞大的内容库与用户心智。 ## 为什么老牌内容站还有价值 老牌内容站的真正壁垒不是网站皮肤而是多年沉淀的垂直领域文章、数据、品牌信任和固定用户群。这些资产在 AI 时代可以被重新加工变成问答知识库、摘要、个性化推荐等新功能。 ## 财经频道如何用 AI 生成早报 假设一个财经频道每天早上自动汇总前一日行情、重要公告和机构观点用 AI 生成一份 5 分钟早报。这个功能并不需要重新开发复杂系统而是把已有资讯通过检索、摘要与模板化生成组合起来。 ## 体育频道如何做实时问答助手 体育用户高频问题往往是“昨天比赛谁赢了”“球队下一场什么时候”。如果用 AI 直接回答可能产生幻觉更稳妥的方式是先检索站内赛程和战报再让模型基于检索结果组织答案。这些内容量不大但足够演示完整流程。注意正式项目不能这样把内容写死在 Markdown 里要建立内容采集和更新链路。4.2 内容切片与向量化入库为什么要切片因为大模型对单次输入的长度有限制同时检索粒度太粗会导致结果不精准。把长文章按标题拆成一篇篇独立文本每一篇生成一个向量检索时就能精确命中用户最关心的那一篇。向量化是把文本变成一组浮点数让语义相近的文本在向量空间里距离更近。这里使用 Embedding 模型完成。文件路径ingest.pyimport json import re import numpy as np from openai import OpenAI from config import API_KEY, BASE_URL, EMBEDDING_MODEL client OpenAI(api_keyAPI_KEY, base_urlBASE_URL) def read_articles(path: str): with open(path, r, encodingutf-8) as f: text f.read() blocks re.split(r\n##\s, text) articles [] for block in blocks: lines block.strip().split(\n, 1) if len(lines) 2: continue title lines[0].strip() body lines[1].strip() if title and body: articles.append({title: title, content: body[:800]}) return articles def get_embedding(text: str): resp client.embeddings.create( modelEMBEDDING_MODEL, inputtext ) return resp.data[0].embedding def main(): articles read_articles(data/articles.md) vectors [] for article in articles: vec get_embedding(article[title] \n article[content]) vectors.append(vec) print(f已向量化{article[title]}) with open(vectors.json, w, encodingutf-8) as f: json.dump({articles: articles, vectors: vectors}, f, ensure_asciiFalse) print(f完成共入库 {len(articles)} 篇内容) if __name__ __main__: main()代码解释read_articles按 Markdown 的##标题切分将每个二级标题视为一篇独立内容。get_embedding调用 Embedding 模型把文本转换为向量。最终把内容和向量都保存到vectors.json方便后续检索复用。运行命令python ingest.py预期输出类似已向量化互联网早期门户的流量密码 已向量化为什么老牌内容站还有价值 已向量化财经频道如何用 AI 生成早报 已向量化体育频道如何做实时问答助手 完成共入库 4 篇内容4.3 实现检索增强问答检索增强问答的核心是先算相似度找到最相关的几篇内容再拼进 prompt让模型基于站内资料回答。文件路径assistant.pyimport json import numpy as np from openai import OpenAI from config import API_KEY, BASE_URL, EMBEDDING_MODEL, CHAT_MODEL, TOP_K client OpenAI(api_keyAPI_KEY, base_urlBASE_URL) def load_index(): with open(vectors.json, r, encodingutf-8) as f: return json.load(f) def cosine_similarity(vec_a, vec_b): a np.array(vec_a) b np.array(vec_b) return a.dot(b) / (np.linalg.norm(a) * np.linalg.norm(b)) def search(query: str, index, top_k: int TOP_K): q_vec client.embeddings.create( modelEMBEDDING_MODEL, inputquery ).data[0].embedding scored [] for i, vec in enumerate(index[vectors]): score cosine_similarity(q_vec, vec) scored.append((score, i)) scored.sort(keylambda x: x[0], reverseTrue) return [index[articles][i] for _, i in scored[:top_k]] def build_prompt(query: str, docs: list) - str: context \n\n.join( f标题{d[title]}\n内容{d[content][:500]} for d in docs ) return f你是一个面向老牌内容站的智能助手。 请优先使用下面提供的站内资料回答用户问题。 如果资料不足以回答请明确说明“站内还没有相关信息”再结合通用知识给出建议。 站内资料 {context} 用户问题{query} def ask(query: str): index load_index() docs search(query, index, top_kTOP_K) prompt build_prompt(query, docs) resp client.chat.completions.create( modelCHAT_MODEL, messages[ {role: system, content: 你是一个内容站智能助手回答简洁、准确、友好。}, {role: user, content: prompt} ], temperature0.3 ) return resp.choices[0].message.content def main(): print(AI 助手已启动输入问题开始问答输入 exit 退出。) while True: query input(\n用户).strip() if query.lower() exit: break answer ask(query) print(f\n助手{answer}) if __name__ __main__: main()这里有两个关键点temperature0.3降低随机性让回答更稳定适合内容站问答场景。build_prompt里明确说了“站内资料不足时要承认”这是减少幻觉的第一道防线。运行命令python assistant.py尝试输入“老牌内容站为什么还有价值”预期回答会引用站内资料而不是泛泛而谈。4.4 增加一个最小的 Agent 工具调用RAG 负责处理“知识型问题”但用户还会问“今天星期几”“天气怎么样”“赛事结果是什么”这类实时问题。这时模型自身不知道答案需要调用外部工具。下面实现一个最小的 Agent 循环只包含“获取当前时间”这个工具用来演示完整机制。文件路径agent_demo.pyimport datetime import json from openai import OpenAI from config import API_KEY, BASE_URL, CHAT_MODEL client OpenAI(api_keyAPI_KEY, base_urlBASE_URL) def get_tools(): return [ { type: function, function: { name: get_current_time, description: 获取当前日期和时间, parameters: { type: object, properties: {} } } } ] def run_agent(question: str): messages [ {role: system, content: 你是一个可靠的助手可以调用工具获取实时信息。}, {role: user, content: question} ] resp client.chat.completions.create( modelCHAT_MODEL, messagesmessages, toolsget_tools(), tool_choiceauto ) msg resp.choices[0].message if not msg.tool_calls: return msg.content messages.append(msg) for tool_call in msg.tool_calls: if tool_call.function.name get_current_time: now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) messages.append({ role: tool, tool_call_id: tool_call.id, content: now }) second_resp client.chat.completions.create( modelCHAT_MODEL, messagesmessages ) return second_resp.choices[0].message.content def main(): question input(请输入你的问题) print(run_agent(question)) if __name__ __main__: main()这段代码展示了 Agent 的核心机制系统先把用户的“现在几点”问题发给模型。模型发现需要实时时间返回一个tool_calls指令。程序执行get_current_time函数拿到时间。程序把时间结果以roletool追加到消息列表。模型再次接到包含工具结果的消息生成最终答复。这就是一个不依赖任何 Agent 框架的最小实现。理解之后再上手 LangChain、Spring AI 这类框架会轻松很多。4.5 运行与验证按顺序执行python ingest.py python assistant.py输入“财经频道如何用 AI 生成早报”助手会基于站内资料给出答案。再测试 Agentpython agent_demo.py输入“现在几点了”模型会调用工具返回类似现在是 2025-01-15 14:30:22。这说明“模型自己不知道时间但通过工具调用拿到了实时信息”的闭环已经跑通。5. 常见问题与排查思路问题现象常见原因解决思路接口报 401 错误API Key 配置错误或未加载检查.env文件确认服务商配置正确模型名称不存在服务商不支持当前模型 ID登录模型服务后台换成实际可用的模型名检索结果不相关切片策略不合理或内容太少调整切片粒度增加高质量内容验证 Embedding 效果回答仍然幻觉检索到无关资料被强行拼进 prompt设置相似度阈值低于阈值时明确告诉用户“站内无相关内容”响应速度慢每次请求都重新加载向量索引启动时加载一次索引放入缓存复用token 超限检索到的内容太多或单篇过长降低TOP_K限制单篇截取长度必要时做摘要成本上升快高频问题重复调用大模型对常见问题做缓存简单问题用轻量模型复杂问题才用大模型补充一个高频场景如果使用 Embedding 模型时中文效果差可以优先考虑对中文支持更好的模型。不同服务商的 Embedding 模型在中文语义上的表现差异较大建议用真实业务数据做一个小规模评测再决定使用哪个模型。6. 最佳实践传统产品接入 AI 的工程建议6.1 先选场景再选模型很多项目一开始就追求“全能力 AI 化”结果就是什么都接什么都不稳定。更务实的路径是选一个高频、数据完整、用户痛点明确的场景先落地。比如雅虎这类门户网站第一批适合 AI 化的场景通常是站内搜索增强把传统关键词搜索升级为语义搜索。内容摘要新闻列表生成一句话摘要。智能问答用户不理解某个业务概念时由 AI 基于站内指南回答。信息聚合每天自动生成财经早报、体育战报。场景确定后再根据是否需要实时数据、是否要接入内部系统、成本预算有多大来决定用普通问答、RAG 还是 Agent。6.2 内容与知识库治理RAG 的上限取决于知识库质量。结构混乱、重复度高、过期内容多的库检索效果必然差。工程上需要持续维护定期更新内容移除过期失效数据。内容清洗去重、纠错、统一格式。为内容打标签方便做元数据过滤。记录内容来源和更新时间方便追溯答案。老牌内容站的最大资本是历史内容但历史内容不等于高质量知识库。想用 AI 盘活存量资产第一步往往是数据治理而不是调模型。6.3 权限、安全与隐私边界当一个 AI 助手接入站内内容后要特别关注两点。第一不能把未公开数据泄露给模型服务商。如果模型接口在公网内部稿件、用户隐私数据不应该直接发送。可以采用私有化部署模型或在发送前做脱敏、过滤、最小化截取。第二Agent 工具调用必须做鉴权和授权。让 AI 调用查询接口之前要确认当前用户有没有权限访问对应数据。建议遵循最小权限原则每个工具只开放必要的数据范围所有调用记录落日志。6.4 灰度发布与效果评估AI 功能上线不能只靠“看起来能答”。建议准备一个评测集包含典型用户问题、标准答案、期望引用来源每次修改 prompt 或模型都跑一遍。上线节奏可以采用灰度策略内部小范围试用。白名单用户开放。全量发布后持续收集用户反馈。同时记录每个问答的命中率、点赞/点踩、超时率、成本消耗用数据判断 AI 助手是否真的帮用户解决了问题。7. 总结与下一步雅虎计划借助 AI 工具重振业务、兰佐内强调“复古”是最大优势这件事对技术开发者也有启发老产品不需要推倒重来更重要的是把存量内容资产用新的交互方式重新表达。本文从工程角度实现了一个最小可运行的内容站 AI 助手覆盖了内容切片、向量化检索、RAG 问答和 Agent 工具调用。如果你现在也在负责一个有历史积累的产品可以先用这套原型验证“AI 存量内容”是否成立。先把一个小场景跑通再逐步扩展工具链、优化检索质量、完善评估体系。下一步值得学习的方向包括引入多轮对话记忆、扩展更多业务工具、把向量数据库替换成生产级方案、加入缓存和限流、设计更完善的评测集。AI 不是用来替代老产品的而是让老产品重新被用户用起来。“复古”优势的真正含义是把别人没有的沉淀变成新体验的底座。
返回列表