如何用 CrewAI Flow 在 ai-engineering-hub 构建并行检索文档、记忆与网页的研究助手并输出带相关度评分的引用?
【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub
在 ai-engineering-hub 仓库的context-engineering-hub子项目里,context-engineering-workflow/ 用 CrewAI Flow 搭了一个多源研究助手:一条查询会同时触发文档向量检索(Milvus)、对话记忆检索(Zep Cloud)和网页检索(Firecrawl),再由 Evaluator 代理对每个来源给出 0–1 的相关度评分,最后由 Synthesizer 合成带引用的回答。这篇文章按仓库自带文档走一遍完整路径:准备五个 API Key 和 PDF 文档,启动 Streamlit 应用,处理第一篇文档,提问后在“Sources & Citations”面板里核对相关度评分与逐条引用。
前提条件:Python >= 3.13(pyproject.toml 中requires-python = ">=3.13"),TensorLake、Voyage AI、OpenAI、Zep、Firecrawl 五家服务的 API Key,以及可访问网络的机器。
准备环境、依赖与 API Key
先安装uv。README 给出的安装命令会联网下载并安装 uv 到本机,确认来源可信后再执行:
# MacOS/Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"README 的原始步骤是在新目录里uv init research-assistant再建环境。仓库中的context-engineering-workflow/目录已经自带 pyproject.toml 和uv.lock,所以可以直接进入该目录建虚拟环境并同步依赖:
cd context-engineering-workflow uv venv source .venv/bin/activate # MacOS/Linux;Windows 用 .venv\Scripts\activate uv sync依赖版本在 pyproject.toml 中固定:crewai>=0.165.1、crewai-tools>=0.0.1、pymilvus>=2.6.0、tensorlake>=0.2.44、voyageai>=0.3.4、zep-crewai>=1.0.0、openai>=1.99.9、firecrawl-py>=4.3.0、streamlit>=1.49.1、python-dotenv、pydantic>=2.0.0。
在项目目录创建.env,五个 Key 的变量名必须与文档一致(应用启动时会逐一检查这些环境变量):
TENSORLAKE_API_KEY=your_tensorlake_key VOYAGE_API_KEY=your_voyage_key OPENAI_API_KEY=your_openai_key ZEP_API_KEY=your_zep_key FIRECRAWL_API_KEY=your_firecrawl_keyKey 到对应服务的官网申请:TensorLake(文档解析)、Zep AI(记忆)、Firecrawl(网页搜索)、OpenAI(结构化生成)、Voyage(上下文嵌入)。
准备研究文档:README 要求把 PDF 放到data/目录(仅支持 PDF 格式)。仓库已自带一份示例论文 data/attention-is-all-you-need-Paper.pdf,也可以换成自己的文档。
先看懂 Flow 的四段主路径
flow.py 中ResearchAssistantFlow的四个阶段决定了你在界面上会看到什么:
process_query(@start()):把查询摘要后存入 Zep 记忆层,再进入下一阶段。gather_context_from_all_sources:为 RAG、Memory、Web Search、ArXiv 各建一个 Task,放进同一个Crew执行。README 说明各来源独立并行运行,互不阻塞;标题中提到的文档、记忆、网页就是其中三路,第四路 ArXiv 学术检索也同时执行。evaluate_context_relevance:Evaluator 代理按ContextEvaluationResult这个 Pydantic 校验输出,字段包括relevant_sources(被判定相关的来源名)、filtered_context(只保留相关信息的字典)、relevance_scores(每个来源 0–1 的置信评分)和reasoning(过滤决策的解释)。synthesize_final_response:Synthesizer 基于过滤后的上下文生成最终回答,并把回答摘要存回 Zep。
Flow 通过flow.kickoff(inputs={"query": ..., "user_id": ..., "thread_id": ...})触发;app.py 里固定使用user_id="streamlit_user"、thread_id="streamlit_session"。代理和任务的 role、goal、backstory 与描述文本分别来自 research_agents.yaml 和 research_tasks.yaml,其中评估任务的描述明确要求“ERROR 状态的来源不得进入 relevant_sources,只在 reasoning 中提及”。
启动应用并处理第一篇文档
uv run app.py # 或 streamlit run app.py按以下顺序操作:
- 在侧边栏点击Initialize Research Assistant按钮,看到 “✅ Assistant initialized!” 表示 Flow、RAG 管道、记忆层初始化完成;失败会显示 “Failed to initialize Research Assistant: …” 的具体报错。
- 用Upload PDF Document选择 PDF,点击Process。处理走 RAGPipeline.process_documents:TensorLake 上传并按
RESEARCH_PAPER_SCHEMA结构化解析出 chunk → 用voyage-context-3生成 1024 维上下文嵌入 → 写入 Milvus。看到 “✅ Processed!” 和 “✅ Document Ready” 即成功。 - 处理完文档前,主聊天区会显示 “⚠️ Please process a document first using the sidebar.”,此时不能提问;这是判断文档是否已就绪的直接依据。
两个初始化行为需要事先知道,都来自源码而不是猜测:
- retriever.py 的
_ensure_collection在每次初始化时如果检测到已存在research_assistantcollection,会先 drop 再重建,并打印 “Dropping existing collection: research_assistant”。也就是说重启应用会清空旧向量数据,需要重新 Process 文档。 - memory.py 在初始化时会删除旧 thread 再新建,每次启动应用都是一个新会话,Zep 中保留的是跨会话的用户级摘要记忆。
文档处理失败时,app.py 会把异常归类为 “Document parsing failed”(TensorLake 相关)、“Embedding generation failed” 或 “API authentication failed”,可据此定位是哪一环的 Key 或服务出错。
提问并核对相关度评分与引用
在聊天框输入查询(例如 “Summarize the key contributions of this paper.”),回答下方会出现View Sources & Citations折叠面板,这里是标题承诺的“带相关度评分的引用”的核对点:
- Source Relevance Summary:列出 Evaluator 判定为
relevant_sources的来源名,并给出每个来源的评分,格式为• RAG: 0.95(0–1,保留两位小数);右侧Reasoning展示过滤决策的文字解释。评分由 flow.py 中relevance_scores字段的定义保证在 0–1 区间。 - 分来源展开:RAG (Documents)、Memory (History)、Web Search、ArXiv Papers 各自带一个状态标记,取值
OK、ERROR、INSUFFICIENT_CONTEXT或UNKNOWN,只在状态为OK时展开具体内容。 - RAG 逐条引用:每条引用显示来源文件名与
📄 Page X, Chunk Y (Score: 0.xxx),附带该 chunk 的前 300 字符内容预览;底部还有Retrieved Chunks与Documents Searched两个检索元数据。这个分数来自 Milvus 的余弦相似度检索结果(IVF_FLAT索引、COSINE度量,见 retriever.py),与 Evaluator 的来源级评分是两层不同的信号。
判断一轮结果是否正常的依据都写在代码行为里:
- RAG 向量库为空且没有提供
document_paths时,rag_tool.py 返回INSUFFICIENT_CONTEXT并提示先加载文档——界面上 RAG 卡片就会显示该状态而不是编造内容。 - 某来源返回
ERROR时,它不会进入relevant_sources,只在 Reasoning 中被提及;INSUFFICIENT_CONTEXT的来源会以警告文案形式展示其answer字段。 - 没有文档、没有网络或某个 Key 失效时,对应来源单独降级,不会中断整个 Flow,可以在面板里逐路排查。
边界与已知限制
- 标题提到的“文档、记忆、网页”三路之外,代码里实际还并行跑了一路 ArXiv 学术检索(research_tasks.yaml 中的
arxiv_search_task),面板中显示为 ArXiv Papers。 - 文档仅支持 PDF,且文档要先在侧边栏 Process 进向量库才能被检索;RAG 默认
top_k=3(rag_tool.py 中RAGInput的默认值)。 - 每启动一次应用,Milvus 的
research_assistantcollection 和 Zep thread 都会重建(行为见上一节),所以验证“跨轮记忆”要在同一次运行内的连续对话中进行。 - Web Search 卡片只在有
search_results、显式status == 'OK'、或同时有answer与relevance_assessment时判为 OK,否则按ERROR/INSUFFICIENT_CONTEXT/UNKNOWN展示,核对结果时以此为准。
完成上述路径后,你可以针对同一份 Attention Is All You Need 连续提问两轮,观察第二轮中 Memory (History) 卡片从空到带上下文的变化,以及 Source Relevance Summary 中各来源评分随问题变化——这就是该 Flow“并行检索 + 相关度评分 + 逐条引用”三件事的实际验证闭环。
【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考