10Advanced DEEPSEEK_API_KEY

RLM agent

Answer a question about a source directory that is too large for one prompt.

flowchart LR
  Q([query]) --> R[RLMAgent]
  R -- writes code --> X[sandbox]
  X -- reads files --> F[(FileSystemContext)]
  X -- sub-queries --> L[subLLM]
  R --> A([answer])

What it shows

  • The root model writes code that reads only the files it needs.
  • FileSystemContext loads files lazily and caches them.

The program

examples/rlm-agent/index.ts
import { readdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';

import { FileSystemContext, RLMAgent } from '@astack-tech/components';
import type { LLMProvider } from '@astack-tech/components';
import { ModelProvider } from '@astack-tech/integrations';

const apiKey = process.env['DEEPSEEK_API_KEY'];
if (!apiKey) {
  throw new Error('Set DEEPSEEK_API_KEY to run this example.');
}

// RLM needs a minimal text-in, text-out interface. Adapt Deepseek to it.
const model = new ModelProvider.Deepseek({ apiKey });
const llm: LLMProvider = {
  generate: prompt => model.generateCompletion(prompt),
};

// The context is a directory and a list of files in it. The root model writes code that
// reads files on demand, so the whole directory never has to fit in one prompt.
const sourceDir = fileURLToPath(new URL('../../packages/core/src', import.meta.url));
const files = readdirSync(sourceDir, { recursive: true, encoding: 'utf8' }).filter(file =>
  file.endsWith('.ts')
);
const context = new FileSystemContext(sourceDir, files);

const agent = new RLMAgent({ rootLLM: llm, subLLM: llm });

const result = await agent.run({
  context,
  query: 'How does Pipeline decide which output to return when no endpoint is given?',
});

console.log(result.answer);

Run it

pnpm install && pnpm build

export DEEPSEEK_API_KEY=sk-...
pnpm --filter @astack-examples/rlm-agent start
CONCEPTRLMAnswer questions over contexts that do not fit in one prompt.View the folder on GitHub