Agent skill

Langchain4j Vector Stores Configuration

by giuseppe-trisciuoglio in giuseppe-trisciuoglio/developer-kit

Provides configuration patterns for LangChain4J vector stores in RAG applications.

MITAuto-check: notesDatabases

Install Langchain4j Vector Stores Configuration

skills CLI
$ npx skills add giuseppe-trisciuoglio/developer-kit --skill langchain4j-vector-stores-configuration -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install giuseppe-trisciuoglio/developer-kit langchain4j-vector-stores-configuration --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/giuseppe-trisciuoglio/developer-kit.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/developer-kit-java/skills/langchain4j-vector-stores-configuration .claude/skills/langchain4j-vector-stores-configuration && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
langchain4j-vector-stores-configuration
GitHub stars
357
Token cost
~2.7k tokens
SKILL.md length
431 words
Files
3 (incl. references)
Skills in repo
115
Repo updated
First seen
Licence
MIT

At a glance

Provides configuration patterns for LangChain4J vector stores in RAG applications.

  • Works in 6 steps: Configure: Build the embedding store… → Test connection: Verify store… → Validate dimensions: Confirm embedding… → …
  • Building semantic search
  • SKILL.md covers Overview, When to Use, Instructions and Examples, plus 3 more sections
  • Needs OPENAI_API_KEY

What it does

Langchain4j Vector Stores Configuration is an agent skill from giuseppe-trisciuoglio/developer-kit. Provides configuration patterns for LangChain4J vector stores in RAG applications. Use when building semantic search, integrating vector databases (PostgreSQL/pgvector, Pinecone, MongoDB, Milvus, Neo4j), implementing embedding storage/retrieval, setting up hybrid search, or optimizing vector database performance for production AI applications.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/api-reference.md` and `references/examples.md`).

It sits in Databases, covering Vector databases and Retrieval-augmented generation. It works with Milvus, MongoDB, PostgreSQL and pgvector. The repository describes itself as: Modular plugin marketplace for Claude Code and agentic CLIs, with validated, spec-driven skills, agents, commands, and workflows for Java, TypeScript, Python, PHP, AWS, and AI. The licence is MIT.

When your agent uses it

  • Building semantic search
  • Integrating vector databases (PostgreSQL/pgvector
  • Implementing embedding storage/retrieval
  • Setting up hybrid search

Example prompts

  • “Use the langchain4j-vector-stores-configuration skill to provide configuration patterns for LangChain4J vector stores in RAG applications”
  • “/langchain4j-vector-stores-configuration”

Requirements

  • A credential in OPENAI_API_KEY
  • Pre-approved tools (allowed-tools): Read, Write, Edit, Bash, Glob, Grep

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Configure: Build the embedding store with required dimensions and connection parameters
  2. Test connection: Verify store connectivity with a health check before ingesting data
  3. Validate dimensions: Confirm embedding model dimensions match store configuration
  4. Ingest test data: Add a small batch of test documents to verify ingestion works
  5. Run test query: Execute a sample semantic search to confirm retrieval accuracy
  6. Proceed to production: Only after all steps pass, proceed with full data ingestion

What it can do on your machine

Read from SKILL.md and the folder at commit fe73fb3. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Bash
    • Glob
    • Grep

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are java).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • OPENAI_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Langchain4j Vector Stores Configuration loads about 2.7k tokens when it runs, and up to ~8.4k if it reads all its reference files. Until then it costs about 96 tokens; SKILL.md has 431 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~96
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~8.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Read, Write, Edit, Bash, Glob, Grep

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from giuseppe-trisciuoglio/developer-kit at commit fe73fb3, republished under its MIT licence (© giuseppe-trisciuoglio). 431 words, ~2,680 tokens.

Download SKILL.mdSave it as .claude/skills/langchain4j-vector-stores-configuration/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
langchain4j-vector-stores-configuration
description
Provides configuration patterns for LangChain4J vector stores in RAG applications. Use when building semantic search, integrating vector databases (PostgreSQL/pgvector, Pinecone, MongoDB, Milvus, Neo4j), implementing embedding storage/retrieval, setting up hybrid search, or optimizing vector database performance for production AI applications.
allowed-tools
Read, Write, Edit, Bash, Glob, Grep

LangChain4J Vector Stores Configuration

Configure vector stores for Retrieval-Augmented Generation applications with LangChain4J.

Overview

LangChain4J provides a unified abstraction for vector stores (PostgreSQL/pgvector, Pinecone, MongoDB Atlas, Milvus, Neo4j) with builder-based configuration, metadata filtering, and hybrid search support.

When to Use

  • Configuring vector stores for semantic search and RAG applications
  • Setting up embedding storage with metadata filtering and hybrid search
  • Optimizing vector database performance for production AI workloads

Instructions

Set Up Basic Vector Store

Configure an embedding store for vector operations:

java
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
    return PgVectorEmbeddingStore.builder()
        .host("localhost")
        .port(5432)
        .database("vectordb")
        .user("username")
        .password("password")
        .table("embeddings")
        .dimension(1536) // OpenAI embedding dimension
        .createTable(true)
        .useIndex(true)
        .build();
}
Validation Workflow

Follow this workflow to ensure correct vector store setup:

  1. Configure: Build the embedding store with required dimensions and connection parameters
  2. Test connection: Verify store connectivity with a health check before ingesting data
  3. Validate dimensions: Confirm embedding model dimensions match store configuration
  4. Ingest test data: Add a small batch of test documents to verify ingestion works
  5. Run test query: Execute a sample semantic search to confirm retrieval accuracy
  6. Proceed to production: Only after all steps pass, proceed with full data ingestion
Configure Multiple Vector Stores

Use different stores for different use cases:

java
@Configuration
public class MultiVectorStoreConfiguration {

    @Bean
    @Qualifier("documentsStore")
    public EmbeddingStore<TextSegment> documentsEmbeddingStore() {
        return PgVectorEmbeddingStore.builder()
            .table("document_embeddings")
            .dimension(1536)
            .build();
    }

    @Bean
    @Qualifier("chatHistoryStore")
    public EmbeddingStore<TextSegment> chatHistoryEmbeddingStore() {
        return MongoDbEmbeddingStore.builder()
            .collectionName("chat_embeddings")
            .build();
    }
}
Implement Document Ingestion

Use EmbeddingStoreIngestor for automated document processing:

java
@Bean
public EmbeddingStoreIngestor embeddingStoreIngestor(
        EmbeddingStore<TextSegment> embeddingStore,
        EmbeddingModel embeddingModel) {

    return EmbeddingStoreIngestor.builder()
        .documentSplitter(DocumentSplitters.recursive(
            300,  // maxSegmentSizeInTokens
            20,   // maxOverlapSizeInTokens
            new OpenAiTokenizer(GPT_3_5_TURBO)
        ))
        .embeddingModel(embeddingModel)
        .embeddingStore(embeddingStore)
        .build();
}
Set Up Metadata Filtering

Configure metadata-based filtering capabilities:

java
// MongoDB with metadata field mapping
IndexMapping indexMapping = IndexMapping.builder()
    .dimension(1536)
    .metadataFieldNames(Set.of("category", "source", "created_date", "author"))
    .build();

// Search with metadata filters
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
    .queryEmbedding(queryEmbedding)
    .maxResults(10)
    .filter(and(
        metadataKey("category").isEqualTo("technical_docs"),
        metadataKey("created_date").isGreaterThan(LocalDate.now().minusMonths(6))
    ))
    .build();
Configure Production Settings

Implement connection pooling and monitoring:

java
@Bean
public EmbeddingStore<TextSegment> optimizedPgVectorStore() {
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setJdbcUrl("jdbc:postgresql://localhost:5432/vectordb");
    hikariConfig.setUsername("username");
    hikariConfig.setPassword("password");
    hikariConfig.setMaximumPoolSize(20);
    hikariConfig.setMinimumIdle(5);
    hikariConfig.setConnectionTimeout(30000);

    DataSource dataSource = new HikariDataSource(hikariConfig);

    return PgVectorEmbeddingStore.builder()
        .dataSource(dataSource)
        .table("embeddings")
        .dimension(1536)
        .useIndex(true)
        .build();
}
Implement Health Checks

Monitor vector store connectivity:

java
@Component
public class VectorStoreHealthIndicator implements HealthIndicator {

    private final EmbeddingStore<TextSegment> embeddingStore;

    @Override
    public Health health() {
        try {
            embeddingStore.search(EmbeddingSearchRequest.builder()
                .queryEmbedding(new Embedding(Collections.nCopies(1536, 0.0f)))
                .maxResults(1)
                .build());

            return Health.up()
                .withDetail("store", embeddingStore.getClass().getSimpleName())
                .build();
        } catch (Exception e) {
            return Health.down()
                .withDetail("error", e.getMessage())
                .build();
        }
    }
}

Examples

Basic RAG Application Setup
java
@Configuration
public class SimpleRagConfig {

    @Bean
    public EmbeddingStore<TextSegment> embeddingStore() {
        return PgVectorEmbeddingStore.builder()
            .host("localhost")
            .database("rag_db")
            .table("documents")
            .dimension(1536)
            .build();
    }

    @Bean
    public ChatLanguageModel chatModel() {
        return OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY"));
    }
}
Semantic Search Service
java
@Service
public class SemanticSearchService {

    private final EmbeddingStore<TextSegment> store;
    private final EmbeddingModel embeddingModel;

    public List<String> search(String query, int maxResults) {
        Embedding queryEmbedding = embeddingModel.embed(query).content();

        EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
            .queryEmbedding(queryEmbedding)
            .maxResults(maxResults)
            .minScore(0.75)
            .build();

        return store.search(request).matches().stream()
            .map(match -> match.embedded().text())
            .toList();
    }
}
Production Setup with Monitoring
java
@Configuration
public class ProductionVectorStoreConfig {

    @Bean
    public EmbeddingStore<TextSegment> vectorStore(
            @Value("${vector.store.host}") String host,
            MeterRegistry meterRegistry) {

        EmbeddingStore<TextSegment> store = PgVectorEmbeddingStore.builder()
            .host(host)
            .database("production_vectors")
            .useIndex(true)
            .indexListSize(200)
            .build();

        return new MonitoredEmbeddingStore<>(store, meterRegistry);
    }
}

Best Practices

Choose the Right Vector Store

For Development:

  • Use InMemoryEmbeddingStore for local development and testing
  • Fast setup, no external dependencies
  • Data lost on application restart

For Production:

  • PostgreSQL + pgvector: Excellent for existing PostgreSQL environments
  • Pinecone: Managed service, good for rapid prototyping
  • MongoDB Atlas: Good integration with existing MongoDB applications
  • Milvus/Zilliz: High performance for large-scale deployments
Show full SKILL.md (152 more words)Show less
Configure Appropriate Index Types

Choose index types based on performance requirements:

java
// For high recall requirements
.indexType(IndexType.FLAT)  // Exact search, slower but accurate

// For balanced performance
.indexType(IndexType.IVF_FLAT)  // Good balance of speed and accuracy

// For high-speed approximate search
.indexType(IndexType.HNSW)  // Fastest, slightly less accurate
Optimize Vector Dimensions

Match embedding dimensions to your model:

java
// OpenAI text-embedding-3-small
.dimension(1536)

// OpenAI text-embedding-3-large
.dimension(3072)

// Sentence Transformers
.dimension(384)  // all-MiniLM-L6-v2
.dimension(768)  // all-mpnet-base-v2
Implement Batch Operations

Use batch operations for better performance:

java
@Service
public class BatchEmbeddingService {

    private static final int BATCH_SIZE = 100;

    public void addDocumentsBatch(List<Document> documents) {
        for (List<Document> batch : Lists.partition(documents, BATCH_SIZE)) {
            List<TextSegment> segments = batch.stream()
                .map(doc -> TextSegment.from(doc.text(), doc.metadata()))
                .collect(Collectors.toList());

            List<Embedding> embeddings = embeddingModel.embedAll(segments)
                .content();

            embeddingStore.addAll(embeddings, segments);
        }
    }
}
Secure Configuration

Protect sensitive configuration:

java
// Use environment variables
@Value("${vector.store.api.key:#{null}}")
private String apiKey;

// Validate configuration
@PostConstruct
public void validateConfiguration() {
    if (StringUtils.isBlank(apiKey)) {
        throw new IllegalStateException("Vector store API key must be configured");
    }
}

References

For comprehensive documentation and advanced configurations, see:

Constraints and Warnings

  • Vector dimensions must match the embedding model; mismatched dimensions will cause errors.
  • Large vector collections require proper indexing configuration for acceptable search performance.
  • Embedding generation can be expensive; implement batching and caching strategies.
  • Different vector stores have different distance metric support; verify compatibility.
  • Connection pooling is critical for production deployments to prevent connection exhaustion.
  • Metadata filtering capabilities vary between vector store implementations.
  • Vector stores consume significant memory; monitor resource usage in production.
  • Migration between vector store providers may require re-embedding all documents.
  • Batch operations are more efficient than single-document operations.
  • Always validate configuration during application startup to fail fast.

© giuseppe-trisciuoglio, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (references) in plugins/developer-kit-java/skills/langchain4j-vector-stores-configuration of giuseppe-trisciuoglio/developer-kit.

  • SKILL.md
  • references/api-reference.md
  • references/examples.md

Open the folder on GitHubat commit fe73fb3

Compare with similar skills

Langchain4j Vector Stores Configuration next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Langchain4j Vector Stores Configuration compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Langchain4j Vector Stores Configuration this skillgiuseppe-trisciuoglio/developer-kit357—~2.7kAutomated safety check: NotesMIT
Using Vector Databasesancoleman/ai-design-components525—~3.5kAutomated safety check: PassMIT
RAG Implementationwshobson/agents40k9 repos~1.1kAutomated safety check: PassMIT
Hunt RAG Vectorelementalsouls/Claude-BugHunter4.8k—~2.6kAutomated safety check: PassMIT
Vector Database Engineeraiskillstore/marketplace4337 repos~563Automated safety check: PassNone
Pgvector Semantic Searchtimescale/pg-aiguide1.9k—~3.8kAutomated safety check: PassApache-2.0

Similar skills

  • Using Vector Databases

    ancoleman/ai-design-components

    Vector database implementation for AI/ML applications, semantic search, and RAG systems.

    525 GitHub stars~3.5k tokensUpdated 10 mo ago
    DatabasesAuto-check passed
  • RAG Implementation

    wshobson/agents

    Build retrieval-augmented generation systems: pick a vector database and embedding model, choose retrieval and reranking strategies, and start from a LangGraph pipeline.

    40k GitHub starsUsed in 9 repos~1.1k tokens
    AI & LLM EngineeringAuto-check passed
  • Hunt RAG Vector

    elementalsouls/Claude-BugHunter

    Hunt vector-store / embedding-layer weaknesses in RAG pipelines (OWASP LLM08 Vector and Embedding Weaknesses) — persistent corpus poisoning that survives across sessions and users (distinct from…

    4.8k GitHub stars~2.6k tokensUpdated yesterday
    AI & LLM EngineeringAuto-check passed
  • Vector Database Engineer

    aiskillstore/marketplace

    Expert in vector databases, embedding strategies, and semantic search implementation.

    433 GitHub starsUsed in 7 repos~563 tokens
    DatabasesAuto-check passed
  • Pgvector Semantic Search

    timescale/pg-aiguide

    A skill your agent uses for setting up vector similarity search with pgvector for AI/ML embeddings, RAG applications, or semantic search.

    1.9k GitHub stars~3.8k tokensUpdated 3 days ago
    AI & LLM EngineeringAuto-check passed
  • Postgres Hybrid Text Search

    timescale/pg-aiguide

    A skill your agent uses to implement hybrid search combining BM25 keyword search with semantic vector search using Reciprocal Rank Fusion (RRF).

    1.9k GitHub stars~3.1k tokensUpdated 3 days ago
    AI & LLM EngineeringAuto-check passed

More from giuseppe-trisciuoglio/developer-kit

All 115 skills in this repo
  • Nestjs Drizzle Crud Generator

    giuseppe-trisciuoglio/developer-kit

    Generates complete CRUD modules for NestJS applications with Drizzle ORM.

    357 GitHub stars~1.3k tokensUpdated 1 mo ago
    Auto-check: notes
  • Spring Boot Actuator

    giuseppe-trisciuoglio/developer-kit

    Provides patterns to configure Spring Boot Actuator for production-grade monitoring, health probes, secured management endpoints, and Micrometer metrics across JVM services.

    357 GitHub stars~2.2k tokensUpdated 1 mo ago
    Auto-check: notes
  • Spring Boot Crud Patterns

    giuseppe-trisciuoglio/developer-kit

    Provides and generates complete CRUD workflows for Spring Boot 3 services.

    357 GitHub stars~2.5k tokensUpdated 1 mo ago
    Auto-check: notes
  • Spring Boot Security JWT

    giuseppe-trisciuoglio/developer-kit

    Provides JWT authentication and authorization patterns for Spring Boot 3.5.x covering token generation with JJWT, Bearer/cookie authentication, database/OAuth2 integration, and RBAC/permission-based…

    357 GitHub stars~3.9k tokensUpdated 1 mo ago
    Auto-check: notes
  • AWS CLI Beast

    giuseppe-trisciuoglio/developer-kit

    Provides advanced AWS CLI patterns for managing EC2, Lambda, S3, DynamoDB, RDS, VPC, IAM, and CloudWatch.

    357 GitHub stars~1.7k tokensUpdated 1 mo ago
    Auto-check: notes
  • PR Review Comments

    giuseppe-trisciuoglio/developer-kit

    Posts review findings from a JSON file as inline comments on a GitHub Pull Request, attaching each comment to its file and line.

    357 GitHub stars~1k tokensUpdated 1 mo ago
    Auto-check: notes

Categories

Questions about Langchain4j Vector Stores Configuration

What does Langchain4j Vector Stores Configuration do?

Provides configuration patterns for LangChain4J vector stores in RAG applications. Langchain4j Vector Stores Configuration is an agent skill from giuseppe-trisciuoglio/developer-kit. Provides configuration patterns for LangChain4J vector stores in RAG applications.

When should I use Langchain4j Vector Stores Configuration?

Langchain4j Vector Stores Configuration fits situations like: building semantic search; integrating vector databases (PostgreSQL/pgvector; implementing embedding storage/retrieval; setting up hybrid search.

How do I install Langchain4j Vector Stores Configuration in Claude Code?

Run `npx skills add giuseppe-trisciuoglio/developer-kit --skill langchain4j-vector-stores-configuration -a claude-code`. Or copy the skill folder (plugins/developer-kit-java/skills/langchain4j-vector-stores-configuration in giuseppe-trisciuoglio/developer-kit) into .claude/skills/langchain4j-vector-stores-configuration in your project. Claude Code loads it when a task matches its description.

How do I install Langchain4j Vector Stores Configuration in Codex?

Run `npx skills add giuseppe-trisciuoglio/developer-kit --skill langchain4j-vector-stores-configuration -a codex`. Or copy the skill folder (plugins/developer-kit-java/skills/langchain4j-vector-stores-configuration in giuseppe-trisciuoglio/developer-kit) into .agents/skills/langchain4j-vector-stores-configuration in your project. Codex loads it when a task matches its description.

Can I use Langchain4j Vector Stores Configuration in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add giuseppe-trisciuoglio/developer-kit --skill langchain4j-vector-stores-configuration -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/langchain4j-vector-stores-configuration, .gemini/skills/langchain4j-vector-stores-configuration, .github/skills/langchain4j-vector-stores-configuration and .opencode/skills/langchain4j-vector-stores-configuration in your project.

What does Langchain4j Vector Stores Configuration need to run?

Going by SKILL.md and its folder, Langchain4j Vector Stores Configuration needs credentials named OPENAI_API_KEY. Our summary lists: A credential in OPENAI_API_KEY. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash, Glob, Grep.

Does Langchain4j Vector Stores Configuration access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Langchain4j Vector Stores Configuration safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Langchain4j Vector Stores Configuration use?

Langchain4j Vector Stores Configuration is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Langchain4j Vector Stores Configuration use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 5.7k tokens, read only when the agent opens those files.

What are the alternatives to Langchain4j Vector Stores Configuration?

Skills that share tags, products or a category with Langchain4j Vector Stores Configuration: Using Vector Databases (ancoleman/ai-design-components, 525 stars), RAG Implementation (wshobson/agents, 40k stars), Hunt RAG Vector (elementalsouls/Claude-BugHunter, 4.8k stars) and Vector Database Engineer (aiskillstore/marketplace, 433 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Langchain4j Vector Stores Configuration?

giuseppe-trisciuoglio (a GitHub user) maintains it in giuseppe-trisciuoglio/developer-kit, which has 357 GitHub stars. The repository holds 115 skills in this directory. The repository was last updated on September 10, 2026.

Source: giuseppe-trisciuoglio/developer-kit on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.