首页 / 文章

基于 Agno Teams 的智能 RAG:查询重写、反馈循环与 Qdrant

由 Agno 团队构建的智能 RAG 系统:一名协调员负责重写查询,一名审核员负责循环检索,答案仅来自 Qdrant 混合搜索中经过审批的上下文。

发布者:REACTAPP.TOP阅读约 22 分钟5160 词

来源: The Agent Coordinator Pattern: Orchestrating Query Rewriting, Retrieval, and Critique with Agno

在智能体之间构建检索与评估的循环在白板上很容易画出来,但要真正实现却极为困难。此处描述的系统运行在Agno Teams上,包含四个角色:协调者、查询重写器、负责不断优化上下文的循环模块,以及只有在证据充分时才会给出答案的响应智能体。其底层采用Qdrant的混合检索技术,结合了密集向量、BM25以及互反排名融合方法。

团队架构

最顶层是协调者,即处于coordinate模式的Team。它本身不执行任何操作,只是分配任务、等待,然后将每个结果传递给后续环节。

  1. 查询重写智能体会对原始问题进行加工,生成三到五个语义相似的变体。不同的表述会检索到不同的段落,而单一的表述很少能找到所有相关内容。
  2. 检索-评估循环才是真正执行任务的地方。在协调器中会设置一个第二个Team,将其模式设为tasks,并通过max_iterations限制迭代次数,该团队作为单个成员存在。在这个团队中,检索代理会针对每个变体在Qdrant上执行混合搜索,结合密集向量和稀疏向量,并采用后期交互重排机制。随后评估代理会对检索结果的相关性和覆盖度进行评分。如果覆盖度不足,查询会以优化后的形式再次发出;而若覆盖度良好,则可直接通过评估。当评估代理满意或迭代次数用尽时,该循环即结束,以先发生者为准。
  3. 响应代理仅能看到已通过评估的上下文,而不会看到原始的检索结果。它严格依据这些内容来回答问题,指出哪段文字支持了哪一项主张,并明确说明何时上下文存在不足。
  4. 最终结果会原封不动地通过协调器返回,无需任何重写或二次判断。

为何要在一个团队中再设置一个团队?这是将“批判与循环”的理念应用到Agno自身的迭代机制中,因此应用程序代码中无需手动编写while循环。协调器只看到一个结构清晰的成员,所有的重试逻辑都包含在该成员内部。

构建知识库

在知识库建立之前,任何智能体都无法获取任何信息,而做好这一部分与智能体设计同样重要。

其背后的数据集为MedQuAD_Context_GroupedQA,包含约8,000篇医学文本,每篇文本都配有分组后的问答对。数据导入时仅保留context列。问答对则保留在数据集中,因为实验检测的是对原始文本的检索能力,而非答案的记忆能力。

不存在分块处理。每行的完整上下文都会被嵌入并作为一个个 Qdrant 点存储起来。这样更便于理解,但代价是对于较长的上下文,必须依赖嵌入 API 自带的截断功能。

每个点包含三个向量,每个向量都位于独立的命名槽中,从而为同一文本提供三种互补的视图:

  • dense:768 维度的 Gemini 嵌入向量
  • sparse:从 BM25 到 FastEmbed 的各种稀疏向量算法
  • late_interaction:用于重新排序的 ColBERT 多向量,不用于初次检索

最后是有效载荷结构。Agno 的 Qdrant 集成要求特定的有效载荷键(name、content、meta_data 和 content_id),以便在检索时重新构建其内部的 Document 对象。

项目代码

这些文件存放在一个小型目录树中:

.
├── data_ingester.py
├── in-context-learning-agentic-team.py
├── pyproject.toml
├── .env
└── uv.lock

首先是对全局配置的设置,包括导入内容、模型以及知识对象:

import os

from agno.agent import Agent
from agno.knowledge.knowledge import Knowledge
from agno.models.openai import OpenAIChat
from agno.knowledge.embedder.google import GeminiEmbedder
from agno.team import Team
from agno.team.mode import TeamMode
from agno.vectordb.qdrant import Qdrant
from agno.vectordb.search import SearchType
from dotenv import load_dotenv, find_dotenv

# ---------------------------------------------------------------------------
# Shared config
# ---------------------------------------------------------------------------
load_dotenv(find_dotenv())

MODEL_ID = "gpt-4o"
COLLECTION_NAME = os.getenv("QDRANT_COLLECTION", "medquad_hybrid")

# Must match the ingestion script's model/dimensions exactly, or the query
# vector lands in the wrong embedding space entirely.
embedder = GeminiEmbedder(
    id=os.getenv("GEMINI_EMBEDDING_MODEL", "gemini-embedding-2-preview"),
    dimensions=768,
    api_key=os.getenv("GEMINI_API_KEY"),
)

vector_db = Qdrant(
    collection=COLLECTION_NAME,
    url=os.getenv("QDRANT_URL", "http://localhost:6333"),
    api_key=os.getenv("QDRANT_API_KEY"),
    embedder=embedder,
    search_type=SearchType.hybrid,
)

knowledge_base = Knowledge(
    vector_db=vector_db,
)

查询重写器

该工具没有其他功能,仅依靠语言能力。接到问题后,它会生成三到五种表述不同的版本,这些版本在用词、具体程度及同义词方面有所差异。其目的是在开始检索之前扩大搜索范围。

# ---------------------------------------------------------------------------
# 1. Query Rewriting Agent
# ---------------------------------------------------------------------------

query_rewriter = Agent(
    name="Query Rewriting Agent",
    role="Given a user query, generate N semantically similar reformulations",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "Given the user's query, produce 3 to 5 semantically similar variants.",
        "Vary phrasing, specificity, and synonyms so each variant could surface "
        "different but relevant passages during retrieval.",
        "Return the variants as a clean numbered list, nothing else.",
    ],
    add_datetime_to_context=True,
)

检索代理

在所有代理中,这是直接向Qdrant发起查询的类型。每种查询方式都会进行融合的密集型加稀疏型搜索,返回的匹配结果会标注其来源以及得分高低;如有需要,还可使用后期交互重排器。其说明要求报告“未找到结果”,绝不能编造看似合理的文本。

# ---------------------------------------------------------------------------
# 2. Retrieval Agent (Qdrant-backed knowledge)
# ---------------------------------------------------------------------------

retrieval_agent = Agent(
    name="Retrieval Agent",
    role="Search the Qdrant knowledge base for passages relevant to a query",
    model=OpenAIChat(id=MODEL_ID),
    knowledge=knowledge_base,
    search_knowledge=True,
    instructions=[
        "For each incoming query variant, search the knowledge base.",
        "Return the retrieved passages verbatim along with their source and "
        "similarity score so the Critique Agent can evaluate them.",
        "If nothing relevant is found for a variant, say so explicitly instead "
        "of fabricating context.",
    ],
    add_datetime_to_context=True,
)

评价代理

该团队中的怀疑论者本身不会给出任何回应。它会根据检索代理找到的内容的相关性和全面性进行评分,然后要么批准该上下文,要么给出理由将其退回。正是这一点使得“一次检索并寄希望于成功”的方式转变为真正的反馈循环。

# ---------------------------------------------------------------------------
# 3. Critique Agent
# ---------------------------------------------------------------------------

critique_agent = Agent(
    name="Critique Agent",
    role="Critique and self-evaluate retrieved context for relevance and coverage",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "Evaluate the retrieved passages against the original user query.",
        "Score relevance and coverage on a 1-5 scale and explain briefly.",
        "If coverage is weak (score below 4) or passages are off-topic, "
        "explicitly request the Retrieval Agent to retry with a refined query, "
        "narrower or broader scope, or different query variant.",
        "If coverage is adequate, clearly state that the context is approved "
        "and ready to be handed to the Response Generation Agent.",
    ],
    add_datetime_to_context=True,
)

# ---------------------------------------------------------------------------
# Retrieval <-> Critique loop, as a nested tasks-mode sub-team
# ---------------------------------------------------------------------------

retrieval_critique_loop = Team(
    name="Retrieval-Critique Loop",
    role=(
        "Iteratively retrieve context for each query variant and critique it "
        "until the context is approved or the iteration budget is exhausted"
    ),
    mode=TeamMode.tasks,
    model=OpenAIChat(id=MODEL_ID),
    members=[retrieval_agent, critique_agent],
    max_iterations=4,
    instructions=[
        "Run retrieval for every query variant received.",
        "After each retrieval pass, send the results to the Critique Agent.",
        "If the Critique Agent requests a retry, refine the query and retrieve "
        "again.",
        "Stop as soon as the Critique Agent approves the context, or when the "
        "iteration budget is reached -- whichever comes first.",
        "Return the final approved (or best-effort) fused context.",
    ],
)

响应代理

只有该代理会与用户交流。它会读取已被审核者批准的上下文,用引文为每一项主张提供依据,若缺乏足够信息则会明确显示“上下文不足”的提示,而不会自行猜测。

# ---------------------------------------------------------------------------
# 4. Response Generation Agent
# ---------------------------------------------------------------------------

response_agent = Agent(
    name="Response Generation Agent",
    role="Generate the final answer from the fused, approved context",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "You will receive the original user query and the final fused context "
        "approved by the Retrieval-Critique Loop.",
        "Answer strictly grounded in the provided context.",
        "If the context is insufficient, say so rather than guessing.",
        "Cite which passage(s) support each claim where possible.",
    ],
    add_datetime_to_context=True,
)

协调器

称其为“代理”有些言过其实,因为它更像是一位指挥者。它知晓处理流程的顺序(重写、检索与评估、回复),并直接传递输出结果而不进行编辑。所有的推理都在后续阶段完成,协调器仅负责确保各项操作按正确顺序执行。

# ---------------------------------------------------------------------------
# Top-level coordinator
# ---------------------------------------------------------------------------

agent_coordinator = Team(
    name="Agent Coordinator",
    mode=TeamMode.coordinate,
    model=OpenAIChat(id=MODEL_ID),
    members=[query_rewriter, retrieval_critique_loop, response_agent],
    instructions=[
        "You coordinate an agentic RAG pipeline.",
        "Step 1: send the user's query to the Query Rewriting Agent to obtain "
        "N semantically similar query variants.",
        "Step 2: send all query variants to the Retrieval-Critique Loop and "
        "wait for the final fused, approved context.",
        "Step 3: send the original user query plus the fused context to the "
        "Response Generation Agent.",
        "Step 4: return the Response Generation Agent's output as the final "
        "answer -- do not rewrite or second-guess it.",
    ],
    add_datetime_to_context=True,
    show_members_responses=True,
)

运行它

该数据导入脚本将数据集、三个嵌入模型以及Qdrant连接在一起:

import os
import time
import uuid

from datasets import load_dataset
from fastembed import LateInteractionTextEmbedding, SparseTextEmbedding
from google import genai
from google.genai.types import EmbedContentConfig, HttpOptions, HttpRetryOptions
from qdrant_client import QdrantClient
from qdrant_client.models import (
    Distance,
    HnswConfigDiff,
    Modifier,
    MultiVectorComparator,
    MultiVectorConfig,
    PointStruct,
    SparseVector,
    SparseVectorParams,
    VectorParams,
)
from dotenv import load_dotenv, find_dotenv

# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------
load_dotenv(find_dotenv())

DATASET_ID = "pavanmantha/MedQuAD_Context_GroupedQA"
COLLECTION_NAME = os.getenv("QDRANT_COLLECTION", "medquad_hybrid")

# Dense: Google Gemini embedding.
# gemini-embedding-2-preview is Google's newest (multimodal-capable) model;
# swap to "gemini-embedding-001" if you want the GA, text-only model instead.
GEMINI_MODEL = os.getenv("GEMINI_EMBEDDING_MODEL", "gemini-embedding-2-preview")
DENSE_DIM = int(os.getenv("GEMINI_EMBEDDING_DIM", "768"))  # Google's recommended sweet spot

# Sparse: BM25 (must be paired with Modifier.IDF on the Qdrant side)
SPARSE_MODEL_NAME = "Qdrant/bm25"

# Late interaction: ColBERT-style multivector, used later for reranking
LATE_INTERACTION_MODEL_NAME = "answerdotai/answerai-colbert-small-v1"
LATE_INTERACTION_DIM = 96  # matches answerai-colbert-small-v1

BATCH_SIZE = 16  # points per upsert batch

# Retry/backoff for Gemini calls (you were hitting 4xx rate limits and
# 5xx "not available" errors -- both are transient and worth retrying)
GEMINI_MAX_ATTEMPTS = int(os.getenv("GEMINI_MAX_ATTEMPTS", "6"))
GEMINI_RETRY_INITIAL_DELAY = float(os.getenv("GEMINI_RETRY_INITIAL_DELAY", "2.0"))
GEMINI_RETRY_MAX_DELAY = float(os.getenv("GEMINI_RETRY_MAX_DELAY", "64.0"))
GEMINI_RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504]
GEMINI_REQUEST_DELAY_SECONDS = float(os.getenv("GEMINI_REQUEST_DELAY_SECONDS", "0.5"))

# ---------------------------------------------------------------------------
# Clients / models (initialized once)
# ---------------------------------------------------------------------------

genai_client = genai.Client(
    http_options=HttpOptions(
        retry_options=HttpRetryOptions(
            attempts=GEMINI_MAX_ATTEMPTS,
            initial_delay=GEMINI_RETRY_INITIAL_DELAY,
            max_delay=GEMINI_RETRY_MAX_DELAY,
            http_status_codes=GEMINI_RETRYABLE_STATUS_CODES,
        )
    )
)  # picks up GEMINI_API_KEY from env; auto-retries 429/5xx with backoff

qdrant_client = QdrantClient(
    url=os.getenv("QDRANT_URL", "http://localhost:6333"),
    api_key=os.getenv("QDRANT_API_KEY"),
)

sparse_model = SparseTextEmbedding(model_name=SPARSE_MODEL_NAME)
late_interaction_model = LateInteractionTextEmbedding(model_name=LATE_INTERACTION_MODEL_NAME)


# ---------------------------------------------------------------------------
# Embedding helpers
# ---------------------------------------------------------------------------

def embed_dense(texts: list[str]) -> list[list[float]]:
    vectors = []
    for text in texts:
        result = genai_client.models.embed_content(
            model=GEMINI_MODEL,
            contents=text,
            config=EmbedContentConfig(
                task_type="RETRIEVAL_DOCUMENT",
                output_dimensionality=DENSE_DIM,
            ),
        )
        vectors.append(result.embeddings[0].values)
        time.sleep(GEMINI_REQUEST_DELAY_SECONDS)  # spacing between calls, tune to your rate limit
    return vectors


def embed_sparse(texts: list[str]) -> list[SparseVector]:
    """Sparse BM25 embeddings via FastEmbed -> Qdrant SparseVector."""
    sparse_embeddings = list(sparse_model.embed(texts))
    return [
        SparseVector(indices=se.indices.tolist(), values=se.values.tolist())
        for se in sparse_embeddings
    ]


def embed_late_interaction(texts: list[str]) -> list[list[list[float]]]:
    multivectors = list(late_interaction_model.embed(texts))
    return [mv.tolist() for mv in multivectors]


# ---------------------------------------------------------------------------
# Collection setup
# ---------------------------------------------------------------------------

def create_collection():
    if qdrant_client.collection_exists(collection_name=COLLECTION_NAME):
        qdrant_client.delete_collection(collection_name=COLLECTION_NAME)

    qdrant_client.create_collection(
        collection_name=COLLECTION_NAME,
        vectors_config={
            "dense": VectorParams(
                size=DENSE_DIM,
                distance=Distance.COSINE,
            ),
            "late_interaction": VectorParams(
                size=LATE_INTERACTION_DIM,
                distance=Distance.COSINE,
                multivector_config=MultiVectorConfig(
                    comparator=MultiVectorComparator.MAX_SIM,
                ),
                hnsw_config=HnswConfigDiff(m=0),  # reranking-only, no ANN index needed
            ),
        },
        sparse_vectors_config={
            "sparse": SparseVectorParams(modifier=Modifier.IDF),
        },
    )


# ---------------------------------------------------------------------------
# Ingestion
# ---------------------------------------------------------------------------

def build_points(chunk_texts: list[str], payloads: list[dict]) -> list[PointStruct]:
    dense_vecs = embed_dense(chunk_texts)
    sparse_vecs = embed_sparse(chunk_texts)
    late_vecs = embed_late_interaction(chunk_texts)

    points = []
    for text, payload, dense_vec, sparse_vec, late_vec in zip(
            chunk_texts, payloads, dense_vecs, sparse_vecs, late_vecs
    ):
        row_idx = payload["source_row_id"]
        points.append(
            PointStruct(
                id=str(uuid.uuid4()),
                vector={
                    "dense": dense_vec,
                    "sparse": sparse_vec,
                    "late_interaction": late_vec,
                },
                payload={
                    # Required by Agno's Qdrant readback (Document reconstruction):
                    "name": f"MedQuAD context {row_idx}",
                    "meta_data": {"source_row_id": row_idx},
                    "content": text,  # the actual context
                    "usage": None,
                    "content_id": str(row_idx),
                },
            )
        )
    return points


def ingest():
    create_collection()

    dataset = load_dataset(DATASET_ID, split="train")

    batch_texts: list[str] = []
    batch_payloads: list[dict] = []
    total_ingested = 0

    for row_idx, row in enumerate(dataset):
        context = row["context"]

        batch_texts.append(context)
        batch_payloads.append({"source_row_id": row_idx})

        if len(batch_texts) >= BATCH_SIZE:
            points = build_points(batch_texts, batch_payloads)
            qdrant_client.upsert(collection_name=COLLECTION_NAME, points=points)
            total_ingested += len(points)
            print(f"Ingested {total_ingested} contexts...")
            batch_texts, batch_payloads = [], []

    # flush remaining
    if batch_texts:
        points = build_points(batch_texts, batch_payloads)
        qdrant_client.upsert(collection_name=COLLECTION_NAME, points=points)
        total_ingested += len(points)

    print(f"Done. Total contexts ingested: {total_ingested}")


if __name__ == "__main__":
    ingest()

主脚本负责组装智能体与团队:

import os

from agno.agent import Agent
from agno.knowledge.knowledge import Knowledge
from agno.models.openai import OpenAIChat
from agno.knowledge.embedder.google import GeminiEmbedder
from agno.team import Team
from agno.team.mode import TeamMode
from agno.vectordb.qdrant import Qdrant
from agno.vectordb.search import SearchType
from dotenv import load_dotenv, find_dotenv

# ---------------------------------------------------------------------------
# Shared config
# ---------------------------------------------------------------------------
load_dotenv(find_dotenv())

MODEL_ID = "gpt-4o"
COLLECTION_NAME = os.getenv("QDRANT_COLLECTION", "medquad_hybrid")

# Must match the ingestion script's model/dimensions exactly, or the query
# vector lands in the wrong embedding space entirely.
embedder = GeminiEmbedder(
    id=os.getenv("GEMINI_EMBEDDING_MODEL", "gemini-embedding-2-preview"),
    dimensions=768,
    api_key=os.getenv("GEMINI_API_KEY"),
)

vector_db = Qdrant(
    collection=COLLECTION_NAME,
    url=os.getenv("QDRANT_URL", "http://localhost:6333"),
    api_key=os.getenv("QDRANT_API_KEY"),
    embedder=embedder,
    search_type=SearchType.hybrid,
)

knowledge_base = Knowledge(
    vector_db=vector_db,
)


# ---------------------------------------------------------------------------
# 1. Query Rewriting Agent
# ---------------------------------------------------------------------------

query_rewriter = Agent(
    name="Query Rewriting Agent",
    role="Given a user query, generate N semantically similar reformulations",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "Given the user's query, produce 3 to 5 semantically similar variants.",
        "Vary phrasing, specificity, and synonyms so each variant could surface "
        "different but relevant passages during retrieval.",
        "Return the variants as a clean numbered list, nothing else.",
    ],
    add_datetime_to_context=True,
)

# ---------------------------------------------------------------------------
# 2. Retrieval Agent (Qdrant-backed knowledge)
# ---------------------------------------------------------------------------

retrieval_agent = Agent(
    name="Retrieval Agent",
    role="Search the Qdrant knowledge base for passages relevant to a query",
    model=OpenAIChat(id=MODEL_ID),
    knowledge=knowledge_base,
    search_knowledge=True,
    instructions=[
        "For each incoming query variant, search the knowledge base.",
        "Return the retrieved passages verbatim along with their source and "
        "similarity score so the Critique Agent can evaluate them.",
        "If nothing relevant is found for a variant, say so explicitly instead "
        "of fabricating context.",
    ],
    add_datetime_to_context=True,
)

# ---------------------------------------------------------------------------
# 3. Critique Agent
# ---------------------------------------------------------------------------

critique_agent = Agent(
    name="Critique Agent",
    role="Critique and self-evaluate retrieved context for relevance and coverage",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "Evaluate the retrieved passages against the original user query.",
        "Score relevance and coverage on a 1-5 scale and explain briefly.",
        "If coverage is weak (score below 4) or passages are off-topic, "
        "explicitly request the Retrieval Agent to retry with a refined query, "
        "narrower or broader scope, or different query variant.",
        "If coverage is adequate, clearly state that the context is approved "
        "and ready to be handed to the Response Generation Agent.",
    ],
    add_datetime_to_context=True,
)

# ---------------------------------------------------------------------------
# Retrieval <-> Critique loop, as a nested tasks-mode sub-team
# ---------------------------------------------------------------------------

retrieval_critique_loop = Team(
    name="Retrieval-Critique Loop",
    role=(
        "Iteratively retrieve context for each query variant and critique it "
        "until the context is approved or the iteration budget is exhausted"
    ),
    mode=TeamMode.tasks,
    model=OpenAIChat(id=MODEL_ID),
    members=[retrieval_agent, critique_agent],
    max_iterations=4,
    instructions=[
        "Run retrieval for every query variant received.",
        "After each retrieval pass, send the results to the Critique Agent.",
        "If the Critique Agent requests a retry, refine the query and retrieve "
        "again.",
        "Stop as soon as the Critique Agent approves the context, or when the "
        "iteration budget is reached -- whichever comes first.",
        "Return the final approved (or best-effort) fused context.",
    ],
)

# ---------------------------------------------------------------------------
# 4. Response Generation Agent
# ---------------------------------------------------------------------------

response_agent = Agent(
    name="Response Generation Agent",
    role="Generate the final answer from the fused, approved context",
    model=OpenAIChat(id=MODEL_ID),
    instructions=[
        "You will receive the original user query and the final fused context "
        "approved by the Retrieval-Critique Loop.",
        "Answer strictly grounded in the provided context.",
        "If the context is insufficient, say so rather than guessing.",
        "Cite which passage(s) support each claim where possible.",
    ],
    add_datetime_to_context=True,
)

# ---------------------------------------------------------------------------
# Top-level coordinator
# ---------------------------------------------------------------------------

agent_coordinator = Team(
    name="Agent Coordinator",
    mode=TeamMode.coordinate,
    model=OpenAIChat(id=MODEL_ID),
    members=[query_rewriter, retrieval_critique_loop, response_agent],
    instructions=[
        "You coordinate an agentic RAG pipeline.",
        "Step 1: send the user's query to the Query Rewriting Agent to obtain "
        "N semantically similar query variants.",
        "Step 2: send all query variants to the Retrieval-Critique Loop and "
        "wait for the final fused, approved context.",
        "Step 3: send the original user query plus the fused context to the "
        "Response Generation Agent.",
        "Step 4: return the Response Generation Agent's output as the final "
        "answer -- do not rewrite or second-guess it.",
    ],
    add_datetime_to_context=True,
    show_members_responses=True,
)

# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    # One-time setup: point the knowledge base at your source documents.
    # Example (uncomment and edit):
    # knowledge_base.add_content(url="https://example.com/your-document.pdf")
    # Q1. "What is (are) Small Intestine Cancer? give document citations as reference.",
    # Q2. "Who is at risk for Langerhans Cell Histiocytosis?",
    # Q3. "What is (are) Langerhans Cell Histiocytosis?",
    agent_coordinator.print_response(
        "Who is at risk for Langerhans Cell Histiocytosis?",
        stream=True,
    )

完整运行会生成一条较长的轨迹,其中包含文档查询记录以及每个代理的消息面板内容:

INFO Found 10 documents
INFO Found 10 documents
INFO Found 10 documents
┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ What is (are) Small Intestine Cancer?                                        ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Query Rewriting Agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ 1. What is the disease known as Small Intestine Cancer?                      ┃
┃ 2. Can you describe Small Intestine Cancer?                                  ┃
┃ 3. How would you define cancer of the small intestine?                       ┃
┃ 4. What are the characteristics of Small Intestine Cancer?                   ┃
┃ 5. Could you explain what Small Intestine Cancer entails?                    ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Query Rewriting Agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ 1. What types of cancers affect the small intestine?                         ┃
┃ 2. Can you list the different forms of cancer found in the small intestine?  ┃
┃ 3. How many kinds of small intestine cancers are there?                      ┃
┃ 4. What are the various cancers of the small intestine?                      ┃
┃ 5. Could you explain the different types of small intestine cancers?         ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ retrieval-agent Tool Calls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ • search_knowledge_base(query=What is Small Intestine Cancer?)               ┃
┃                                                                              ┃
┃ • search_knowledge_base(query=What are Small Intestine Cancers?)             ┃
┃                                                                              ┃
┃ • search_knowledge_base(query=Small Intestine Cancer definition symptoms     ┃
┃ treatment options prognosis)                                                 ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ retrieval-agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ Here are the retrieved passages related to Small Intestine Cancer:           ┃
┃                                                                              ┃
┃ 1. **Passage from MedQuAD context 0:**                                       ┃
┃    - The small intestine is part of the body’s digestive system, which also  ┃
┃ includes the esophagus, stomach, and large intestine. The digestive system   ┃
┃ removes and processes nutrients (vitamins, minerals, carbohydrates, fats,    ┃
┃ proteins, and water) from foods and helps pass waste material out of the     ┃
┃ body. The small intestine is a long tube that connects the stomach to the    ┃
┃ large intestine. It folds many times to fit inside the abdomen. EnlargeThe   ┃
┃ small intestine connects the stomach and the colon. It includes the          ┃
┃ duodenum, jejunum, and ileum. The types of cancer found in the small         ┃
┃ intestine are adenocarcinoma, sarcoma, carcinoid tumors, gastrointestinal    ┃
┃ stromal tumor, and lymphoma. This summary discusses adenocarcinoma and       ┃
┃ leiomyosarcoma (a type of sarcoma). Adenocarcinoma starts in glandular cells ┃
┃ in the lining of the small intestine and is the most common type of small    ┃
┃ intestine cancer. Most of these tumors occur in the part of the small        ┃
┃ intestine near the stomach. They may grow and block the intestine.           ┃
┃ Leiomyosarcoma starts in the smooth muscle cells of the small intestine.     ┃
┃ Most of these tumors occur in the part of the small intestine near the large ┃
┃ intestine. For more information on small intestine cancer, see the           ┃
┃ following: Anything that increases your risk of getting a disease is called  ┃
┃ a risk factor. Having a risk factor does not mean that you will get cancer;  ┃
┃ not having risk factors doesn't mean that you will not get cancer. Talk with ┃
┃ your doctor if you think you may be at risk. [Source: PMID: 26389461]        ┃
┃                                                                              ┃
┃ 2. **Passage from MedQuAD context 121:**                                     ┃
┃    - You had surgery to remove all or part of your small intestine (small    ┃
┃ bowel). You may also have had an ileostomy. During and after surgery, you    ┃
┃ received intravenous (IV) fluids. You also may have had a tube placed        ┃
┃ through your nose and into your stomach. You may have received antibiotics.  ┃
┃ You may have these problems after you return home from the hospital: Follow  ┃
┃ your health care provider's instructions... [Source: Elmously A, Yeo HL.     ┃
┃ Management of small bowel obstruction.]                                      ┃
┃                                                                              ┃
┃ 3. **Passage from MedQuAD context 209:**                                     ┃
┃    - Radiation enteritis is damage to the lining of the intestines (bowels)  ┃
┃ caused by radiation therapy, which is used for some types of cancer          ┃
┃ treatment... When symptoms become long-term (chronic), other problems may    ┃
┃ include: The health care provider will do a physical exam and ask about your ┃
┃ medical history. Tests may include... [Source: Kuemmerle JF. Inflammatory    ┃
┃ and anatomic diseases of the intestine, peritoneum, mesentery, and omentum.] ┃
┃                                                                              ┃
┃ These passages were retrieved for both queries, "What is Small Intestine     ┃
┃ Cancer?" and "What are Small Intestine Cancers?" They cover an overview,     ┃
┃ treatment, and some related conditions and procedures.                       ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ critique-agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ **Relevance Score: 4/5**                                                     ┃
┃                                                                              ┃
┃ The passages include relevant information about Small Intestine Cancer,      ┃
┃ especially the types of cancers that can occur in the small intestine, such  ┃
┃ as adenocarcinoma and leiomyosarcoma, which directly addresses the query on  ┃
┃ what Small Intestine Cancer is. The passage provides important details about ┃
┃ where these cancers are likely to occur within the small intestine and some  ┃
┃ general information about risk factors.                                      ┃
┃                                                                              ┃
┃ **Coverage Score: 3/5**                                                      ┃
┃                                                                              ┃
┃ While the passages offer a brief overview and touch on significant points    ┃
┃ like types of cancers and risk factors, they do not thoroughly define Small  ┃
┃ Intestine Cancer or discuss characteristics, treatment options, symptoms,    ┃
┃ diagnosis, or prognosis, which would provide a more comprehensive            ┃
┃ understanding. The second and third passages primarily discuss specific      ┃
┃ surgical procedures and conditions related to cancer treatment rather than   ┃
┃ providing detailed insights into Small Intestinal Cancer itself.             ┃
┃                                                                              ┃
┃ **Recommendation:**                                                          ┃
┃                                                                              ┃
┃ The coverage is insufficient for delivering a complete response to the query ┃
┃ about Small Intestine Cancer. It's advisable to request the Retrieval Agent  ┃
┃ conduct a more focused search that includes information on defining Small    ┃
┃ Intestine Cancer, its symptoms, treatment options, and prognosis. This will  ┃
┃ ensure a more comprehensive answer can be given to the user.                 ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ retrieval-agent Tool Calls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ • search_knowledge_base(query=What is Small Intestine Cancer?)               ┃
┃                                                                              ┃
┃ • search_knowledge_base(query=What are Small Intestine Cancers?)             ┃
┃                                                                              ┃
┃ • search_knowledge_base(query=Small Intestine Cancer definition symptoms     ┃
┃ treatment options prognosis)                                                 ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ retrieval-agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ Here are the retrieved passages related to Small Intestine Cancer, including ┃
┃ its definition, symptoms, treatment options, and prognosis:                  ┃
┃                                                                              ┃
┃ 1. **Passage from MedQuAD context 0:**                                       ┃
┃    - The small intestine is part of the body’s digestive system, which also  ┃
┃ includes the esophagus, stomach, and large intestine. The digestive system   ┃
┃ removes and processes nutrients (vitamins, minerals, carbohydrates, fats,    ┃
┃ proteins, and water) from foods and helps pass waste material out of the     ┃
┃ body. The small intestine is a long tube that connects the stomach to the    ┃
┃ large intestine. It folds many times to fit inside the abdomen. EnlargeThe   ┃
┃ small intestine connects the stomach and the colon. It includes the          ┃
┃ duodenum, jejunum, and ileum. The types of cancer found in the small         ┃
┃ intestine are adenocarcinoma, sarcoma, carcinoid tumors, gastrointestinal    ┃
┃ stromal tumor, and lymphoma. Adenocarcinoma starts in glandular cells in the ┃
┃ lining of the small intestine and is the most common type of small intestine ┃
┃ cancer. Most of these tumors occur in the part of the small intestine near   ┃
┃ the stomach. They may grow and block the intestine. Leiomyosarcoma starts in ┃
┃ the smooth muscle cells of the small intestine. Most of these tumors occur   ┃
┃ in the part of the small intestine near the large intestine. Risk factors    ┃
┃ for small intestine cancer include various factors, but having a risk factor ┃
┃ does not mean definite development of cancer. Tests and procedures to        ┃
┃ detect, diagnose, and stage small intestine cancer are usually done at the   ┃
┃ same time. The prognosis and treatment options depend on the type of small   ┃
┃ intestine cancer and whether the tumor can be removed by surgery. Treatment  ┃
┃ depends on whether the cancer is being treated as a primary tumor or is      ┃
┃ metastatic cancer. Different types of treatments are available, including    ┃
┃ surgery, chemotherapy, radiation therapy, and participation in clinical      ┃
┃ trials. Many of today's standard treatments are based on earlier clinical    ┃
┃ trials, and patients who participate in clinical trials also help improve    ┃
┃ future treatments. [PMID: 26389461]                                          ┃
┃                                                                              ┃
┃ This passage is comprehensive in providing definitions, symptoms, risk       ┃
┃ factors, staging, treatment options, and prognosis regarding Small Intestine ┃
┃ Cancer. It describes different cancers that may affect the small intestine   ┃
┃ and the general treatment approach including surgery, chemotherapy, and      ┃
┃ clinical trials, offering a holistic understanding of Small Intestine        ┃
┃ Cancer.                                                                      ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response Generation Agent Response ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ Small Intestine Cancer is a type of cancer that occurs in the small          ┃
┃ intestine, which is part of the body’s digestive system connecting the       ┃
┃ stomach to the large intestine. The small intestine extracts and processes   ┃
┃ nutrients from foods and assists in passing waste material out of the body.  ┃
┃ It includes sections called the duodenum, jejunum, and ileum.                ┃
┃                                                                              ┃
┃ The types of cancer that can develop in the small intestine include          ┃
┃ adenocarcinoma, sarcoma (such as leiomyosarcoma), carcinoid tumors,          ┃
┃ gastrointestinal stromal tumors, and lymphoma. Adenocarcinoma, which starts  ┃
┃ in the glandular cells lining the small intestine, is the most common type.  ┃
┃ These tumors typically form in the part of the small intestine near the      ┃
┃ stomach and may grow to block the intestine. Leiomyosarcoma originates in    ┃
┃ the smooth muscle cells of the small intestine.                              ┃
┃                                                                              ┃
┃ Several factors may increase the risk of developing small intestine cancer,  ┃
┃ though having a risk factor does not guarantee that cancer will develop.     ┃
┃ Detection, diagnosis, and staging of small intestine cancer usually occur    ┃
┃ simultaneously through various tests and procedures.                         ┃
┃                                                                              ┃
┃ The prognosis and treatment for small intestine cancer depend on the cancer  ┃
┃ type and whether the tumor can be removed surgically. Treatment options      ┃
┃ include surgery, chemotherapy, radiation therapy, and participation in       ┃
┃ clinical trials. These trials are essential as many of today's standard      ┃
┃ treatments are based on earlier clinical trial results. Patients who         ┃
┃ participate in clinical trials contribute to the potential improvement of    ┃
┃ future cancer treatments.                                                    ┃
┃                                                                              ┃
┃ This comprehensive understanding of Small Intestine Cancer covers its        ┃
┃ definition, types, risk factors, diagnosis methods, and treatment practices, ┃
┃ providing an insightful perspective on managing this disease [Source: PMID:  ┃
┃ 26389461].                                                                   ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Team Tool Calls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=query-rewriting-agent, task=Generate     ┃
┃ five semantically similar                                                    ┃
┃   reformulations of the query: 'What is Small Intestine Cancer?')            ┃
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=query-rewriting-agent, task=Generate     ┃
┃ five semantically similar                                                    ┃
┃   reformulations of the query: 'What are Small Intestine Cancers?')          ┃
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=retrieval-agent, task=Retrieve           ┃
┃ information on Small Intestine Cancer from                                   ┃
┃   the knowledge base.)                                                       ┃
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=critique-agent, task=Review the          ┃
┃ retrieved passages related to Small                                          ┃
┃   Intestine Cancer from MedQuAD context and evaluate for relevance and       ┃
┃ coverage. Confirm if additional                                              ┃
┃   retrieval is needed to comprehensively answer the user's query.)           ┃
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=retrieval-agent, task=Conduct a more     ┃
┃ focused search in the knowledge base                                         ┃
┃   to obtain detailed information on Small Intestine Cancer, including its    ┃
┃ definition, symptoms, treatment                                              ┃
┃   options, and prognosis.)                                                   ┃
┃                                                                              ┃
┃ • delegate_task_to_member(member_id=response-generation-agent, task=Using    ┃
┃ the retrieved passage on Small                                               ┃
┃   Intestine Cancer from MedQuAD context 0, generate a comprehensive response ┃
┃ that defines Small Intestine                                                 ┃
┃   Cancer, its types, symptoms, treatment options, and prognosis. The         ┃
┃ response should cover what small                                             ┃
┃   intestine cancer is, associated risk factors, diagnosis, and available     ┃
┃ treatment practices.)                                                        ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (50.2s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                              ┃
┃ Small Intestine Cancer is a type of cancer occurring in the small intestine, ┃
┃ part of the digestive system that connects the stomach to the large          ┃
┃ intestine. It plays a key role in extracting nutrients from food and passing ┃
┃ waste material. The small intestine encompasses the duodenum, jejunum, and   ┃
┃ ileum.                                                                       ┃
┃                                                                              ┃
┃ Types of Small Intestine Cancer include adenocarcinoma, sarcoma (such as     ┃
┃ leiomyosarcoma), carcinoid tumors, gastrointestinal stromal tumors, and      ┃
┃ lymphoma. Adenocarcinoma starts in glandular cells lining the small          ┃
┃ intestine and is the most common type. It typically occurs near the stomach  ┃
┃ and can grow to block the intestine. Leiomyosarcoma originates in the smooth ┃
┃ muscle cells, often near the large intestine.                                ┃
┃                                                                              ┃
┃ Risk factors vary, but a risk factor does not guarantee cancer development.  ┃
┃ Diagnosis and staging usually involve simultaneous testing, and the          ┃
┃ prognosis and treatment options depend on the cancer type and tumor          ┃
┃ resectability. Treatments include surgery, chemotherapy, radiation, and      ┃
┃ clinical trials, which offer newer treatment avenues.                        ┃
┃                                                                              ┃
┃ This overview provides a detailed look at Small Intestine Cancer, including  ┃
┃ types, risks, diagnosis, and treatments based on clinical advancements       ┃
┃ [Source: PMID: 26389461].                                                    ┃
┃                                                                              ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

该设计的优势

最终得到的是一个在输出内容前会先自我检验的RAG流程:检索、评估和生成是独立的步骤,每个步骤都可以单独检查,而非通过一个不可见的调用完成。实现这一目标需要通过嵌套Agno Teams进行迭代优化,在Qdrant中整合密集向量、稀疏向量以及后期交互向量,同时还要仔细处理负载键、向量名称以及智能体之间如何共享上下文等细节问题。由于大部分调试时间都花在这些细节上,最初的尝试很可能会失败。

相关阅读

  • 多手一支笔:协调AI智能体的七条规则 —— 为何在流程优于智能体时协调器不应掌控工具,如何记录子智能体的返回结果与终止条件,以及每条规则对应的Python示例代码。