For the complete documentation index, see llms.txt. This page is also available as Markdown.

Build a KB Agent End to End

Build a role-scoped knowledge-base agent end to end: load your data, assign roles, build the agent, test it, and manage it over time.

This guide walks the whole path: get your data into the platform, scope access so each user only sees what their role permits, build the agent, test it, and keep changing it safely. It assumes you are new to the platform and points you to the exact pages and commands at each step. Workspace access, source-specific connector configuration, and queryable tables must be ready before the relevant steps. Raw file uploads can require Concurrence-assisted table setup; see the prerequisites below.

Read this guide first. It covers the whole build path. When you reach step 3, the retrieval-architecture decision and the measurement-driven build loop are covered in depth in the companion deep-dive, Knowledge-Base Agent: Retrieval and Build Methodology.

What you'll build: an agent that answers your team's questions from your own knowledge base, where each user sees only the documents and tools their role allows, and any per-user integration is called as that user.

The path:

  1. Load your data so the platform can serve it.

  2. Assign roles so each user sees the right data (skip if you don't need per-user scoping).

  3. Build the agent that finds and grounds answers.

  4. Test it for answer quality and for correct permissions.

  5. Change, test, and deploy as you keep improving it.

A few terms used throughout: the world model is the platform's normalized store of your data; an entity is one record in it (a person, an encounter); a skill or tool is something the agent can do or call; a context graph is the agent's conversation state machine. If any of these are new, skim Core Concepts first.

Before you start

  • For raw file uploads, an agreed dataset contract and a queryable-table setup with your Concurrence contact. Upload acceptance alone does not make a file retrievable by an agent.

  • A workspace and platform credentials. See Authentication & API Keys.

  • The forge platform CLI (used for the commands below), or the console. Either works.

  • All commands below use --env <env>, which points the CLI at your workspace credentials. The example values (emails, ids, role names) are placeholders; replace them with your own.

Step 1: Load your data

You are loading two kinds of data: the documents your agent answers from (your knowledge base), and, if you'll scope access per user, the people who use it (and their roles). Choose the supported ingestion path for your source. Confirm mapping, processing, and queryability separately from submission.

FHIR data (already in a healthcare format)

Push a FHIR bundle and it projects into the world model automatically, no custom code:

This is the best path for clinicians and patients, which are typically already FHIR (a clinician is a Practitioner). See FHIR.

A live connection (retired)

Live connector syncs were retired with the connector runner on October 10, 2026. A data-source record can still be saved, but nothing polls it, and the sync-trigger operation was removed. Load changing data with repeated FHIR imports or file uploads instead.

A file upload

For a one-off file, register the dataset contract and upload the file with a workspace credential. See Data Intake for the current upload operation and processing workflow. The former shareable upload-link system has been retired.

An uploaded file needs one more step before an agent can query it. Supported FHIR imports must finish mapping and projection before you verify queryability. A raw file upload (for example a CSV) is stored and logged, but turning it into a structured table the agent can query is not yet automatic, so work with your Concurrence contact to set that table up. Once the table exists, you expose it to the agent as a warehouse tool (step 3).

Keeping data current and controlling what's exposed

  • Update: re-importing a FHIR bundle updates the affected resources.

  • History: check a FHIR resource's version history with GET /v1/{workspace_id}/fhir/resources/{resource_type}/{resource_id}/history.

  • Exposure: which data a given user's agent can actually reach is controlled by role grants (step 2) and by which tables the agent's tools query (step 3), not by the raw data load.

Step 2: Assign roles so each user sees the right data

Skip this step if every session is the same and there is no per-user scoping.

If different users should see different things (a clinician sees their caseload, a specialist sees specialist procedures, an administrator can't read clinical detail), use external principals. The model never decides who the user is: you map each user to an entity and its roles, and the platform scopes the agent's tools and data to those roles and passes the user's identity through to your integrations. Set it up in four commands.

2.1 Register your roles

A role is a named bundle that grants attach to. Create one per role your system uses:

name is the internal slug you'll reference; external_name is your system's label. List them to get their ids: forge platform external-role list --env <env>. (Endpoint: POST /v1/{workspace_id}/external-roles.)

2.2 Map each user to an entity and roles

Each user is a person entity in the world model (loaded in step 1; entity_id is that person's world-model id, which you can look up via Data & World Model). Bind the user's identity and roles to it:

external_subject_key is the user's stable identity (usually their email); it's what gets passed through to your integrations. Re-running with the same (source, external_subject_key) updates in place, so a roster sync is idempotent. A multi-role user just lists multiple roles and gets the union. (Endpoint: PUT /v1/{workspace_id}/external-role-assignments.)

2.3 Grant each role its scopes

A grant says "this role may use this resource." resource_type is one of kb_scope (a scope tag on your documents), skill (a skill slug), or integration_endpoint (an endpoint id); access is read or write:

A resource is unrestricted until a grant references it; once any grant does, only the granted roles may use it. (Endpoint: POST /v1/{workspace_id}/role-grants.)

2.4 Anchor the conversation to the user's entity

In production the user's SSO session anchors the conversation automatically. To start one yourself (for testing, or operator-started sessions), pass the entity explicitly:

From here, every tool call and integration is scoped to that user's roles for the life of the session. For the full reference, see External Principals.

Step 3: Build the agent

A KB agent has three moving parts: an index of your documents the agent can see, a tool to fetch a document by id, and a retrieval strategy. For a small knowledge base, the simplest strategy wins: preload the whole catalog (titles and ids) so the agent picks the documents it needs and fetches them by id. For a larger corpus, switch to hybrid search.

Build it measurement-first: write the conversations you want the agent to handle as tests, start from a bare-bones agent, and add only what a failing test demands. The agent ends up with exactly the complexity its tests require, and nothing speculative.

Turn requirements into a coverage matrix and fixed test conversations, run a minimal agent, inspect failures, make one bounded change, and rerun. A candidate is ready for review only when repeated results meet the criteria and preserve the baseline.
Keep fixed conversations and versioned baselines so each change can be checked for regressions.

Adding what the agent can do

The agent acts through skills and tools. A skill is an LLM-driven capability; a tool or platform function calls out to data or an API. Common additions:

  • Query a table you loaded in step 1 (for example, ad-hoc analytics): create a warehouse tool, a SQL platform function that selects from your table. The agent calls it like any tool.

  • Call an external system: configure an integration and expose its endpoints as tools.

  • Add a capability: author a skill.

If an endpoint the agent needs doesn't exist yet, it has to be built first. The platform can call an endpoint, but it can't invent one. An API your agent should use that doesn't exist in your systems today is net-new work (by your team or with Concurrence) before it can be wired in as an integration.

Step 4: Test it

Test two things separately.

Answer quality. Does the agent fetch the right document, ground its reply in it, and decline when the knowledge base has no answer? Build a fixed question set with known-good answers and run it. That question set is the durable asset: every future change becomes a quick re-run instead of a guess. See Simulation Coverage and Tool Testing.

Permissions. Anchor a conversation as a given role and confirm the agent only reaches what that role permits.

Test permissions at the right layer. Tool and integration-endpoint grants are enforced by the platform: a disallowed tool call returns a structured refusal you can see in the transcript. Knowledge-base document scoping is enforced today by the agent's own behavior reading the user's role context, so verify it by checking the agent's fetches against the role rather than expecting a platform-level block.

Step 5: Change, test, and deploy over time

Once the agent is live you'll keep changing it. Do that safely with version sets and regression tests.

  • Version sets pin which agent, context graph, and model a service uses, like git branches for your configuration. edge always points at your latest; release is what production serves. You iterate on a version set, then promote it to release to deploy. See Version Sets & Promotion.

  • Regression-test before you promote. Re-run the test set from step 4 against the changed version and compare it to a saved baseline; promote only if it holds. The methodology guide covers running the suite, saving baselines, and reading the diff.

So the lifecycle is one loop: change on a version set, regression-test against your suite, promote to release to deploy. Repeat.

You're done

You loaded data, scoped access, built an agent, tested it, and have a safe way to keep changing it, end to end. From here: expand your test set as you find gaps, add live-lookup tools for real-time data, and move to hybrid search as the knowledge base grows past the catalog-preload size.

Last updated

Was this helpful?