Neste CodeLab, você aprenderá a criar um Agente de busca de hotéis usando LangChain, Serviços de IA do Couchbasee Catálogo de agentes. Também incorporaremos Arize Phoenix para observabilidade e avaliação para garantir que nosso agente tenha um desempenho confiável.
Este tutorial leva você do zero a um agente totalmente funcional que pode pesquisar hotéis, filtrar por comodidades e responder a consultas em linguagem natural usando dados do mundo real.
Observação: Você pode encontrar o caderno completo do Google CodeLab para este CodeLab aqui.
O que são os serviços de IA do Couchbase?
A criação de aplicativos de IA geralmente envolve a combinação de vários serviços: um banco de dados vetorial para memória, um provedor de inferência para LLMs (como OpenAI ou Anthropic) e uma infraestrutura separada para incorporar modelos.
Serviços de IA do Couchbase simplifica isso fornecendo uma plataforma unificada onde seus dados operacionais, pesquisa vetorial e modelos de IA convivem juntos. Ela oferece:
- API de inferência e incorporação de LLM: Acesse LLMs populares (como o Llama 3) e modelos de incorporação diretamente no Couchbase Capella, sem chaves de API externas, sem infraestrutura extra e sem saída de dados. Os dados de seu aplicativo permanecem dentro do Capella. As consultas, os vetores e a inferência de modelos ocorrem onde os dados residem. Isso permite experiências de IA seguras e de baixa latência, ao mesmo tempo em que atende aos requisitos de privacidade e conformidade. Portanto, o principal valor: dados e IA juntos, sem enviar informações confidenciais para fora do seu sistema.
- Plataforma unificada: Banco de dados + Vetorização + Pesquisa + Modelo
- Pesquisa vetorial integrada: Realize pesquisas semânticas diretamente em seus dados JSON com latência de milissegundos.
Por que isso é necessário?
À medida que passamos de simples chatbots para fluxos de trabalho autênticos, Quando os modelos de IA usam ferramentas de forma autônoma, a latência e a complexidade da configuração tornam-se gargalos. Ao co-localizar seus dados e serviços de IA, você reduz a sobrecarga operacional e a latência. Além disso, ferramentas como a Catálogo de agentes ajudam a gerenciar centenas de prompts e ferramentas de agentes e fornecem registro integrado para seus agentes.
Pré-requisitos
Antes de começarmos, verifique se você tem:
- A Couchbase Capella conta.
- Python 3.10+ instalado.
- Familiaridade básica com Python e notebooks Jupyter.
Criar um cluster no Couchbase Capella
- Faça login no Couchbase Capella.
- Crie um novo cluster ou use um já existente. Observe que o cluster precisa executar a versão mais recente do Couchbase Server 8.0 com os serviços Data, Query, Index e Eventing.
- Crie um balde.
- Crie um escopo e uma coleção para seus dados.
Etapa 1: Instalar dependências
Começaremos instalando os pacotes necessários. Isso inclui o pacote infraestrutura de couchbase para configuração, o auxiliar agente CLI para o catálogo e os pacotes de integração do LangChain.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
%pip install -q \ "pydantic>=2.0.0,<3.0.0" \ "python-dotenv>=1.0.0,<2.0.0" \ "pandas>=2.0.0,<3.0.0" \ "nest-asyncio>=1.6.0,<2.0.0" \ "langchain-couchbase>=0.2.4,<0.5.0" \ "langchain-openai>=0.3.11,<0.4.0" \ "arize-phoenix>=11.37.0,<12.0.0" \ "openinference-instrumentation-langchain>=0.1.29,<0.2.0" \ "couchbase-infrastructure" # Install Agent Catalog %pip install agentc==1.0.0 |
Etapa 2: Infraestrutura como código
Em vez de clicar manualmente na interface do usuário, usamos o infraestrutura de couchbase para provisionar programaticamente nosso ambiente Capella. Isso garante uma configuração reproduzível.
Nós o faremos:
- Crie um projeto e um cluster.
- Implantar um modelo de incorporação (
nvidia/llama-3.2-nv-embedqa-1b-v2) e um LLM (meta/llama3-8b-instruct). - Carregar o
amostra de viagemconjunto de dados.
O Couchbase AI Services fornece pontos de extremidade compatíveis com OpenAI que são usados pelos agentes.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import os from getpass import getpass from couchbase_infrastructure import CapellaConfig, CapellaClient from couchbase_infrastructure.resources import ( create_project, create_developer_pro_cluster, add_allowed_cidr, load_sample_data, create_database_user, deploy_ai_model, create_ai_api_key, ) # 1. Collect Credentials management_api_key = getpass("Enter your MANAGEMENT_API_KEY: ") organization_id = input("Enter your ORGANIZATION_ID: ") config = CapellaConfig( management_api_key=management_api_key, organization_id=organization_id, project_name="agent-app", cluster_name="agent-app-cluster", db_username="agent_app_user", sample_bucket="travel-sample", # Using Couchbase AI Services for models embedding_model_name="nvidia/llama-3.2-nv-embedqa-1b-v2", llm_model_name="meta/llama3-8b-instruct", ) # 2. Provision Cluster client = CapellaClient(config) org_id = client.get_organization_id() project_id = create_project(client, org_id, config.project_name) cluster_id = create_developer_pro_cluster(client, org_id, project_id, config.cluster_name, config) # 3. Network & Data Setup add_allowed_cidr(client, org_id, project_id, cluster_id, "0.0.0.0/0") # Allow all IPs for tutorial load_sample_data(client, org_id, project_id, cluster_id, config.sample_bucket) db_password = create_database_user(client, org_id, project_id, cluster_id, config.db_username, config.sample_bucket) # 4. Deploy AI Models print("Deploying AI Models...") deploy_ai_model(client, org_id, config.embedding_model_name, "agent-hub-embedding-model", "embedding", config) deploy_ai_model(client, org_id, config.llm_model_name, "agent-hub-llm-model", "llm", config) # 5. Generate API Keys api_key = create_ai_api_key(client, org_id, config.ai_model_region) |
Certifique-se de seguir as etapas para configurar o certificado raiz de segurança. As conexões seguras com o Couchbase Capella exigem um certificado raiz para verificação do TLS. Você pode encontrá-lo na seção ## 📜 Configuração do certificado raiz da seção do Google Colab Notebook.
Etapa 3: Integração do catálogo de agentes
O Catálogo de agentes é uma ferramenta avançada para gerenciar o ciclo de vida dos recursos do seu agente. Em vez de codificar prompts e definições de ferramentas em seus arquivos Python, você os gerencia como ativos com versão. É possível centralizar e reutilizar suas ferramentas entre as equipes de desenvolvimento. Também é possível examinar e monitorar as respostas do agente com o Agent Tracer.
Inicialização e download de ativos
Primeiro, inicializamos o catálogo e baixamos nossos prompts e ferramentas predefinidos.
|
1 2 3 4 5 6 7 8 |
!git init !agentc init # Download example tools and prompts !mkdir -p prompts tools !wget -O prompts/hotel_search_assistant.yaml https://raw.githubusercontent.com/couchbase-examples/agent-catalog-quickstart/refs/heads/main/notebooks/hotel_search_agent_langchain/prompts/hotel_search_assistant.yaml !wget -O tools/search_vector_database.py https://raw.githubusercontent.com/couchbase-examples/agent-catalog-quickstart/refs/heads/main/notebooks/hotel_search_agent_langchain/tools/search_vector_database.py !wget -O agentcatalog_index.json https://raw.githubusercontent.com/couchbase-examples/agent-catalog-quickstart/refs/heads/main/notebooks/hotel_search_agent_langchain/agentcatalog_index.json |
Indexar e publicar
Usamos agente para indexar nossos arquivos locais e publicá-los no Couchbase. Isso armazena os metadados em seu banco de dados, tornando-os pesquisáveis e detectáveis pelo agente em tempo de execução.
|
1 2 3 4 5 |
# Create local index of tools and prompts !agentc index . # Upload to Couchbase !agentc publish |
Etapa 4: Preparando o Vector Store
Para permitir que nosso agente pesquise hotéis semanticamente (por exemplo, “lugar aconchegante perto da praia”), precisamos gerar embeddings vetoriais para nossos dados de hotéis.
Definimos um auxiliar para formatar os dados do nosso hotel em uma representação de rich text, priorizando a localização e as comodidades.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from langchain_couchbase.vectorstores import CouchbaseVectorStore def load_hotel_data_to_couchbase(cluster, bucket_name, scope_name, collection_name, embeddings, index_name): # Check if data exists # ... (omitted for brevity) ... # Generate rich text for each hotel # e.g., "Le Clos Fleuri in Giverny, France. Amenities: Free breakfast: Yes..." hotel_texts = get_hotel_texts() # Initialize Vector Store connected to Capella vector_store = CouchbaseVectorStore( cluster=cluster, bucket_name=bucket_name, scope_name=scope_name, collection_name=collection_name, embedding=embeddings, index_name=index_name, ) # Batch upload texts vector_store.add_texts(texts=hotel_texts) print(f"Successfully loaded {len(hotel_texts)} hotel embeddings") |
Etapa 5: Criação do agente LangChain
Usamos o Catálogo de agentes para buscar nossas definições de ferramentas e prompts dinamicamente. O código permanece genérico, enquanto seus recursos (ferramentas) e personalidade (prompts) são gerenciados separadamente. Também criaremos nosso ReAct agentes.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import agentc from langchain.agents import AgentExecutor, create_react_agent from langchain_core.prompts import PromptTemplate from langchain_core.tools import Tool def create_langchain_agent(self, catalog, span): # 1. Setup AI Services using Capella endpoints embeddings, llm = setup_ai_services(framework="langchain") # 2. Discover Tools from Catalog # The catalog.find() method searches your published catalog tool_search = catalog.find("tool", name="search_vector_database") tools = [ Tool( name=tool_search.meta.name, description=tool_search.meta.description, func=tool_search.func, # The actual python function ), ] # 3. Discover Prompt from Catalog hotel_prompt = catalog.find("prompt", name="hotel_search_assistant") # 4. Construct the Prompt Template custom_prompt = PromptTemplate( template=hotel_prompt.content.strip(), input_variables=["input", "agent_scratchpad"], partial_variables={ "tools": "\n".join([f"{tool.name}: {tool.description}" for tool in tools]), "tool_names": ", ".join([tool.name for tool in tools]), }, ) # 5. Create the ReAct Agent agent = create_react_agent(llm, tools, custom_prompt) agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, handle_parsing_errors=True, # Auto-correct formatting errors max_iterations=5, return_intermediate_steps=True, ) return agent_executor |
Etapa 6: Execução do agente
Com o agente inicializado, podemos realizar consultas complexas. O agente irá:
- Receber a entrada do usuário.
- Decidir que ele precisa usar o
banco de dados de pesquisa de vetoresferramenta. - Execute a pesquisa em relação ao Capella.
- Sintetize os resultados em uma resposta em linguagem natural.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Initialize Agent Catalog catalog = agentc.catalog.Catalog() span = catalog.Span(name="Hotel Support Agent", blacklist=set()) # Create the agent agent_executor = couchbase_client.create_langchain_agent(catalog, span) # Run a query query = "Find hotels in Giverny with free breakfast" response = agent_executor.invoke({"input": query}) print(f"User: {query}") print(f"Agent: {response['output']}") |
Exemplo de saída:
Agente: Encontrei um hotel em Giverny que oferece café da manhã gratuito chamado Le Clos Fleuri. Ele está localizado na 5 rue de la Dîme, 27620 Giverny. Oferece internet e estacionamento gratuitos.

Observação: No Capella Model Services, os resultados do modelo podem ser em cache (cache semântico e padrão). O mecanismo de cache aumenta a eficiência e a velocidade do RAG, principalmente ao lidar com consultas repetidas ou semelhantes. Quando uma consulta é processada pela primeira vez, o LLM gera uma resposta e, em seguida, armazena essa resposta no Couchbase. Quando consultas semelhantes chegam posteriormente, as respostas armazenadas em cache são retornadas. A duração do armazenamento em cache pode ser configurada nos serviços do Capella Model.
Adição de cache semântico
O armazenamento em cache é particularmente valioso em cenários em que os usuários podem enviar consultas semelhantes várias vezes ou em que determinadas informações são solicitadas com frequência. Ao armazenar essas informações em um cache, podemos reduzir significativamente o tempo necessário para responder a essas consultas, melhorando a experiência do usuário.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
## Semantic Caching Demonstration # This section demonstrates how to enable and use Semantic Caching with Capella Model Services. # Semantic caching stores responses for queries and reuses them for semantically similar future queries, significantly reducing latency and cost. # 1. Setup LLM with Semantic Caching enabled # We pass the "X-cb-cache": "semantic" header to enable the feature print(" Setting up LLM with Semantic Caching enabled...") llm_with_cache = ChatOpenAI( model=os.environ["CAPELLA_API_LLM_MODEL"], base_url=os.environ["CAPELLA_API_LLM_ENDPOINT"] + "/v1" if not os.environ["CAPELLA_API_LLM_ENDPOINT"].endswith("/v1") else os.environ["CAPELLA_API_LLM_ENDPOINT"], api_key=os.environ["CAPELLA_API_LLM_KEY"], temperature=0, # Deterministic for caching default_headers={"X-cb-cache": "semantic"} ) # 2. Define a query and a semantically similar variation query_1 = "What are the best hotels in Paris with a view of the Eiffel Tower?" query_2 = "Recommend some hotels in Paris where I can see the Eiffel Tower." print(f"\n Query 1: {query_1}") print(f" Query 2 (Semantically similar): {query_2}") # 3. First execution (Cache Miss) print("\n Executing Query 1 (First run - Cache MISS)...") start_time = time.time() response_1 = llm_with_cache.invoke(query_1) end_time = time.time() time_1 = end_time - start_time print(f" Time taken: {time_1:.4f} seconds") print(f" Response: {response_1.content[:100]}...") # 4. Second execution (Cache Hit) # The system should recognize query_2 is semantically similar to query_1 and return the cached response print("\n Executing Query 2 (Semantically similar - Cache HIT)...") start_time = time.time() response_2 = llm_with_cache.invoke(query_2) end_time = time.time() time_2 = end_time - start_time print(f" Time taken: {time_2:.4f} seconds") print(f" Response: {response_2.content[:100]}...") |
Etapa 7: Observabilidade com o Arize Phoenix
Na produção, você precisa saber por que um agente deu uma resposta específica. Usamos o Arize Phoenix para rastrear o “processo de pensamento” do agente (a cadeia ReAct).
Também podemos executar avaliações para verificar alucinações ou relevância.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import phoenix as px from phoenix.evals import llm_classify, LENIENT_QA_PROMPT_TEMPLATE # 1. Start Phoenix Server session = px.launch_app() # 2. Instrument LangChain from openinference.instrumentation.langchain import LangChainInstrumentor LangChainInstrumentor().instrument() # ... Run your agent queries ... # 3. Evaluate Results # We use an LLM-as-a-judge to grade our agent's responses hotel_qa_results = llm_classify( data=hotel_eval_df[["input", "output", "reference"]], model=evaluator_llm, template=LENIENT_QA_PROMPT_TEMPLATE, rails=["correct", "incorrect"], provide_explanation=True, ) |
Ao inspecionar a UI do Phoenix, você pode visualizar a sequência exata de chamadas de ferramentas e ver a latência de cada etapa da cadeia.
Conclusão
Criamos com sucesso um agente de busca de hotéis robusto. Essa arquitetura aproveita:
- Serviços de IA do Couchbase: Para uma camada de dados e IA unificada e de baixa latência.
- Catálogo de agentes: Para um gerenciamento organizado e com controle de versão das ferramentas e prompts do agente. O catálogo de agentes também oferece rastreamento. Ele permite que os usuários usem o SQL++ com rastreamentos, aproveitem o desempenho do Couchbase e obtenham informações sobre detalhes de prompts e ferramentas na mesma plataforma.
- LangChain: Para uma orquestração flexível.
- Arize Phoenix: Para observabilidade.
Essa abordagem é bem dimensionada para equipes que criam sistemas multiagentes complexos, em que o gerenciamento de dados e a descoberta de ferramentas são desafios críticos.