{"id":5100,"date":"2026-01-26T12:58:14","date_gmt":"2026-01-26T20:58:14","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/"},"modified":"2026-01-26T12:58:14","modified_gmt":"2026-01-26T20:58:14","slug":"migrate-your-existing-agents-to-couchbase-ai-services","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/","title":{"rendered":"Migrate Your Existing Agents to Couchbase AI Services"},"content":{"rendered":"\n<p><span>A typical AI agent application in 2025 usually involves:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span>A cloud-hosted LLM<\/span><\/li>\n\n\n<li><span>A vector database for retrieval<\/span><\/li>\n\n\n<li><span>A separate operational database<\/span><\/li>\n\n\n<li><span>Prompt management and tool management tools<\/span><\/li>\n\n\n<li><span>Observability and tracing frameworks<\/span><\/li>\n\n\n<li><span>Guardrails<\/span><\/li>\n\n<\/ul>\n\n\n\n<p><span>Each tool solves a problem. Collectively, however, they can potentially create architectural sprawl with unpredictable latency, rising operational costs, and governance blind spots. As a result, a lot of AI agents never move beyond demos or internal prototypes because the complexity escalates too fast.<\/span><\/p>\n\n\n\n<p><span>This post walks through how we migrated an existing AI agent application to Couchbase AI Services and the Agent Catalog, moving to a single production-ready AI platform.\u00a0<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>The Core Problem: Fragmentation Kills Production AI<\/span><\/h2>\n\n\n\n<p><span>It&#8217;s important to understand why agentic systems struggle in production. Most AI agents today are built from too many loosely coupled parts: prompts live in one system, vectors in another, conversations are logged inconsistently, tools are invoked without clear traceability <\/span><span>\u2013<\/span><span> making agent behavior difficult to debug. At the same time, sending enterprise data to third-party LLM endpoints introduces compliance and security risks. Finally, governance is usually treated as an afterthought; many frameworks emphasize what an agent can do, but fail to explain why it made a decision, which prompt or tool influenced it, or whether that decision should have been allowed at all. This is an unacceptable gap for real business workflows.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>What Are Couchbase AI Services?<\/span><\/h2>\n\n\n\n<p><span>Building AI applications often involves juggling multiple services: a vector database for memory, an inference provider for LLMs (like OpenAI or Anthropic), and separate infrastructure for embedding models.<\/span><\/p>\n\n\n\n<p><b>Couchbase AI Services<\/b><span> streamlines this by providing a unified platform where your operational data, vector search, and AI models live together. It offers:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><b>LLM inference and embeddings API:<\/b><span> Access popular LLMs (like Llama 3) and embedding models directly within Couchbase Capella, with no external API keys, no extra infrastructure, and no data egress. Your application data stays inside Capella. Queries, vectors, and model inference all happen where the data lives. This enables secure, low-latency AI experiences while meeting privacy and compliance requirements. The key value: data and AI together, with sensitive information kept inside your system.<\/span><\/li>\n\n\n<li><b>Unified platform:<\/b><span> Maintain your database, vectorization, search, and model in a central location.<\/span><\/li>\n\n\n<li><b>Integrated Vector Search:<\/b><span> Perform semantic search directly on your JSON data with millisecond latency.<\/span><\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Why Is This Needed?<\/span><\/h3>\n\n\n\n<p><span>As we move from simple chatbots to <\/span><b>agentic workflows<\/b> <span>\u2013<\/span><span> where AI models autonomously use tools <\/span><span>\u2013<\/span><span> latency and setup complexity become major bottlenecks. Couchbase AI Services takes a platform-first approach. By co-locating your data and AI services, it reduces operational overhead and latency. In addition, tools like the <\/span><b>Agent Catalog<\/b><span> help manage hundreds of agent prompts and tools, while providing built-in logging and telemetry for agents.\u00a0<\/span><\/p>\n\n\n\n<p><span>At this point, the question shifts from why a platform-first approach matters to how it works in practice.<\/span><\/p>\n\n\n\n<p><span>So let\u2019s explore how you can migrate an existing agentic application, and improve its performance, governance, and reliability along the way.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>What the Current App Looks Like<\/span><\/h2>\n\n\n\n<p><span>The current application is an HR Sourcing Agent designed to automate the initial screening of candidates. The main job of the agent application is to ingest raw resume files (PDFs), understand the content of the resumes using an LLM, and structure the unstructured data into a queryable format enriched with semantic embeddings in Couchbase. It allows HR professionals to upload a new job description and get results for the best-suited candidates using Couchbase vector search.\u00a0<\/span><\/p>\n\n\n\n<p><span>In its current state, the HR Sourcing App is a Python-based microservice that wraps an LLM with the Google ADK. It manually wires together model definitions, agent prompts, and execution pipelines. While functional, the architecture requires the developer to manage session state in memory, handle retry logic, clean raw model outputs, and maintain the integration between the LLM and the database manually. Also, there is no built-in telemetry for our agent.\u00a0<\/span><\/p>\n\n\n\n<p><span>\u200b\u200bThe app manually instantiates a model provider. In this specific case, it connects to a hosted open source model (Qwen 2.5-72B via Nebius) using the <\/span><a href=\"https:\/\/www.litellm.ai\/\"><span>LiteLLM<\/span><\/a><span> wrapper. The app has to manually spin up a runtime environment for the agent. It initializes an InMemorySessionService to track the state of the conversation (even if short-lived) and a Runner to execute the user&#8217;s input (the resume text) against the agent pipeline.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>Migrating the Agent Application to Couchbase AI Services<\/span><\/h2>\n\n\n\n<p><span>Now let\u2019s dive into how to migrate the core logic of our agent to use Couchbase AI Services and the Agent Catalog.\u00a0<\/span><\/p>\n\n\n\n<p><span>The new agent uses a LangChain ReAct agent to process job descriptions, it performs intelligent candidate matching using vector search and provides ranked candidate recommendations with explanations.\u00a0<\/span><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Prerequisites<\/span><\/h3>\n\n\n\n<p><span>Before we begin, ensure you have:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span>Python 3.10+ installed.<\/span><\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Install Dependencies<\/span><\/h3>\n\n\n\n<p><span>We&#8217;ll start by installing the necessary packages. This includes the <\/span><span>agentc<\/span><span> CLI for the catalog and the LangChain integration packages.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]%pip install -q<br \/>\n    &#8220;pydantic&gt;=2.0.0,&lt;3.0.0&#8221;  &#8220;python-dotenv&gt;=1.0.0,&lt;2.0.0&#8221;  &#8220;pandas&gt;=2.0.0,&lt;3.0.0&#8221;  &#8220;nest-asyncio&gt;=1.6.0,&lt;2.0.0&#8221;  &#8220;langchain-couchbase&gt;=0.2.4,&lt;0.5.0&#8221;  &#8220;langchain-openai&gt;=0.3.11,&lt;0.4.0&#8221;  &#8220;arize-phoenix&gt;=11.37.0,&lt;12.0.0&#8221;  &#8220;openinference-instrumentation-langchain&gt;=0.1.29,&lt;0.2.0&#8221;<\/p>\n<p># Install Agent Catalog<br \/>\n%pip install agentc==1.0.0[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Centralized Model Service (Couchbase AI Model Services Integration)<\/span><\/h3>\n\n\n\n<p><span>In the original <\/span><i><span>adk_resume_agent.py<\/span><\/i><span>, we had to manually instantiate LiteLLM, manage specific provider API keys (Nebius, OpenAI, etc.), and handle the connection logic inside our application code. We will migrate the code to use Couchbase.\u00a0<\/span><\/p>\n\n\n\n<p><span>Couchbase AI Services provides OpenAI-compatible endpoints that are used by the agents. For the LLM and embeddings, we use the LangChain OpenAI package, which integrates directly with the LangChain Couchbase connector.<\/span><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span>Enable AI Services<\/span><\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span>Navigate to Capella\u2019s AI Services section on the UI.<\/span><\/li>\n\n\n<li><span>Deploy the Embeddings and LLM models.<\/span>\n<ul>\n<li><span>You need to launch an embedding and an LLM for this demo in the same region as the Capella cluster where the data will be stored.<\/span><\/li>\n<li><span>Deploy an LLM that has tool calling capabilities such as <\/span><i><span>mistralai\/mistral-7b-instruct-v0.3<\/span><\/i><span>. For embeddings, you can choose a model like the <\/span><i><span>nvidia\/llama-3.2-nv-embedqa-1b-v2<\/span><\/i><span>.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n<li><span>Note the endpoint URL and generate API keys.<\/span><\/li>\n\n<\/ol>\n\n\n\n<p><span>For more details on launching AI models, you can check the <\/span><a href=\"https:\/\/docs.couchbase.com\/ai\/build\/model-service\/model-service.html\"><span>official documentation<\/span><\/a><span>.<\/span><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span>Implementing the Code Logic for LLM and Embedding Models<\/span><\/h4>\n\n\n\n<p><span>We need to configure the endpoints for Capella Model Services. Capella Model Services are compatible with the OpenAI API format, so we can use the standard <\/span><span>langchain-openai<\/span><span> library by pointing it to our Capella endpoint. We initialize the embedding model with <\/span><span>OpenAIEmbeddings<\/span><span> and the LLM with <\/span><span>ChatOpenAI<\/span><span>, but point it to Capella. <\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]# Model Services Config<br \/>\nCAPELLA_API_ENDPOINT = getpass.getpass(&#8220;Capella Model Services Endpoint: &#8220;)<br \/>\nCAPELLA_API_LLM_MODEL = &#8220;mistralai\/mistral-7b-instruct-v0.3&#8221;<br \/>\nCAPELLA_API_LLM_KEY = getpass.getpass(&#8220;LLM API Key: &#8220;)<br \/>\nCAPELLA_API_EMBEDDING_MODEL = &#8220;nvidia\/llama-3.2-nv-embedqa-1b-v2&#8221;<br \/>\nCAPELLA_API_EMBEDDINGS_KEY = getpass.getpass(&#8220;Embedding API Key: &#8220;)<\/p>\n<p>def setup_ai_services(temperature: float = 0.0):<br \/>\n    embeddings = None<br \/>\n    llm = None<\/p>\n<p>    if not embeddings and os.getenv(&#8220;CAPELLA_API_ENDPOINT&#8221;) and os.getenv(&#8220;CAPELLA_API_EMBEDDINGS_KEY&#8221;):<br \/>\n        try:<br \/>\n            endpoint = os.getenv(&#8220;CAPELLA_API_ENDPOINT&#8221;)<br \/>\n            api_key = os.getenv(&#8220;CAPELLA_API_EMBEDDINGS_KEY&#8221;)<br \/>\n            model = os.getenv(&#8220;CAPELLA_API_EMBEDDING_MODEL&#8221;, &#8220;Snowflake\/snowflake-arctic-embed-l-v2.0&#8221;)<\/p>\n<p>            api_base = endpoint if endpoint.endswith(&#8216;\/v1&#8217;) else f&#8221;{endpoint}\/v1&#8243;<\/p>\n<p>            embeddings = OpenAIEmbeddings(<br \/>\n                model=model,<br \/>\n                api_key=api_key,<br \/>\n                base_url=api_base,<br \/>\n                check_embedding_ctx_length=False,<br \/>\n            )<br \/>\n        except Exception as e:<br \/>\n            logger.error(f&#8221;Couchbase AI embeddings failed: {e}&#8221;)<\/p>\n<p>    if not llm and os.getenv(&#8220;CAPELLA_API_ENDPOINT&#8221;) and os.getenv(&#8220;CAPELLA_API_LLM_KEY&#8221;):<br \/>\n        try:<br \/>\n            endpoint = os.getenv(&#8220;CAPELLA_API_ENDPOINT&#8221;)<br \/>\n            llm_key = os.getenv(&#8220;CAPELLA_API_LLM_KEY&#8221;)<br \/>\n            llm_model = os.getenv(&#8220;CAPELLA_API_LLM_MODEL&#8221;, &#8220;deepseek-ai\/DeepSeek-R1-Distill-Llama-8B&#8221;)<\/p>\n<p>            api_base = endpoint if endpoint.endswith(&#8216;\/v1&#8217;) else f&#8221;{endpoint}\/v1&#8243;<\/p>\n<p>            llm = ChatOpenAI(<br \/>\n                model=llm_model,<br \/>\n                base_url=api_base,<br \/>\n                api_key=llm_key,<br \/>\n                temperature=temperature,<br \/>\n            )<br \/>\n            test_response = llm.invoke(&#8220;Hello&#8221;)<br \/>\n        except Exception as e:<br \/>\n            logger.error(f&#8221;Couchbase AI LLM failed: {e}&#8221;)<br \/>\n            llm = None[\/crayon]<\/p>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<p><span>Instead of hardcoding model providers, the agent now connects to a unified Capella endpoint, which acts as an API gateway for both the LLM and the embedding model.\u00a0<\/span><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Decoupling Prompts and Tools With Agent Catalog<\/span><\/h3>\n\n\n\n<p><span>The Agent Catalog is a powerful tool for managing the lifecycle of your agent&#8217;s capabilities. Instead of hardcoding prompts and tool definitions in your Python files, you manage them as versioned assets. You can centralize and reuse your tools across your development teams. You can also examine and monitor agent responses with the Agent Tracer. These features provide visibility, control, and traceability for agent development and deployment. Your teams can build agents with confidence, knowing they can be audited and managed effectively.\u00a0\u00a0<\/span><\/p>\n\n\n\n<p><span>Without the ability to back-trace agent behavior, it becomes impossible to automate the ongoing trust, validation, and corroboration of the autonomous decisions made by agents. In the Agent Catalog, this is performed by evaluating both the agentic code and its conversation transcript with its LLM to assess the appropriateness of its pending decision or MCP tool lookup.\u00a0\u00a0<\/span><\/p>\n\n\n\n<p><span>So let\u2019s incorporate Agent Catalog in the project.\u00a0<\/span><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span>Adding the Vector Search Tool\u00a0<\/span><\/h4>\n\n\n\n<p><span>We will start by adding our tool definition for the Agent Catalog. In this case we have the vector search tool.\u00a0<\/span><\/p>\n\n\n\n<p><span>To add a new Python function as a tool for your agent, you can use the Agent Catalog command-line tool\u2019s add command:<\/span><\/p>\n\n\n\n<p><span>agentc add\u00a0<\/span><\/p>\n\n\n\n<p><span>If you have an existing Python tool that you want to add to the Agent Catalog, add agentc to your imports and the @agentc.catalog.tool decorator to your tool definition. In our example, we define a Python function for performing vector search as our tool.\u00a0<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]&#8221;&#8221;&#8221;<br \/>\nVector search tool for finding candidates based on job descriptions.<br \/>\nThis tool uses Couchbase vector search to find the most relevant candidates.<\/p>\n<p>Updated for Agent Catalog v1.0.0 with @tool decorator.<br \/>\n&#8220;&#8221;&#8221;<\/p>\n<p>import os<br \/>\nimport logging<br \/>\nfrom typing import List, Dict, Any<br \/>\nfrom datetime import timedelta<\/p>\n<p>from agentc_core.tool import tool<br \/>\nfrom couchbase.cluster import Cluster<br \/>\nfrom couchbase.auth import PasswordAuthenticator<br \/>\nfrom couchbase.options import ClusterOptions<br \/>\nfrom couchbase.vector_search import VectorQuery, VectorSearch<br \/>\nfrom couchbase.search import SearchRequest, MatchNoneQuery<\/p>\n<p>logger = logging.getLogger(__name__)<\/p>\n<p>def generate_embedding(text: str, embeddings_client) -&gt; List[float]:<br \/>\n    &#8220;&#8221;&#8221;Generate embeddings for text using the provided embeddings client.&#8221;&#8221;&#8221;<br \/>\n    try:<br \/>\n        # Use the embeddings client to generate embeddings<br \/>\n        result = embeddings_client.embed_query(text)<br \/>\n        return result<br \/>\n    except Exception as e:<br \/>\n        logger.error(f&#8221;Error generating embedding: {e}&#8221;)<br \/>\n        return [0.0] * 1024  # Return zero vector as fallback<\/p>\n<p>@tool(<br \/>\n    name=&#8221;search_candidates_vector&#8221;,<br \/>\n    description=&#8221;Search for candidates using vector similarity based on a job description. Returns matching candidate profiles ranked by relevance.&#8221;,<br \/>\n    annotations={&#8220;category&#8221;: &#8220;hr&#8221;, &#8220;type&#8221;: &#8220;search&#8221;}<br \/>\n)<br \/>\ndef search_candidates_vector(<br \/>\n    job_description: str,<br \/>\n    num_results: int = 5,<br \/>\n    embeddings_client=None,<br \/>\n) -&gt; str:<br \/>\n    &#8220;&#8221;&#8221;<br \/>\n    Search for candidates using vector similarity based on job description.<\/p>\n<p>    Args:<br \/>\n        job_description: The job description text to search against<br \/>\n        num_results: Number of top candidates to return (default: 5)<br \/>\n        embeddings_client: The embeddings client for generating query embeddings<\/p>\n<p>    Returns:<br \/>\n        Formatted string with candidate information<br \/>\n    &#8220;&#8221;&#8221;<br \/>\n    try:<br \/>\n        # Get environment variables<br \/>\n        bucket_name = os.getenv(&#8220;CB_BUCKET&#8221;, &#8220;travel-sample&#8221;)<br \/>\n        scope_name = os.getenv(&#8220;CB_SCOPE&#8221;, &#8220;agentc_data&#8221;)<br \/>\n        collection_name = os.getenv(&#8220;CB_COLLECTION&#8221;, &#8220;candidates&#8221;)<br \/>\n        index_name = os.getenv(&#8220;CB_INDEX&#8221;, &#8220;candidates_index&#8221;)<\/p>\n<p>        # Connect to Couchbase<br \/>\n        cluster = get_cluster_connection()<br \/>\n        if not cluster:<br \/>\n            return &#8220;Error: Could not connect to database&#8221;<\/p>\n<p>        bucket = cluster.bucket(bucket_name)<br \/>\n        scope = bucket.scope(scope_name)<br \/>\n        collection = scope.collection(collection_name)  # Use scope.collection(), not bucket.collection()<\/p>\n<p>        # Generate query embedding<br \/>\n        logger.info(f&#8221;Generating embedding for job description&#8230;&#8221;)<br \/>\n        if embeddings_client is None:<br \/>\n            return &#8220;Error: Embeddings client not provided&#8221;<\/p>\n<p>        query_embedding = generate_embedding(job_description, embeddings_client)<\/p>\n<p>        # Perform vector search<br \/>\n        logger.info(f&#8221;Performing vector search with index: {index_name}&#8221;)<br \/>\n        search_req = SearchRequest.create(MatchNoneQuery()).with_vector_search(<br \/>\n            VectorSearch.from_vector_query(<br \/>\n                VectorQuery(&#8220;embedding&#8221;, query_embedding, num_candidates=num_results * 2)<br \/>\n            )<br \/>\n        )<\/p>\n<p>        result = scope.search(index_name, search_req, timeout=timedelta(seconds=20))<br \/>\n        rows = list(result.rows())<\/p>\n<p>        if not rows:<br \/>\n            return &#8220;No candidates found matching the job description.&#8221;<\/p>\n<p>        # Fetch candidate details<br \/>\n        candidates = []<br \/>\n        for row in rows[:num_results]:<br \/>\n            try:<br \/>\n                doc = collection.get(row.id, timeout=timedelta(seconds=5))<br \/>\n                if doc and doc.value:<br \/>\n                    data = doc.value<br \/>\n                    data[&#8220;_id&#8221;] = row.id<br \/>\n                    data[&#8220;_score&#8221;] = row.score<br \/>\n                    candidates.append(data)<br \/>\n            except Exception as e:<br \/>\n                logger.warning(f&#8221;Error fetching candidate {row.id}: {e}&#8221;)<br \/>\n                continue<\/p>\n<p>        # Format results<br \/>\n        if not candidates:<br \/>\n            return &#8220;No candidate details could be retrieved.&#8221;<\/p>\n<p>        result_text = f&#8221;Found {len(candidates)} matching candidates:nn&#8221;<\/p>\n<p>        for i, candidate in enumerate(candidates, 1):<br \/>\n            result_text += f&#8221;**Candidate {i}: {candidate.get(&#8216;name&#8217;, &#8216;Unknown&#8217;)}**n&#8221;<br \/>\n            result_text += f&#8221;- Match Score: {candidate.get(&#8216;_score&#8217;, 0):.4f}n&#8221;<br \/>\n            result_text += f&#8221;- Email: {candidate.get(&#8217;email&#8217;, &#8216;N\/A&#8217;)}n&#8221;<br \/>\n            result_text += f&#8221;- Location: {candidate.get(&#8216;location&#8217;, &#8216;N\/A&#8217;)}n&#8221;<br \/>\n            result_text += f&#8221;- Years of Experience: {candidate.get(&#8216;years_experience&#8217;, 0)}n&#8221;<\/p>\n<p>            skills = candidate.get(&#8216;skills&#8217;, [])<br \/>\n            if skills:<br \/>\n                result_text += f&#8221;- Skills: {&#8216;, &#8216;.join(skills[:10])}n&#8221;<\/p>\n<p>            technical_skills = candidate.get(&#8216;technical_skills&#8217;, [])<br \/>\n            if technical_skills:<br \/>\n                result_text += f&#8221;- Technical Skills: {&#8216;, &#8216;.join(technical_skills[:10])}n&#8221;<\/p>\n<p>            summary = candidate.get(&#8216;summary&#8217;, &#8221;)<br \/>\n            if summary:<br \/>\n                # Truncate summary if too long<br \/>\n                summary_text = summary[:200] + &#8220;&#8230;&#8221; if len(summary) &gt; 200 else summary<br \/>\n                result_text += f&#8221;- Summary: {summary_text}n&#8221;<\/p>\n<p>            result_text += &#8220;n&#8221;<\/p>\n<p>        return result_text<\/p>\n<p>    except Exception as e:<br \/>\n        logger.error(f&#8221;Error in vector search: {e}&#8221;)<br \/>\n        import traceback<br \/>\n        traceback.print_exc()<br \/>\n        return f&#8221;Error performing candidate search: {str(e)}&#8221;<br \/>\n[\/crayon]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span>Adding the Prompts\u00a0<\/span><\/h4>\n\n\n\n<p><span>In the original architecture, the agent&#8217;s instructions were buried inside the Python code as large string variables, making them difficult to version or update without a full deployment. With the Agent Catalog, we now define our &#8220;HR Recruiter&#8221; persona as a standalone, managed asset using prompts. Using a structured YAML definition (record_kind: prompt), we create the hr_recruiter_assistant. This definition doesn&#8217;t just hold the text; it encapsulates the entire behavior of the agent, strictly defining the ReAct pattern (Thought \u2192 Action \u2192 Observation) that guides the LLM to use the vector search tool effectively.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]record_kind: prompt<br \/>\nname: hr_recruiter_assistant<br \/>\ndescription: AI-powered HR recruiter assistant that helps match candidates to job descriptions using vector search<br \/>\nannotations:<br \/>\n  category: hr<br \/>\n  type: recruitment<br \/>\ncontent: |<br \/>\n  You are an expert HR recruiter assistant with deep knowledge of talent acquisition and candidate matching.<br \/>\n  Your role is to help HR professionals find the best candidates for job openings by analyzing job descriptions<br \/>\n  and searching through a database of candidate profiles.<\/p>\n<p>  You have access to the following tools:<br \/>\n  {tools}<\/p>\n<p>  Use the following format for your responses:<\/p>\n<p>  Question: the input question or job description you must analyze<br \/>\n  Thought: think about what information you need to find the best candidates<br \/>\n  Action: the action to take, should be one of [{tool_names}]<br \/>\n  Action Input: the input to the action (for candidate search, provide the job description text)<br \/>\n  Observation: the result of the action<br \/>\n  &#8230; (this Thought\/Action\/Action Input\/Observation can repeat N times)<br \/>\n  Thought: I now have enough information to provide recommendations<br \/>\n  Final Answer: Provide a comprehensive summary of the top candidates including:<br \/>\n  &#8211; Candidate names and key qualifications<br \/>\n  &#8211; Skills match percentage and relevance<br \/>\n  &#8211; Years of experience<br \/>\n  &#8211; Why each candidate is a good fit for the role<br \/>\n  &#8211; Any notable strengths or unique qualifications<\/p>\n<p>  IMPORTANT GUIDELINES:<br \/>\n  &#8211; Always use the search_candidates_vector tool to find candidates<br \/>\n  &#8211; Analyze the job description to understand required skills and experience<br \/>\n  &#8211; Provide detailed reasoning for candidate recommendations<br \/>\n  &#8211; Highlight both technical skills and soft skills when relevant<br \/>\n  &#8211; Be specific about match percentages and scores<br \/>\n  &#8211; Format your final answer in a clear, professional manner<\/p>\n<p>  Begin!<\/p>\n<p>  Question: {input}<br \/>\n  Thought: {agent_scratchpad}<br \/>\n[\/crayon]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span>Index and Publishing the Local Files<\/span><\/h4>\n\n\n\n<p><span>We use <\/span><span>agentc<\/span><span> to index our local files and publish them to Couchbase. This stores the metadata in the database, making it searchable and discoverable by the agent at runtime.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]# Create local index of tools and prompts<br \/>\nagentc index .<\/p>\n<p># Upload to Couchbase<br \/>\nagentc publish<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>In our code, we initialize the Catalog and use catalog.find() to retrieve verified prompts and tools. We no longer hardcode prompts; instead, we fetch them.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]# BEFORE: Hardcoded Prompt Strings<br \/>\n# parse_instruction = &#8220;You are a resume parsing assistant&#8230;&#8221;<\/p>\n<p>import agentc<br \/>\nfrom agentc import Catalog, Span<\/p>\n<p># AFTER: Dynamic Asset Loading<br \/>\ncatalog = Catalog()<\/p>\n<p># Load the &#8220;search&#8221; tool dynamically<br \/>\ntool_result = catalog.find(&#8220;tool&#8221;, name=&#8221;search_candidates_vector&#8221;)<\/p>\n<p># Load the &#8220;recruiter&#8221; persona dynamically<br \/>\nprompt_result = catalog.find(&#8220;prompt&#8221;, name=&#8221;hr_recruiter_assistant&#8221;)<\/p>\n<p># We act on the retrieved metadata<br \/>\ntools = [Tool(name=tool_result.meta.name, func=&#8230;)]<br \/>\n[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Standardized Reasoning Engine (LangChain Integration)<\/span><\/h3>\n\n\n\n<p><span>The previous app used a custom SequentialAgent pipeline. While flexible, it meant we had to maintain our own execution loops, error handling, and retry logic for the agent&#8217;s reasoning steps.<\/span><span><br>\n<\/span><\/p>\n\n\n\n<p><span>By leveraging the Agent Catalog&#8217;s compatibility with LangChain, we switched to a standard ReAct (Reason + Act) agent architecture. We simply feed the tools and prompts fetched from the catalog directly into create_react_agent.<\/span><\/p>\n\n\n\n<p><span>What\u2019s the benefit? We get industry-standard reasoning loops <\/span><span>\u2013 <\/span><span>Thought -&gt; Action -&gt; Observation <\/span><span>\u2013<\/span><span> out of the box. The agent can now autonomously decide to search for &#8220;React Developers,&#8221; analyze the results, and then perform a second search for &#8220;Frontend Engineers&#8221; if the first yields few results. something the linear ADK pipeline struggled with.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]   def create_langchain_agent(self, catalog: Catalog, embeddings, llm):<\/p>\n<p>        try:<\/p>\n<p>            # Load tools from catalog using v1.0.0 API<br \/>\n            tool_result = catalog.find(&#8220;tool&#8221;, name=&#8221;search_candidates_vector&#8221;)<\/p>\n<p>            # Create tool wrapper that injects embeddings client<br \/>\n            def search_with_embeddings(job_description: str) -&gt; str:<br \/>\n                return tool_result.func(<br \/>\n                    job_description=job_description,<br \/>\n                    num_results=5,<br \/>\n                    embeddings_client=embeddings,<br \/>\n                )<\/p>\n<p>            tools = [<br \/>\n                Tool(<br \/>\n                    name=tool_result.meta.name,<br \/>\n                    description=tool_result.meta.description,<br \/>\n                    func=search_with_embeddings,<br \/>\n                ),<br \/>\n            ]<\/p>\n<p>            # Load prompt from catalog using v1.0.0 API<\/p>\n<p>            prompt_result = catalog.find(&#8220;prompt&#8221;, name=&#8221;hr_recruiter_assistant&#8221;)<br \/>\n            if prompt_result is None:<br \/>\n                raise ValueError(&#8220;Could not find hr_recruiter_assistant prompt in catalog. Run &#8216;agentc index&#8217; first.&#8221;)<\/p>\n<p>            custom_prompt = PromptTemplate(<br \/>\n                template=prompt_result.content.strip(),<br \/>\n                input_variables=[&#8220;input&#8221;, &#8220;agent_scratchpad&#8221;],<br \/>\n                partial_variables={<br \/>\n                    &#8220;tools&#8221;: &#8220;n&#8221;.join([f&#8221;{tool.name}: {tool.description}&#8221; for tool in tools]),<br \/>\n                    &#8220;tool_names&#8221;: &#8220;, &#8220;.join([tool.name for tool in tools]),<br \/>\n                },<br \/>\n            )<\/p>\n<p>            # Create agent<br \/>\n            agent = create_react_agent(llm, tools, custom_prompt)<br \/>\n            agent_executor = AgentExecutor(<br \/>\n                agent=agent,<br \/>\n                tools=tools,<br \/>\n                verbose=True,<br \/>\n                handle_parsing_errors=handle_parsing_error,<br \/>\n                max_iterations=5,<br \/>\n                max_execution_time=120,<br \/>\n                early_stopping_method=&#8221;force&#8221;,<br \/>\n                return_intermediate_steps=True,<br \/>\n            )<\/p>\n<p>            logger.info(&#8220;LangChain ReAct agent created successfully&#8221;)<br \/>\n            return agent_executor[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Built-in Observability (Agent Tracing)<\/span><\/h3>\n\n\n\n<p><span>In the previous agent application, observability was limited to print() statements. There was no way to &#8220;replay&#8221; an agent&#8217;s session to understand why it rejected a specific candidate.<\/span><\/p>\n\n\n\n<p><span>Agent Catalog provides tracing. It allows users to use SQL++ with traces, leverage the performance of Couchbase, and get insight into details of prompts and tools in the same platform.<\/span><\/p>\n\n\n\n<p><span>We can add Transactional Observability using catalog.Span(). We wrap the execution logic in a context manager that logs every thought, action, and result back to Couchbase. We can now view a full &#8220;trace&#8221; of the recruitment session in the Capella UI, showing exactly how the LLM processed a candidate&#8217;s resume.\u00a0<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]application_span = catalog.Span(name=&#8221;HR Recruiter Agent&#8221;)<\/p>\n<p># AFTER: granular observability<br \/>\nwith span.new(name=&#8221;job_matching_query&#8221;) as query_span:<br \/>\n    # Log the input<br \/>\n    query_span.log(UserContent(value=job_description))<\/p>\n<p>    # Run the agent<br \/>\n    response = agent.invoke({&#8220;input&#8221;: job_description})<\/p>\n<p>    # Log the agent&#8217;s final decision<br \/>\n    query_span.log(AssistantContent(value=response[&#8220;output&#8221;]))<\/p>\n<p>[\/crayon]<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-17852\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/Screenshot-2026-01-26-at-12.56.04-PM.png\" alt=\"\" width=\"1428\" height=\"914\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>Conclusion<\/b><\/h2>\n\n\n\n<p><span>AI agents fail in production not because LLMs lack capability, but because agentic systems can become too complex. By adopting a platform-first approach with Couchbase AI Services and the Agent Catalog, we transformed a complex agent into a governed, scalable agentic system.\u00a0<\/span><\/p>\n\n\n\n<p><span>If you\u2019re building AI agents today, the real question isn\u2019t <\/span><i><span>which LLM to use<\/span><\/i> <span>\u2013<\/span><span> it\u2019s how you\u2019ll run agents safely, observably, and at scale. Couchbase AI Services are built for exactly that.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A typical AI agent application in 2025 usually involves: Each tool solves a problem. Collectively, however, they can potentially create architectural sprawl with unpredictable latency, rising operational costs, and governance blind spots. As a result, a lot of AI agents never move beyond demos or internal prototypes because the complexity escalates too fast. This post [&hellip;]<\/p>\n","protected":false},"author":49,"featured_media":5099,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[754],"tags":[],"ppma_author":[110],"class_list":["post-5100","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-services"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Migrate Your Existing Agents to Couchbase AI Services - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Migrate Your Existing Agents to Couchbase AI Services\" \/>\n<meta property=\"og:description\" content=\"A typical AI agent application in 2025 usually involves: Each tool solves a problem. Collectively, however, they can potentially create architectural sprawl with unpredictable latency, rising operational costs, and governance blind spots. As a result, a lot of AI agents never move beyond demos or internal prototypes because the complexity escalates too fast. This post [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-26T20:58:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Laurent Doguin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ldoguin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laurent Doguin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/\"},\"author\":{\"name\":\"Laurent Doguin\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\"},\"headline\":\"Migrate Your Existing Agents to Couchbase AI Services\",\"datePublished\":\"2026-01-26T20:58:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/\"},\"wordCount\":3308,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png\",\"articleSection\":[\"AI Services\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/\",\"name\":\"Migrate Your Existing Agents to Couchbase AI Services - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png\",\"datePublished\":\"2026-01-26T20:58:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/migrate-your-existing-agents-to-couchbase-ai-services\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Migrate Your Existing Agents to Couchbase AI Services\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/c0aa9b8f1ed51b7a9e2f7cb755994a5e\",\"name\":\"Laurent Doguin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g\",\"caption\":\"Laurent Doguin\"},\"description\":\"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/ldoguin\"],\"honorificPrefix\":\"Mr\",\"birthDate\":\"1985-06-07\",\"gender\":\"male\",\"award\":[\"Devoxx Champion\",\"Couchbase Legend\"],\"knowsAbout\":[\"Java\"],\"knowsLanguage\":[\"English\",\"French\"],\"jobTitle\":\"Director Developer Relation & Strategy\",\"worksFor\":\"Couchbase\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/author\\\/laurent-doguin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Migrate Your Existing Agents to Couchbase AI Services - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/","og_locale":"en_US","og_type":"article","og_title":"Migrate Your Existing Agents to Couchbase AI Services","og_description":"A typical AI agent application in 2025 usually involves: Each tool solves a problem. Collectively, however, they can potentially create architectural sprawl with unpredictable latency, rising operational costs, and governance blind spots. As a result, a lot of AI agents never move beyond demos or internal prototypes because the complexity escalates too fast. This post [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/","og_site_name":"The Couchbase Blog","article_published_time":"2026-01-26T20:58:14+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png","type":"image\/png"}],"author":"Laurent Doguin","twitter_card":"summary_large_image","twitter_creator":"@ldoguin","twitter_misc":{"Written by":"Laurent Doguin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/"},"author":{"name":"Laurent Doguin","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e"},"headline":"Migrate Your Existing Agents to Couchbase AI Services","datePublished":"2026-01-26T20:58:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/"},"wordCount":3308,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png","articleSection":["AI Services"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/","url":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/","name":"Migrate Your Existing Agents to Couchbase AI Services - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png","datePublished":"2026-01-26T20:58:14+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Migrate-Your-Existing-Agents-to-Couchbase-AI-Services-1.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/migrate-your-existing-agents-to-couchbase-ai-services\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Migrate Your Existing Agents to Couchbase AI Services"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c0aa9b8f1ed51b7a9e2f7cb755994a5e","name":"Laurent Doguin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g12929ce99397769f362b7a90d6b85071","url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","caption":"Laurent Doguin"},"description":"Laurent is a nerdy metal head who lives in Paris. He mostly writes code in Java and structured text in AsciiDoc, and often talks about data, reactive programming and other buzzwordy stuff. He is also a former Developer Advocate for Clever Cloud and Nuxeo where he devoted his time and expertise to helping those communities grow bigger and stronger. He now runs Developer Relations at Couchbase.","sameAs":["https:\/\/x.com\/ldoguin"],"honorificPrefix":"Mr","birthDate":"1985-06-07","gender":"male","award":["Devoxx Champion","Couchbase Legend"],"knowsAbout":["Java"],"knowsLanguage":["English","French"],"jobTitle":"Director Developer Relation & Strategy","worksFor":"Couchbase","url":"https:\/\/www.couchbase.com\/blog\/author\/laurent-doguin\/"}]}},"acf":[],"authors":[{"term_id":110,"user_id":49,"is_guest":0,"slug":"laurent-doguin","display_name":"Laurent Doguin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b8c466908092b46634af916b6921f30187a051e4367ded7ac9b1a3f2c5692fd2?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/5100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/49"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=5100"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/5100\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/5099"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=5100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=5100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=5100"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=5100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}