> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Mine Coding Rules From Team Chat

> Turn overlapping team conversations about code standards into deduplicated Rule nodes a coding agent can query before it writes code

Your team's coding standards live in chat: a principal engineer listing formatting expectations, a manager repeating that Susan reviews every merge before it lands. A coding agent needs those standards as a clean, queryable list of rules — not as two overlapping conversations it has to read again every time.

## What You'll Build

Two short chat transcripts about the team's coding standards go into memory as an ordinary graph. A second pass — a `memify()` pipeline you assemble yourself from two tasks — walks that graph's document chunks, asks an LLM which coding rules each chunk states, and writes them back as `Rule` nodes grouped under the `coding_agent_rules` node set. The enrichment task reads the rules already in that node set before extracting more, so the standards both chats mention — Susan's review, no Friday releases — land as single rules rather than duplicates. What you get out is a flat list of team rules returned by one `SearchType.CODING_RULES` recall, plus two HTML graph visualizations that show what the enrichment pass added.

The complete runnable script is
[`examples/demos/custom_pipelines/memify_coding_agent_rule_extraction_example.py`](https://github.com/topoteretes/cognee/blob/main/examples/demos/custom_pipelines/memify_coding_agent_rule_extraction_example.py) —
this page walks through its key moments rather than reproducing it.

## Features in Play

* [Remember](/core-concepts/main-operations/remember) — stores the two chat transcripts as the base graph the enrichment pass runs over
* [Memify](/core-concepts/main-operations/legacy-operations/memify) — runs the custom extraction → enrichment pipeline against that existing graph instead of ingesting anything new
* [Custom Tasks and Pipelines](/guides/custom-tasks-pipelines) — the two `Task` objects, and the `batch_size` config that decides how many chunks reach the enrichment task at once
* [NodeSets](/core-concepts/further-concepts/node-sets) — `coding_agent_rules` is both where the new `Rule` nodes are filed and where the deduplication check looks
* [Recall](/core-concepts/main-operations/recall) — pinned to [`SearchType.CODING_RULES`](/core-concepts/main-operations/legacy-operations/search) and scoped to that node set, so it returns the rules themselves rather than a generated answer
* [Graph Visualization](/guides/graph-visualization) — the before and after HTML renders that make the added rule layer visible

## What to Expect

The excerpts below come from one real run, trimmed of most log lines. Both the graph build and the rule extraction are live LLM calls, so the rule wording and the node and edge counts vary from run to run; the shape of the output does not.

**The reset and the remember call produce the "before" graph.** `Data reset complete.` follows the `forget(everything=True)` wipe, and `Text remembered successfully.` follows two add-and-cognify pipeline runs, one per chat. The `Retrieved 31 nodes` line is the visualization reading that base graph: documents, chunks, and entities, and no `Rule` node yet.

```text theme={null}
Resetting cognee data...
...
Data reset complete.
...
Text remembered successfully.
...
2026-09-10T11:19:07.910648 [info     ] Retrieved 31 nodes and 49 edges in 0.00 seconds [cognee.shared.logging_utils]
...
Open file to see graph visualization after remember: ...
```

**The memify pass runs the enrichment task once per chunk.** `Retrieving full graph.` is what a `memify()` call with no `data` argument does first, and the projection is the same 31-node graph. `add_rule_associations` then starts and completes twice, because `batch_size: 1` hands it one chunk at a time; the second call only starts after the first has written its rules, which is why it can see them. The warnings between those lines (elided here) name two new `Rule` nodes after the first call and five after the second: seven rules in total, so the two standards both chats state were written once.

```text theme={null}
2026-09-10T11:19:09.775850 [info     ] Retrieving full graph.         [CogneeGraph]
2026-09-10T11:19:09.778634 [info     ] Graph projection completed: 31 nodes, 49 edges in 0.00s [CogneeGraph]
2026-09-10T11:19:09.795031 [info     ] Pipeline run started: `7371376c-3c8d-565f-86c7-ad38d09a525b` [run_tasks_with_telemetry()]
2026-09-10T11:19:09.801307 [info     ] Async Generator task started: `extract_subgraph_chunks` [run_tasks_base]
2026-09-10T11:19:09.807345 [info     ] Coroutine task started: `add_rule_associations` [run_tasks_base]
...
2026-09-10T11:19:22.335390 [info     ] Coroutine task completed: `add_rule_associations` [run_tasks_base]
2026-09-10T11:19:22.348521 [info     ] Coroutine task started: `add_rule_associations` [run_tasks_base]
...
2026-09-10T11:19:44.787578 [info     ] Coroutine task completed: `add_rule_associations` [run_tasks_base]
2026-09-10T11:19:44.800784 [info     ] Async Generator task completed: `extract_subgraph_chunks` [run_tasks_base]
2026-09-10T11:19:44.810365 [info     ] Pipeline run completed: `7371376c-3c8d-565f-86c7-ad38d09a525b` [run_tasks_with_telemetry()]
```

**The recall returns the rules themselves, one bullet each.** The router line shows that the words "coding rules" in the query would have selected `CODING_RULES` anyway; the script pins it so the result never depends on that. Seven rules come back for the six standards the principal engineer listed: the LLM split "Typing and Docstrings" into two rules, and Susan's review and the Friday freeze each appear once even though both chats state them. Note how far the wording drifts from the chat: the extraction prompt turns each standard into a fuller policy, naming tools the team never mentioned and generalizing Susan into "a qualified reviewer". Treat the rule text as a draft to edit, not a transcript.

```text theme={null}
2026-09-10T11:19:44.839687 [info     ] query_router: routed=CODING_RULES score=5.0 query='List me the coding rules' scores={'CODING_RULES': 5.0} [query_router]
...
2026-09-10T11:19:53.940534 [info     ] recall: 7 results across sources=['graph'] (session=-) [recall]
Coding rules created by memify:
- Avoid scheduling production releases or deployments on Fridays or immediately before weekends and major holidays. ...
- Annotate complex or non-obvious code segments with an explicit NOTE: comment that explains why the code is complex, the intended behavior, and references to design documents or tests. ...
- Enforce PEP8-style formatting automatically: include a canonical formatter (e.g., black) and linters (e.g., flake8) in the repository, enable them via pre-commit hooks, and fail CI if code is not formatted/linted. ...
- Require type annotations for functions, methods, and public APIs, and run a static type checker (e.g., mypy or pyright) in CI. ...
- Avoid duplicate code: refactor duplicated logic into a single, well-tested helper function or module. ...
- Require docstrings for all public modules, classes, and functions following a documented style (Google, NumPy, or project standard). ...
- Require at least one approved code review by a qualified reviewer (someone other than the author) before merging changes into the main branch. ...
```

**The "after" graph is exactly the rule layer bigger.** The second visualization reads 39 nodes and 63 edges against the 31 and 49 before: the eight new nodes are the seven `Rule` nodes plus the `coding_agent_rules` `NodeSet` node, and the fourteen new edges are one `rule_associated_from` edge back to the source chunk and one `belongs_to_set` edge into the node set per rule. Open both HTML files to see that layer.

```text theme={null}
2026-09-10T11:19:53.969445 [info     ] Retrieved 39 nodes and 63 edges in 0.00 seconds [cognee.shared.logging_utils]
...
Open file to see graph visualization after memify enhancment: ...
```

## Before You Start

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured — both the initial graph build and the rule extraction call the LLM
* Run it from a checkout of the cognee repo: the script writes its two visualizations into an `.artifacts/` folder next to the script file
* The run opens with `cognee.forget(everything=True)`, which wipes all data and system state — point it at a scratch instance rather than memory you want to keep

## How It Works

### Stage 1: Write Down the Team's Rule Chatter

```python theme={null}
    coding_rules_chat_from_principal_engineer = """
    We want code to be formatted by PEP8 standards.
    Typing and Docstrings must be added.
    Please also make sure to write NOTE: on all more complex code segments.
    If there is any duplicate code, try to handle it in one function to avoid code duplication.
    Susan should also always review new code changes before merging to main.
    New releases should not happen on Friday so we don't have to fix them during the weekend.
    """
```

The demo's input is two plain strings standing in for messages a team actually sends. The second one, `coding_rules_chat_from_manager`, restates the last two rules above almost word for word — that overlap is deliberate, and collapsing it is the job the enrichment pass has to do.

### Stage 2: Remember the Chats and Snapshot the Graph

```python theme={null}
    await cognee.remember(
        [coding_rules_chat_from_principal_engineer, coding_rules_chat_from_manager],
        self_improvement=False,
    )
    print("Text remembered successfully.\n")

    # Visualize graph after remembering
    file_path = os.path.join(
        pathlib.Path(__file__).parent, ".artifacts", "graph_visualization_after_remember.html"
    )
    await visualize_graph(file_path)
    print(f"Open file to see graph visualization after remember: {file_path}\n")
```

`remember()` builds the ordinary graph — documents, chunks, entities — with `self_improvement=False`, because this demo drives its own enrichment rather than the default one. The visualization written here is the "before" half of the comparison: chunks and entities, and not a single `Rule` node yet.

### Stage 3: Assemble the memify Task Pair

```python theme={null}
    # extract_subgraph_chunks is a function that returns all document chunks from specified subgraphs (if no subgraph is specifed the whole graph will be sent through memify)
    subgraph_extraction_tasks = [Task(extract_subgraph_chunks)]

    # add_rule_associations is a function that handles processing coding rules from chunks and keeps track of
    # existing rules so duplicate rules won't be created. As the result of this processing new Rule nodes will be created
    # in the graph that specify coding rules found in conversations.
    coding_rules_association_tasks = [
        Task(
            add_rule_associations,
            rules_nodeset_name="coding_agent_rules",
            task_config={"batch_size": 1},
        ),
    ]
```

Every memify pipeline is an extraction stage feeding an enrichment stage. Extraction here yields the text of every `DocumentChunk` in the graph; enrichment sends each chunk to the LLM together with the rules already filed under `coding_agent_rules`, and writes back only what is new. `batch_size: 1` is what makes that deduplication work chunk by chunk: one chunk per call, so the rules the first chat produced are already in the node set when the manager's chat is processed.

### Stage 4: Run memify Over the Existing Graph

```python theme={null}
    # Memify accepts these tasks and orchestrates forwarding of graph data through these tasks (if data is not specified).
    # If data is explicitely specified in the arguments this specified data will be forwarded through the tasks instead
    await memify(
        extraction_tasks=subgraph_extraction_tasks,
        enrichment_tasks=coding_rules_association_tasks,
    )
```

With no `data` argument, `memify()` loads the graph itself and pushes it through the pair. Each new `Rule` node is filed in the `coding_agent_rules` node set and linked back to the chunk it came from by a `rule_associated_from` edge, so a rule is always traceable to the conversation that stated it.

### Stage 5: Read the Rules Back

```python theme={null}
    # Find the new specific coding rules added to graph through memify (created based on chat conversation between team members)
    coding_rules = await cognee.recall(
        query_text="List me the coding rules",
        query_type=cognee.SearchType.CODING_RULES,
        node_name=["coding_agent_rules"],
    )

    print("Coding rules created by memify:")
    for result in coding_rules:
        print("- " + result.text)
```

Pinning `query_type` to `SearchType.CODING_RULES` takes the choice away from the router and skips the completion step entirely: the retriever reads the `coding_agent_rules` node set directly and hands back the rule texts, which is what an agent wants before it edits a file. The script then writes a second visualization, `graph_visualization_after_memify.html`, so the rule layer can be compared against the "before" render from Stage 2.

## Run It

```bash theme={null}
uv run python examples/demos/custom_pipelines/memify_coding_agent_rule_extraction_example.py
```

<Columns cols={2}>
  <Card title="Memify" icon="sparkles" href="/core-concepts/main-operations/legacy-operations/memify">
    The extraction and enrichment stages behind this pipeline, and the other built-in pairs.
  </Card>

  <Card title="Custom Tasks and Pipelines" icon="workflow" href="/guides/custom-tasks-pipelines">
    Writing your own `Task` functions and wiring them into a pipeline.
  </Card>

  <Card title="NodeSets" icon="tags" href="/core-concepts/further-concepts/node-sets">
    How node sets group the rules and scope the query that reads them back.
  </Card>

  <Card title="Search" icon="search" href="/core-concepts/main-operations/legacy-operations/search">
    What `SearchType.CODING_RULES` returns and the other search types alongside it.
  </Card>
</Columns>
