@helloiamleonie: 从@vboykis那里汲取灵感,将我人生第一次演讲转化为一篇博客文章。我讨论了关于agentic搜索在上下文工程中的角色…
摘要
这篇文章由Leonie Monigatti撰写,讨论了agentic搜索在AI智能体上下文工程中的作用,追溯了从固定RAG流水线到agentic RAG和上下文整理的演变。它提供了关于agentic系统中使用的各种搜索工具优缺点的直观认识。
查看缓存全文
缓存时间: 2026/05/29 14:11
受 @vboykis 启发,我把首次演讲转化成了一篇博客文章。我探讨了自主搜索在上下文工程中的作用。我们将一起建立对一系列搜索工具优劣势的直观理解。https://leoniemonigatti.com/blog/agentic-search-for-context-engineering.html…
面向上下文工程的自主搜索 – Leonie Monigatti
来源:https://leoniemonigatti.com/blog/agentic-search-for-context-engineering.html
本文是对我于 2026 年 4 月 8 日在伦敦AI Engineer Europe 2026 (https://www.ai.engineer/europe/2026) 上所做的“面向上下文工程的自主搜索”研讨会的长篇编辑版。幻灯片、代码和图表均可在研讨会代码仓库 (https://github.com/iamleonie/workshop-agentic-search) 中找到。如果您偏好视频,完整录播可在 YouTube 上观看:
如果您曾经构建过智能体,就会知道上下文工程是让智能体返回有意义响应的关键部分。上下文工程是决定从所有可能的上下文来源中,究竟哪些内容实际进入智能体的上下文窗口,从而让 LLM 生成最佳响应的过程。这也被称为“上下文策展”过程,如下图中从可能的上下文来源指向上下文窗口的箭头所示。
上下文工程本质上就是自主搜索:上下文来源、搜索工具与上下文窗口
我认为我们往往低估了这个上下文策展箭头的作用,因为它几乎承担了所有繁重工作。其背后隐藏的是智能体可以决定使用的一组搜索工具。这正是我个人的核心观点:
上下文工程大约 80% 是自主搜索。
发展历程
让我们回顾一下过去三年中,AI 堆栈中的搜索是如何从检索增强生成 (RAG) (https://leoniemonigatti.com/blog/retrieval-augmented-generation-langchain.html),演进到自主搜索/自主 RAG,再到如今的上下文工程的。(如果您感兴趣,我还写过从 RAG 到智能体记忆的演进 (https://leoniemonigatti.com/blog/from-rag-to-agent-memory.html))。
检索增强生成
当我们 2024 年开始使用 LLM 进行构建时,我们开始实现具有固定检索管道的 RAG 系统:
- 用户消息(几乎原封不动)被用作搜索查询(通常是向量搜索)。
- 从数据库中一次性拉取分块。
- 检索到的分块与用户消息一起组合到提示中,并馈送给 LLM。
RAG 在 LLM 回答之前使用固定的检索管道
这种设计很直观,对于狭窄的问答场景仍然有效。但它也会以可预见的方式失效,因为您只检索一次:
- 即使模型不需要外部上下文,您也只检索一次,不相关的分块可能会让其混淆。
- 您只检索一次,且无法修正查询。如果返回的结果不包含相关信息,而您需要再次搜索呢?
- 即使问题需要多跳检索,您也只检索一次。例如,第一批分块可能只告诉您接下来要搜索什么,但管道永远不会运行第二次。
自主 RAG
为了克服这些限制,我们用搜索工具取代了固定管道,并将其称为“自主 RAG”、“自主检索”或“自主搜索”。在这种场景下,智能体决定是否调用搜索工具、结果是否相关、是否检索更多内容以及是否重写搜索查询。
自主 RAG 将检索暴露为智能体可以调用的工具
在许多设置中,这很直观,因为您通常只有一个或有限的上下文来源和一个检索工具。
上下文工程
在上下文工程中,我们现在有许多不同的上下文来源:
- 本地文件(例如,您的代码仓库、包含
plan.md或todo.md文件的临时记事本,或智能体技能)存储在磁盘上。 - 数据库(例如,存储大规模企业数据)。
- 网络。
- 长期记忆(我故意将其模糊化,因为记忆是驻留在文件还是数据库中仍在争论中 (https://leoniemonigatti.com/blog/filesystem-vs-database-for-agent-memory.qmd))。
上下文工程涵盖许多上下文来源
根据上下文来源的不同,我们通常有一个原生搜索工具:
- 用于本地文件的文件搜索。
- 用于智能体技能的技能加载。
- 用于数据库的专用数据库工具(语义搜索或查询执行)。
- 用于网络的网络搜索。
- 用于长期记忆的记忆工具。
上下文来源原生的搜索工具将来源映射到检索接口
如果这还不够令人眼花缭乱,现在我们还有一个允许智能体运行终端命令的工具。这个工具有许多不同的名称:LangChain 称之为“shell 工具” (https://reference.langchain.com/python/langchain-community/tools/shell/tool/ShellTool),Anthropic 称之为“bash 工具” (https://platform.claude.com/docs/en/agents-and-tools/tool-use/bash-tool),OpenClaw 称之为“exec 工具” (https://docs.openclaw.ai/tools/exec)。在下文中,我们将其称为 “shell 工具” 。Shell 工具是一个通用的工具,因为它可以与大多数上下文来源交互:它可以处理本地文件(ls、grep)、数据库(CLI、脚本、通过 curl 访问 HTTPS API)以及网络(curl)。
Shell 工具可以通过 CLI 访问许多上下文来源
因此,目前有很多讨论关于 shell 工具是否是智能体所需的一切。如果您想深入了解这一讨论,我已在这篇博客中撰写过,标题为 “Shell 工具并非上下文工程的银弹” (https://www.elastic.co/search-labs/blog/search-tools-context-engineering)。该博客的 TLDR 以及本研讨会的核心主题是,实际问题是 “哪些搜索工具应纳入您的堆栈” ,而不是 shell 工具与其他工具的二选一。如果本次研讨会您只记住一点,那就是:
做好搜索很难。正因如此,我们才有如此多不同的搜索技术,您需要根据延迟和质量要求来策展您的堆栈。
在本研讨会中,我们来看一小部分搜索工具,以让您对其优劣势有直观了解。
构建搜索工具的基础知识
在深入探讨具体的搜索工具之前,让我们回顾一下构建有效搜索工具的一些基础知识。
自主搜索的挑战
理论上,自主搜索看起来很简单:
- 用户发出请求。
- 智能体使用正确的参数调用正确的工具。
- 工具返回搜索结果。
- 智能体用正确答案响应。
但实际上,这可能以多种方式失败。在 Elastic,我们帮助团队基于 Elasticsearch 数据构建智能体,以下是我们观察到的三种最常见的失败模式:
- 智能体根本不调用任何工具,而是从参数化知识中回答。
- 智能体调用了错误的工具(例如,使用网络搜索而非公司索引)。
- 智能体调用了正确的工具但使用了错误的参数。
三种常见的自主搜索失败模式
让我们讨论一些克服这些挑战的通用最佳实践,以便在下一节演示时,您能直观地知道该怎么做。如果您对更多最佳实践感兴趣,我还写过一篇关于我们在 Elastic 学到的构建有效数据库检索工具的经验指南 (https://www.elastic.co/search-labs/blog/database-retrieval-tools-context-engineering)。
工具描述
我不太喜欢这张幻灯片,因为我觉得每个人都知道 “工具描述是任何工具最重要的部分” 。不过,我还是快速给您复习一下,因为我每次看到工具描述时,它们往往是最敷衍的一行描述,然后您还在纳闷为什么您的智能体无法正确使用它。
对工具描述进行提示工程,以便智能体调用正确的工具
诚然,这个模板相当长。我并不是说您需要始终遵循这个模板。相反,从一个清晰的核心用途和触发条件开始。当您注意到智能体难以使用您的工具时,开始添加此模板的更多组件,例如操作、关系、限制和示例。如果这还不够,可以在系统提示中重复相同的规则。
参数复杂度
另一个需要注意的方面是参数复杂度。因为一旦选择了正确的工具,智能体仍需填写参数,而有些参数比其他参数更容易填对。例如,get_customer_by_id 工具的参数字段在 ID 出现在消息中时很容易填写。或者,接受任意字符串作为搜索查询的语义搜索工具通常也没问题。但当您开始添加更多参数,例如过滤器或 top_k 时,LLM 生成有效参数可能会变得更加困难。
但如果您的通用搜索工具允许智能体将完整的 SQL 或 ES|QL (https://www.elastic.co/docs/reference/query-languages/esql) 查询作为参数从头编写呢?大多数模型在生成有效的 SQL 查询方面还不错,但这会增加失败的风险。
参数复杂度从简单的 ID 增加到完整的查询语言
代码演练
让我们看一下实际中一小部分搜索工具的实现示例。(我很想展示所有工具,但时间有限。)完整代码可在研讨会代码仓库 (https://github.com/iamleonie/workshop-agentic-search) 中找到。
本次代码演练使用 LangChain (https://docs.langchain.com/) 进行编排,因为它抽象了很多复杂性,使我们能够专注于高层次概念,并且它提供了开箱即用的 shell 工具和其他有用的功能。
演示中,我们使用 AI Engineer Europe 2026 日程 (https://www.ai.engineer/europe/schedule) 数据集进行搜索。前两个演示使用本地 Elasticsearch 集群,您可以使用 start-local (https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html) 脚本启动。第三个演示从磁盘读取相同数据。为了专注于搜索工具的核心机制,我们将跳过具体的数据准备和摄入步骤,这些内容可在 notebook 00_prepare_data.ipynb (https://github.com/iamleonie/workshop-agentic-search/blob/main/notebooks/00_prepare_data.ipynb) 中找到。
基础自主搜索
让我们先回顾第一个 notebook 01_vanilla_agentic_search.ipynb (https://github.com/iamleonie/workshop-agentic-search/blob/main/notebooks/01_vanilla_agentic_search.ipynb) 中实现的最小化基础自主搜索设置。它包含一个针对索引 conference_schedule 的语义搜索工具,该索引中每个会议场次对应一个文档。
基础自主搜索:一个基于 Elasticsearch 的语义搜索工具
首先,我们设置一个 LLM,这是任何智能体的核心。这里我们通过 LiteLLM 使用 gpt-5.4-nano:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
openai_api_base=LITELLM_API_BASE,
api_key=LITELLM_API_KEY,
model="llm-gateway/gpt-5.4-nano",
temperature=0.5,
)
然后我们定义一个最小系统提示,告诉智能体它是一个搜索智能体、何时检索以及索引的形状:
You are a search agent tasked with answering questions about the AI Engineer Europe 2026 Conference.
You have access to different context retrieval tools to help you answer user queries.
Before answering a question decide whether or not you need to retrieve additional context to answer the question correctly. If the retrieved context does not contain relevant information to answer the query, say that you don't know.
## Elasticsearch (`conference_schedule`)
The conference sessions are indexed in Elasticsearch. One document per session.
| Field | Description |
|--------------|------------|
| `text` | The string that was embedded: each session’s title plus description (blank line between them). It does not include day, time, room, or speakers. |
| `vector` | Dense embedding of `text`, used for similarity search. |
| `metadata` | Structured fields (see metadata description below) |
| Field | Description |
|--------------|------------|
| `metadata.title` | Title of the session|
| `metadata.day` | Date of the session (Example format: April 10) |
| `metadata.time` | Time slot of the session (Example format: 12:40-1:00pm) |
| `metadata.room` | Room where the session takes place |
| `metadata.type` | One of 'keynote', 'workshop', 'talk', 'track_keynote', 'lightning', 'expo_session' |
| `metadata.track` | Track |
| `metadata.speakers` | Name(s) of the speaker(s) as a single comma-separated string |
接下来,我们准备 Elasticsearch 客户端。为此,我们准备 jina-embeddings-v5-text-small 作为嵌入模型,它在搜索时嵌入查询,并连接到我们的 ElasticsearchStore:
from langchain_community.embeddings import JinaEmbeddings
from langchain_elasticsearch import ElasticsearchStore
embeddings = JinaEmbeddings(
jina_api_key=JINA_API_KEY,
model_name="jina-embeddings-v5-text-small",
)
vector_store = ElasticsearchStore(
es_url=ES_URL,
es_user=ES_USERNAME,
es_password=ES_PASSWORD,
index_name="conference_schedule",
embedding=embeddings,
)
这里是有趣的部分:让我们定义搜索工具,它接收搜索查询,运行语义搜索,并返回前三个结果。LangChain 的 @tool 装饰器允许我们将任何 Python 函数转换为智能体工具,默认使用函数名作为工具名,文档字符串作为描述。如下所示,我已经打破了自己之前关于工具描述的建议 (https://leoniemonigatti.com/blog/agentic-search-for-context-engineering.html#tool-descriptions),因为我这里只用了很短的文档字符串。然而,在这种情况下,因为我们只有一个工具且是基础演示用例,所以这已经足够。
from langchain.tools import tool
@tool()
def semantic_search_conference_sessions(query: str) -> str:
"""根据概念或主题进行语义搜索,以查找会议场次。
Args:
query: 用作搜索查询的主题或概念。
Returns:
包含会议场次信息的字符串。
"""
docs = vector_store.similarity_search(query, k=3)
return "\n\n".join(
f"**{doc.metadata['type']} by {doc.metadata['speakers']}**: "
f"{doc.metadata['title']}\nDescription:{doc.page_content}"
for doc in docs
)
现在,我们拥有了组成 AI 智能体的所有组件(通常还会有“记忆”,但这里为专注于搜索工具而有意省略),我们只需将它们组合起来。
from langchain.agents import create_agent
agent = create_agent(
model=llm,
system_prompt=SYSTEM_PROMPT,
tools=[semantic_search_conference_sessions],
)
以一个示例语义搜索查询 “哪些场次讨论了 AI 系统中的监管约束?” 为例,智能体现在调用该工具,并正确找到了 Bilge Yücel 关于在主权限约束下进行 AI 工程的主题演讲 (https://www.youtube.com/watch?v=x2bH0RKPgdc)。
================================
Human Message
================================
Which sessions discuss regulatory constraints in AI systems?
==================================
Ai Message
==================================
Tool Calls:
semantic_search_conference_sessions (call_FE570VnExWZOmupAtjduUcIB)
Call ID: call_FE570VnExWZOmupAtjduUcIB
Args:
query: regulatory constraints in AI systems law regulation compliance governance EU AI Act policy constraints
=================================
Tool Message
=================================
Name: semantic_search_conference_sessions
**talk by Bilge Yücel**: Engineering AI Systems Under Sovereignty Constraints
Description: Regulatory and jurisdictional constraints are no longer an edge case in AI system design; [...]
**talk by Dan Jame
相似文章
@techwith_ram:正在观看这场关于智能体搜索与上下文工程的演讲,主讲人是@helloiamleonie。看了一半,真的…
一个关于智能体搜索技术的研讨会,教授如何使用langchain和Elasticsearch,让AI智能体决定从文件、数据库、内存和网络中检索哪些上下文。
大多数关于“智能体 AI”的讨论都感觉太抽象了。这里是我的智能体研究系统的实际样子
作者分享了他为识别和评估公司内 AI 用例而构建的智能体研究系统的实际分解。该系统使用六个智能体进行发现、评估和上下文提取,强调人在决策环中,而非完全自主。
@dair_ai:关于自主搜索与向量搜索的精彩论文。
本文讨论并比较了自主搜索与向量搜索方法。
@omarsar0: 关于自主AI作为通往AGI的可预见路径的有趣观点论文。(收藏)一直存在激烈争论……
这篇观点论文认为,包含记忆、推理、工具使用、自我改进和对齐的自主AI系统,是比单纯扩展单一模型更可预见的AGI路径,并将这些组件形式化为具有不同瓶颈的可分离轴。
@dair_ai:// 驾驭智能体进化 // 如果你运行迭代式智能体搜索循环,请注意这一点。(收藏它)一……
AEvo 是一个元编辑框架,通过将提议和评估分为两个角色,并利用累积的记忆指导未来搜索,改进了迭代式智能体搜索。它在开放式优化任务上相比基线实现了26%的相对提升,并取得了最先进的结果。