1. 项目概述当AI研究员不再“胡说八道”在金融投资领域信息就是一切。过去几年我见过太多朋友和同行被各种所谓的“AI投资助手”或“智能研报生成器”坑过。这些工具往往基于通用大语言模型它们能流畅地写出长篇大论分析公司前景甚至给出买入建议。但问题在于它们经常“一本正经地胡说八道”——也就是我们常说的“幻觉”Hallucination。比如把一家公司的营收数据张冠李戴虚构出根本不存在的财报电话会议要点或者基于过时的信息得出完全错误的结论。在股票研究这种对数据准确性要求近乎苛刻的领域这种幻觉是致命的轻则误导判断重则造成真金白银的损失。因此构建一个“不胡说八道的股票研究智能体”其核心目标非常明确在充分利用大语言模型LLM强大的信息整合与推理能力的同时从根本上遏制其“编造”的倾向确保其输出的每一个数据点、每一条分析结论都有可靠、可追溯的来源作为支撑。这不仅仅是一个技术项目更是一个在严肃应用场景下如何将前沿AI能力“驯化”为可靠工具的工程实践。它适合所有对量化投资、基本面分析自动化感兴趣的研究员、开发者以及任何希望将AI应用于高精度信息处理场景的团队。最终我们希望得到的不是一个夸夸其谈的聊天机器人而是一个严谨、沉默、高效的“数字研究助理”它能7x24小时地扫描海量信息并始终如一地提供基于事实的深度分析。2. 核心设计思路用“管道”与“枷锁”约束创造力要让一个基于LLM的智能体变得可靠我们不能指望模型自己突然“良心发现”不再编造。相反我们必须从系统架构上入手为它设计一套“工作流程”和“行为规范”强制其输出必须建立在已验证的事实基础上。我的设计思路可以概括为“检索增强生成RAG为核心多阶段验证为保障工具调用为执行手段”的三层架构。2.1 为何选择RAG而非微调面对幻觉问题很多人第一个想到的是对模型进行领域微调Fine-tuning向模型灌输大量的金融知识和历史数据期望它“学习”到正确的知识。但在动态变化的股票研究领域这存在根本性缺陷。首先金融市场信息瞬息万变财报季度更新新闻每分钟都在产生微调模型的知识截止日期是固定的无法获取最新信息。其次微调无法从根本上解决模型“捏造”底层事实的倾向它只是提高了在训练数据分布内回答的准确性对于训练数据之外的问题幻觉依然存在。因此我选择了检索增强生成Retrieval-Augmented Generation, RAG作为基础架构。它的核心思想是“让模型学会查资料”。在回答用户问题例如“分析一下特斯拉2024年第一季度的汽车交付量及其对毛利率的影响”时系统不会让模型凭空回忆或生成而是会先根据问题从一个专属的、高质量的知识库如最新的财报PDF、权威新闻稿、SEC filings中检索出最相关的文档片段。然后将这些检索到的片段作为“证据”或“上下文”连同问题一起提交给模型指令模型“请严格依据以下提供的资料进行回答。” 这样模型的答案就被“锚定”在了具体的文本证据上大大降低了无中生有的风险。2.2 智能体的“工具箱”思维一个高级的研究智能体不能只会读死书。它需要能够主动获取信息、进行计算、验证数据一致性。这就需要引入“智能体Agent”的概念并为其配备“工具”Tools。我们可以把智能体看作一个具备规划能力的中枢它接收任务后会自主决定调用哪些工具、按什么顺序执行。对于股票研究核心工具包括网络搜索工具用于获取最新的市场新闻、分析师观点、宏观数据。需要对接如SerpAPI、Exa.ai等经过处理的搜索API避免直接访问原始网页的杂乱信息。金融数据API工具用于获取结构化的历史股价、财务报表数据利润表、资产负债表、现金流量表、估值指标等。例如接入Alpha Vantage、Polygon.io或雅虎财经API。文档检索工具即RAG的核心从本地向量数据库检索已处理的公司年报、季报、招股说明书等。计算工具一个Python代码解释器如LangChain的PythonREPLTool用于执行自定义的财务比率计算如计算毛利率、市盈率、数据可视化或简单的统计分析。智能体的工作流就变成了规划任务 - 调用搜索工具获取最新动态 - 调用数据API获取量化指标 - 调用文档检索工具获取管理层论述和细节 - 调用计算工具进行整合分析 - 生成最终报告。每一步的输入和输出都尽可能结构化为后续验证提供基础。2.3 多阶段验证与溯源机制即使有了RAG和工具调用我们仍需对模型的输出保持警惕。因此必须设计额外的验证层。答案溯源Answer Citing强制要求模型在输出的每一个关键论断特别是数据后面以类似[来源1]的格式标明其依据的文档块编号。这不仅能增加可信度也方便人工复查。自我一致性检查Self-Consistency Check对于一些关键问题如“本季度净利润是多少”可以让模型或另一个轻量级模型基于检索到的不同来源片段分别生成答案然后比较这些答案是否一致。如果不一致则触发警报或选择置信度最高的来源或在报告中明确指出数据存在冲突。事实核查Fact-Checking对于模型生成的总结性陈述如“公司面临激烈的市场竞争”可以将其拆解成若干可验证的原子事实然后再次使用检索工具去知识库中寻找支持或反对这些原子事实的证据。这是一个更复杂但更彻底的方法。通过这三层设计我们构建的智能体就不再是一个“黑箱”而是一个可审计、可验证、每一步都有据可查的分析系统。3. 系统构建与核心组件实操下面我将以一个具体的例子——构建一个分析美股上市公司比如NVIDIA的智能体——来拆解实操步骤。技术栈我选择Python生态中较为成熟的LangChain和LlamaIndex框架因为它们提供了大量开箱即用的模块来搭建RAG和智能体系统。3.1 知识库构建数据源的质控是生命线垃圾进垃圾出。如果喂给模型的数据本身就是错误或过时的那么再好的系统也无法输出正确结果。因此构建一个干净、可靠、结构化的知识库是第一步也是最关键的一步。数据源选择官方披露文件从SEC官网EDGAR数据库获取公司的10-K年报、10-Q季报、8-K重大事件报告。这些是法律文件准确性最高应作为核心知识源。投资者关系材料公司官网投资者关系板块的财报演示文稿Earnings Presentation、财报电话会议记录稿Transcript。这些材料包含了管理层对数据的解读和未来展望价值极高。权威财经新闻来自Reuters、Bloomberg、华尔街日报等权威媒体的新闻报道。可以通过RSS订阅或API获取但需注意过滤观点性文章优先选择事实报道。数据处理流水线原始PDF、HTML文档需要被转化为模型可以理解和检索的格式。# 示例使用LlamaIndex的文档加载与解析器 from llama_index.core import SimpleDirectoryReader from llama_index.core.node_parser import SentenceSplitter # 1. 加载文档 documents SimpleDirectoryReader(./data/nvidia_sec_filings).load_data() # 2. 文档分块Chunking # 财务文档分块有讲究不能随意切断句子。建议按章节或固定长度重叠分块。 node_parser SentenceSplitter( chunk_size1024, # 每个块的大小 chunk_overlap200, # 块之间的重叠部分避免上下文断裂 separator\n ) nodes node_parser.get_nodes_from_documents(documents) # 3. 为每个块生成嵌入Embedding并存入向量数据库 from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.vector_stores.chroma import ChromaVectorStore import chromadb embed_model OpenAIEmbedding(modeltext-embedding-3-small) chroma_client chromadb.PersistentClient(path./chroma_db) vector_store ChromaVectorStore(chroma_collectionchroma_client.create_collection(nvidia_filings)) storage_context StorageContext.from_defaults(vector_storevector_store) index VectorStoreIndex(nodes, embed_modelembed_model, storage_contextstorage_context)注意分块策略对检索质量影响巨大。对于财报尝试按“业务概述”、“风险因素”、“管理层讨论与分析MDA”、“财务报表附注”等自然章节进行分块效果远好于简单的固定长度分块。重叠overlap设置能有效防止关键信息因恰好被切断而无法被检索到。3.2 检索器的优化不仅仅是语义搜索基础的语义搜索基于嵌入向量的相似度有时会漏掉关键信息。我们需要对其进行增强。混合检索Hybrid Search结合密集向量检索语义相似度和稀疏向量检索关键词匹配如BM25。例如查询“NVIDIA Data Center revenue growth Q4 2024”语义搜索可能找到关于数据中心业务的段落而关键词“Q4 2024”能通过BM25精准定位到特定季度。LangChain可以轻松集成Chroma支持密集检索和rank_bm25稀疏检索。元数据过滤为每个文档块添加丰富的元数据如document_type: “10-Q”,fiscal_year: 2024,fiscal_quarter: “Q1”,section: “Income Statement”。在检索时可以先通过元数据进行筛选例如“只检索2024年Q1财报中关于利润表的部分”然后再进行语义搜索这能极大提升检索精度和速度。重排序Re-Ranking初步检索可能返回10-20个相关块但其中与问题最相关的可能只有前3个。使用一个轻量级的交叉编码器Cross-Encoder模型如BAAI/bge-reranker-large对初筛结果进行重新打分和排序将最相关的块排到最前面再送给LLM作为上下文。这一步能显著改善答案质量。3.3 智能体与工具链的搭建我们使用LangChain的智能体框架来组装这个“数字研究员”。from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.tools import Tool from langchain_community.tools import DuckDuckGoSearchRun from langchain_experimental.tools import PythonREPLTool # 1. 定义LLM llm ChatOpenAI(modelgpt-4-turbo-preview, temperature0) # temperature设为0降低随机性 # 2. 定义工具 # 工具一RAG检索工具基于之前构建的index query_engine index.as_query_engine(similarity_top_k5) # 检索前5个相关块 def rag_query(input_str): response query_engine.query(input_str) return fAnswer: {response.response}\nSources: {[node.node_id for node in response.source_nodes]} rag_tool Tool( nameCompany_Filings_Search, funcrag_query, descriptionUseful for searching through NVIDIAs official SEC filings (10-K, 10-Q) and earnings transcripts. Input should be a specific question about financials, operations, or risks. ) # 工具二网络搜索工具需配置API Key search DuckDuckGoSearchRun() search_tool Tool( nameWeb_Search, funcsearch.run, descriptionUseful for finding recent news, market analysis, or current events about NVIDIA. Use for questions about latest developments not in the filings. ) # 工具三Python计算工具 python_repl_tool PythonREPLTool() # 3. 构建智能体提示词 prompt ChatPromptTemplate.from_messages([ (system, You are a meticulous and accurate stock research analyst. Your task is to answer questions about NVIDIA (NVDA) stock. **CRITICAL RULES:** 1. You MUST use the tools to gather information. DO NOT rely on your internal knowledge. 2. For any factual claim, especially numbers (revenue, EPS, etc.), you MUST use the Company_Filings_Search tool to find the source. 3. For recent news or events not in the filings, use the Web_Search tool. 4. For calculations (e.g., compute gross margin percentage), use the Python_REPL tool. 5. In your final answer, CITE your sources. For data from filings, mention the document type and period (e.g., [10-Q Q1 2024]). For news, mention the headline and date. 6. If different sources conflict, acknowledge the discrepancy and state which source you are primarily relying on and why. 7. If you cannot find sufficient information to answer confidently, say so. DO NOT HALLUCINATE.), MessagesPlaceholder(variable_namechat_history), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), ]) # 4. 创建并运行智能体 tools [rag_tool, search_tool, python_repl_tool] agent create_openai_tools_agent(llm, tools, prompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) result agent_executor.invoke({ input: What was NVIDIAs Data Center revenue growth rate from Q1 FY2024 to Q1 FY2025? Also, find any recent news about new data center chip announcements and calculate the projected impact if the new chip achieves 30% more performance at the same cost. }) print(result[output])这个智能体被赋予了明确的指令和工具使用规范。当它收到一个复杂问题时它会自主规划先调用Company_Filings_Search查找两个季度的数据中心营收数据然后调用Python_REPL计算增长率同时调用Web_Search查找关于新芯片的新闻最后综合所有信息并可能再次调用Python_REPL进行简单的假设性影响测算。在整个过程中它被严格要求引用来源。4. 对抗幻觉的进阶策略与实战心得即使有了上述架构在实际运行中幻觉仍可能从缝隙中钻进来。以下是我在实战中总结的进阶策略和踩坑经验。4.1 提示词工程的魔鬼细节系统提示词System Prompt是智能体的“宪法”其措辞至关重要。除了上述示例中的基本规则还有几个关键点明确禁止性指令直接使用“You are prohibited from...”、“You must not generate information that cannot be verified by the provided tools.”等强否定句式。设定角色与风格强调“你是一个保守的、注重事实的金融分析师”这能潜移默化地影响生成风格。分步思考指令在提示词中鼓励模型“逐步推理”Let‘s think step by step并展示其使用工具的过程。这不仅能提高准确性也使得整个推理过程更透明。我们可以使用LangChain的AgentScratchPad来让模型输出其思考链。4.2 实施“后验”事实核查在智能体生成最终答案后可以添加一个独立的事实核查环节。这个环节可以使用一个更小、更快的模型如GPT-3.5-Turbo专门负责完成以下任务提取声明从长答案中提取出所有事实性声明例如“Q1 FY2025 Data Center revenue was $18.4 billion.”。验证声明针对每个声明将其转化为一个查询再次调用RAG检索工具检查知识库中是否存在支持性证据。生成置信度报告为每个声明标注“已核实”、“部分核实”如数据对但语境略有不同、“未找到支持”或“发现矛盾”。 最终输出时可以将这个置信度报告作为附录或者让主智能体根据核查结果修正答案。4.3 常见问题与排查实录在开发和测试过程中我遇到了几个典型问题及其解决方案问题一检索结果看似相关但答非所问。现象问“毛利率变化原因”模型检索到了正确的财务报表片段但回答却泛泛而谈“成本控制”没有引用具体数据。根因提示词指令不够强硬或者上下文检索到的文本块太长、噪音太多模型没有聚焦到关键信息。解决强化提示词“你的回答必须直接引用检索文本中的具体数字和句子来支持你的观点。”优化检索使用更小的chunk_size并启用重排序确保喂给模型的都是最精炼、最相关的上下文。采用“Map-Reduce”策略先将复杂问题拆解成子问题分别检索回答再汇总。问题二模型忽略工具结果依赖内部知识。现象即使工具返回了2024年的数据模型仍可能基于其2023年初的训练数据记忆说出“截至2023年...”这样的过时信息。根因模型固有知识过于强大有时会覆盖掉提供的上下文。解决在提示词开头使用强有力的“忽略指令”“完全忽略你在2023年7月之前学到的任何关于NVIDIA财务数据的信息。你唯一的信息来源是下面提供的工具。”使用更新、知识截止日期更近的模型如GPT-4 Turbo。在工具返回的结果中以醒目的格式如##OFFICIAL_DATA##: ...包装数据并在提示词中要求模型优先使用这种格式的内容。问题三多步骤计算中出错。现象问题涉及多步计算如基于营收和成本计算利润率再与去年同期比较增长率模型在调用Python工具时代码逻辑错误。根因模型生成的代码可能存在边界错误或逻辑缺陷。解决为Python工具设计更具体的描述引导模型使用正确的公式。在计算后增加一个“合理性检查”步骤。例如计算出的增长率如果超过1000%或为负数则触发警报要求模型复核或说明原因。将复杂计算拆解让模型分步调用工具并输出中间结果便于调试。问题四处理模糊或矛盾信息。现象对于“公司未来增长动力是什么”这种问题财报中管理层可能给出多个方向而新闻中又有不同说法。根因信息本身存在多元视角这不是幻觉而是真实世界的复杂性。解决这正是智能体体现价值的地方。提示词应指导模型“如果发现来自不同来源的信息存在不同侧重点或潜在矛盾应在回答中汇总这些不同观点并注明各自的来源。避免给出一个单一、武断的结论。” 这样输出就不再是一个“答案”而是一份带有引用的“研究简报”价值更高。构建一个不胡说八道的股票研究智能体是一个在“能力”与“可控”之间寻找平衡的持续过程。没有一劳永逸的银弹它需要精心的架构设计、高质量的数据管道、严谨的提示词工程以及最重要的——对输出结果永不松懈的验证态度。这个智能体不会取代人类分析师的深度判断和行业洞察但它能成为一个不知疲倦、绝对客观的初级研究员高效地完成信息收集、数据整理和初步核验的繁重工作让人类分析师能将精力聚焦于更高层次的策略思考。
基于RAG与智能体技术构建高可靠金融研究AI:从幻觉治理到工程实践
1. 项目概述当AI研究员不再“胡说八道”在金融投资领域信息就是一切。过去几年我见过太多朋友和同行被各种所谓的“AI投资助手”或“智能研报生成器”坑过。这些工具往往基于通用大语言模型它们能流畅地写出长篇大论分析公司前景甚至给出买入建议。但问题在于它们经常“一本正经地胡说八道”——也就是我们常说的“幻觉”Hallucination。比如把一家公司的营收数据张冠李戴虚构出根本不存在的财报电话会议要点或者基于过时的信息得出完全错误的结论。在股票研究这种对数据准确性要求近乎苛刻的领域这种幻觉是致命的轻则误导判断重则造成真金白银的损失。因此构建一个“不胡说八道的股票研究智能体”其核心目标非常明确在充分利用大语言模型LLM强大的信息整合与推理能力的同时从根本上遏制其“编造”的倾向确保其输出的每一个数据点、每一条分析结论都有可靠、可追溯的来源作为支撑。这不仅仅是一个技术项目更是一个在严肃应用场景下如何将前沿AI能力“驯化”为可靠工具的工程实践。它适合所有对量化投资、基本面分析自动化感兴趣的研究员、开发者以及任何希望将AI应用于高精度信息处理场景的团队。最终我们希望得到的不是一个夸夸其谈的聊天机器人而是一个严谨、沉默、高效的“数字研究助理”它能7x24小时地扫描海量信息并始终如一地提供基于事实的深度分析。2. 核心设计思路用“管道”与“枷锁”约束创造力要让一个基于LLM的智能体变得可靠我们不能指望模型自己突然“良心发现”不再编造。相反我们必须从系统架构上入手为它设计一套“工作流程”和“行为规范”强制其输出必须建立在已验证的事实基础上。我的设计思路可以概括为“检索增强生成RAG为核心多阶段验证为保障工具调用为执行手段”的三层架构。2.1 为何选择RAG而非微调面对幻觉问题很多人第一个想到的是对模型进行领域微调Fine-tuning向模型灌输大量的金融知识和历史数据期望它“学习”到正确的知识。但在动态变化的股票研究领域这存在根本性缺陷。首先金融市场信息瞬息万变财报季度更新新闻每分钟都在产生微调模型的知识截止日期是固定的无法获取最新信息。其次微调无法从根本上解决模型“捏造”底层事实的倾向它只是提高了在训练数据分布内回答的准确性对于训练数据之外的问题幻觉依然存在。因此我选择了检索增强生成Retrieval-Augmented Generation, RAG作为基础架构。它的核心思想是“让模型学会查资料”。在回答用户问题例如“分析一下特斯拉2024年第一季度的汽车交付量及其对毛利率的影响”时系统不会让模型凭空回忆或生成而是会先根据问题从一个专属的、高质量的知识库如最新的财报PDF、权威新闻稿、SEC filings中检索出最相关的文档片段。然后将这些检索到的片段作为“证据”或“上下文”连同问题一起提交给模型指令模型“请严格依据以下提供的资料进行回答。” 这样模型的答案就被“锚定”在了具体的文本证据上大大降低了无中生有的风险。2.2 智能体的“工具箱”思维一个高级的研究智能体不能只会读死书。它需要能够主动获取信息、进行计算、验证数据一致性。这就需要引入“智能体Agent”的概念并为其配备“工具”Tools。我们可以把智能体看作一个具备规划能力的中枢它接收任务后会自主决定调用哪些工具、按什么顺序执行。对于股票研究核心工具包括网络搜索工具用于获取最新的市场新闻、分析师观点、宏观数据。需要对接如SerpAPI、Exa.ai等经过处理的搜索API避免直接访问原始网页的杂乱信息。金融数据API工具用于获取结构化的历史股价、财务报表数据利润表、资产负债表、现金流量表、估值指标等。例如接入Alpha Vantage、Polygon.io或雅虎财经API。文档检索工具即RAG的核心从本地向量数据库检索已处理的公司年报、季报、招股说明书等。计算工具一个Python代码解释器如LangChain的PythonREPLTool用于执行自定义的财务比率计算如计算毛利率、市盈率、数据可视化或简单的统计分析。智能体的工作流就变成了规划任务 - 调用搜索工具获取最新动态 - 调用数据API获取量化指标 - 调用文档检索工具获取管理层论述和细节 - 调用计算工具进行整合分析 - 生成最终报告。每一步的输入和输出都尽可能结构化为后续验证提供基础。2.3 多阶段验证与溯源机制即使有了RAG和工具调用我们仍需对模型的输出保持警惕。因此必须设计额外的验证层。答案溯源Answer Citing强制要求模型在输出的每一个关键论断特别是数据后面以类似[来源1]的格式标明其依据的文档块编号。这不仅能增加可信度也方便人工复查。自我一致性检查Self-Consistency Check对于一些关键问题如“本季度净利润是多少”可以让模型或另一个轻量级模型基于检索到的不同来源片段分别生成答案然后比较这些答案是否一致。如果不一致则触发警报或选择置信度最高的来源或在报告中明确指出数据存在冲突。事实核查Fact-Checking对于模型生成的总结性陈述如“公司面临激烈的市场竞争”可以将其拆解成若干可验证的原子事实然后再次使用检索工具去知识库中寻找支持或反对这些原子事实的证据。这是一个更复杂但更彻底的方法。通过这三层设计我们构建的智能体就不再是一个“黑箱”而是一个可审计、可验证、每一步都有据可查的分析系统。3. 系统构建与核心组件实操下面我将以一个具体的例子——构建一个分析美股上市公司比如NVIDIA的智能体——来拆解实操步骤。技术栈我选择Python生态中较为成熟的LangChain和LlamaIndex框架因为它们提供了大量开箱即用的模块来搭建RAG和智能体系统。3.1 知识库构建数据源的质控是生命线垃圾进垃圾出。如果喂给模型的数据本身就是错误或过时的那么再好的系统也无法输出正确结果。因此构建一个干净、可靠、结构化的知识库是第一步也是最关键的一步。数据源选择官方披露文件从SEC官网EDGAR数据库获取公司的10-K年报、10-Q季报、8-K重大事件报告。这些是法律文件准确性最高应作为核心知识源。投资者关系材料公司官网投资者关系板块的财报演示文稿Earnings Presentation、财报电话会议记录稿Transcript。这些材料包含了管理层对数据的解读和未来展望价值极高。权威财经新闻来自Reuters、Bloomberg、华尔街日报等权威媒体的新闻报道。可以通过RSS订阅或API获取但需注意过滤观点性文章优先选择事实报道。数据处理流水线原始PDF、HTML文档需要被转化为模型可以理解和检索的格式。# 示例使用LlamaIndex的文档加载与解析器 from llama_index.core import SimpleDirectoryReader from llama_index.core.node_parser import SentenceSplitter # 1. 加载文档 documents SimpleDirectoryReader(./data/nvidia_sec_filings).load_data() # 2. 文档分块Chunking # 财务文档分块有讲究不能随意切断句子。建议按章节或固定长度重叠分块。 node_parser SentenceSplitter( chunk_size1024, # 每个块的大小 chunk_overlap200, # 块之间的重叠部分避免上下文断裂 separator\n ) nodes node_parser.get_nodes_from_documents(documents) # 3. 为每个块生成嵌入Embedding并存入向量数据库 from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.vector_stores.chroma import ChromaVectorStore import chromadb embed_model OpenAIEmbedding(modeltext-embedding-3-small) chroma_client chromadb.PersistentClient(path./chroma_db) vector_store ChromaVectorStore(chroma_collectionchroma_client.create_collection(nvidia_filings)) storage_context StorageContext.from_defaults(vector_storevector_store) index VectorStoreIndex(nodes, embed_modelembed_model, storage_contextstorage_context)注意分块策略对检索质量影响巨大。对于财报尝试按“业务概述”、“风险因素”、“管理层讨论与分析MDA”、“财务报表附注”等自然章节进行分块效果远好于简单的固定长度分块。重叠overlap设置能有效防止关键信息因恰好被切断而无法被检索到。3.2 检索器的优化不仅仅是语义搜索基础的语义搜索基于嵌入向量的相似度有时会漏掉关键信息。我们需要对其进行增强。混合检索Hybrid Search结合密集向量检索语义相似度和稀疏向量检索关键词匹配如BM25。例如查询“NVIDIA Data Center revenue growth Q4 2024”语义搜索可能找到关于数据中心业务的段落而关键词“Q4 2024”能通过BM25精准定位到特定季度。LangChain可以轻松集成Chroma支持密集检索和rank_bm25稀疏检索。元数据过滤为每个文档块添加丰富的元数据如document_type: “10-Q”,fiscal_year: 2024,fiscal_quarter: “Q1”,section: “Income Statement”。在检索时可以先通过元数据进行筛选例如“只检索2024年Q1财报中关于利润表的部分”然后再进行语义搜索这能极大提升检索精度和速度。重排序Re-Ranking初步检索可能返回10-20个相关块但其中与问题最相关的可能只有前3个。使用一个轻量级的交叉编码器Cross-Encoder模型如BAAI/bge-reranker-large对初筛结果进行重新打分和排序将最相关的块排到最前面再送给LLM作为上下文。这一步能显著改善答案质量。3.3 智能体与工具链的搭建我们使用LangChain的智能体框架来组装这个“数字研究员”。from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.tools import Tool from langchain_community.tools import DuckDuckGoSearchRun from langchain_experimental.tools import PythonREPLTool # 1. 定义LLM llm ChatOpenAI(modelgpt-4-turbo-preview, temperature0) # temperature设为0降低随机性 # 2. 定义工具 # 工具一RAG检索工具基于之前构建的index query_engine index.as_query_engine(similarity_top_k5) # 检索前5个相关块 def rag_query(input_str): response query_engine.query(input_str) return fAnswer: {response.response}\nSources: {[node.node_id for node in response.source_nodes]} rag_tool Tool( nameCompany_Filings_Search, funcrag_query, descriptionUseful for searching through NVIDIAs official SEC filings (10-K, 10-Q) and earnings transcripts. Input should be a specific question about financials, operations, or risks. ) # 工具二网络搜索工具需配置API Key search DuckDuckGoSearchRun() search_tool Tool( nameWeb_Search, funcsearch.run, descriptionUseful for finding recent news, market analysis, or current events about NVIDIA. Use for questions about latest developments not in the filings. ) # 工具三Python计算工具 python_repl_tool PythonREPLTool() # 3. 构建智能体提示词 prompt ChatPromptTemplate.from_messages([ (system, You are a meticulous and accurate stock research analyst. Your task is to answer questions about NVIDIA (NVDA) stock. **CRITICAL RULES:** 1. You MUST use the tools to gather information. DO NOT rely on your internal knowledge. 2. For any factual claim, especially numbers (revenue, EPS, etc.), you MUST use the Company_Filings_Search tool to find the source. 3. For recent news or events not in the filings, use the Web_Search tool. 4. For calculations (e.g., compute gross margin percentage), use the Python_REPL tool. 5. In your final answer, CITE your sources. For data from filings, mention the document type and period (e.g., [10-Q Q1 2024]). For news, mention the headline and date. 6. If different sources conflict, acknowledge the discrepancy and state which source you are primarily relying on and why. 7. If you cannot find sufficient information to answer confidently, say so. DO NOT HALLUCINATE.), MessagesPlaceholder(variable_namechat_history), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), ]) # 4. 创建并运行智能体 tools [rag_tool, search_tool, python_repl_tool] agent create_openai_tools_agent(llm, tools, prompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) result agent_executor.invoke({ input: What was NVIDIAs Data Center revenue growth rate from Q1 FY2024 to Q1 FY2025? Also, find any recent news about new data center chip announcements and calculate the projected impact if the new chip achieves 30% more performance at the same cost. }) print(result[output])这个智能体被赋予了明确的指令和工具使用规范。当它收到一个复杂问题时它会自主规划先调用Company_Filings_Search查找两个季度的数据中心营收数据然后调用Python_REPL计算增长率同时调用Web_Search查找关于新芯片的新闻最后综合所有信息并可能再次调用Python_REPL进行简单的假设性影响测算。在整个过程中它被严格要求引用来源。4. 对抗幻觉的进阶策略与实战心得即使有了上述架构在实际运行中幻觉仍可能从缝隙中钻进来。以下是我在实战中总结的进阶策略和踩坑经验。4.1 提示词工程的魔鬼细节系统提示词System Prompt是智能体的“宪法”其措辞至关重要。除了上述示例中的基本规则还有几个关键点明确禁止性指令直接使用“You are prohibited from...”、“You must not generate information that cannot be verified by the provided tools.”等强否定句式。设定角色与风格强调“你是一个保守的、注重事实的金融分析师”这能潜移默化地影响生成风格。分步思考指令在提示词中鼓励模型“逐步推理”Let‘s think step by step并展示其使用工具的过程。这不仅能提高准确性也使得整个推理过程更透明。我们可以使用LangChain的AgentScratchPad来让模型输出其思考链。4.2 实施“后验”事实核查在智能体生成最终答案后可以添加一个独立的事实核查环节。这个环节可以使用一个更小、更快的模型如GPT-3.5-Turbo专门负责完成以下任务提取声明从长答案中提取出所有事实性声明例如“Q1 FY2025 Data Center revenue was $18.4 billion.”。验证声明针对每个声明将其转化为一个查询再次调用RAG检索工具检查知识库中是否存在支持性证据。生成置信度报告为每个声明标注“已核实”、“部分核实”如数据对但语境略有不同、“未找到支持”或“发现矛盾”。 最终输出时可以将这个置信度报告作为附录或者让主智能体根据核查结果修正答案。4.3 常见问题与排查实录在开发和测试过程中我遇到了几个典型问题及其解决方案问题一检索结果看似相关但答非所问。现象问“毛利率变化原因”模型检索到了正确的财务报表片段但回答却泛泛而谈“成本控制”没有引用具体数据。根因提示词指令不够强硬或者上下文检索到的文本块太长、噪音太多模型没有聚焦到关键信息。解决强化提示词“你的回答必须直接引用检索文本中的具体数字和句子来支持你的观点。”优化检索使用更小的chunk_size并启用重排序确保喂给模型的都是最精炼、最相关的上下文。采用“Map-Reduce”策略先将复杂问题拆解成子问题分别检索回答再汇总。问题二模型忽略工具结果依赖内部知识。现象即使工具返回了2024年的数据模型仍可能基于其2023年初的训练数据记忆说出“截至2023年...”这样的过时信息。根因模型固有知识过于强大有时会覆盖掉提供的上下文。解决在提示词开头使用强有力的“忽略指令”“完全忽略你在2023年7月之前学到的任何关于NVIDIA财务数据的信息。你唯一的信息来源是下面提供的工具。”使用更新、知识截止日期更近的模型如GPT-4 Turbo。在工具返回的结果中以醒目的格式如##OFFICIAL_DATA##: ...包装数据并在提示词中要求模型优先使用这种格式的内容。问题三多步骤计算中出错。现象问题涉及多步计算如基于营收和成本计算利润率再与去年同期比较增长率模型在调用Python工具时代码逻辑错误。根因模型生成的代码可能存在边界错误或逻辑缺陷。解决为Python工具设计更具体的描述引导模型使用正确的公式。在计算后增加一个“合理性检查”步骤。例如计算出的增长率如果超过1000%或为负数则触发警报要求模型复核或说明原因。将复杂计算拆解让模型分步调用工具并输出中间结果便于调试。问题四处理模糊或矛盾信息。现象对于“公司未来增长动力是什么”这种问题财报中管理层可能给出多个方向而新闻中又有不同说法。根因信息本身存在多元视角这不是幻觉而是真实世界的复杂性。解决这正是智能体体现价值的地方。提示词应指导模型“如果发现来自不同来源的信息存在不同侧重点或潜在矛盾应在回答中汇总这些不同观点并注明各自的来源。避免给出一个单一、武断的结论。” 这样输出就不再是一个“答案”而是一份带有引用的“研究简报”价值更高。构建一个不胡说八道的股票研究智能体是一个在“能力”与“可控”之间寻找平衡的持续过程。没有一劳永逸的银弹它需要精心的架构设计、高质量的数据管道、严谨的提示词工程以及最重要的——对输出结果永不松懈的验证态度。这个智能体不会取代人类分析师的深度判断和行业洞察但它能成为一个不知疲倦、绝对客观的初级研究员高效地完成信息收集、数据整理和初步核验的繁重工作让人类分析师能将精力聚焦于更高层次的策略思考。