Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add skills/postindustria-tech/agentic-toolkit/langgraph-dev-corrective-ragnpx skills add postindustria-tech/agentic-toolkit --skill langgraph-dev-corrective-raggit clone --depth 1 https://github.com/postindustria-tech/agentic-toolkitWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00058 | $0.01832 |
| Opus 5 | $0.00029 | $0.00916 |
| Sonnet 5 | $0.00012 | $0.00366 |
| Haiku 4.5 | $0.00006 | $0.00183 |
Grade A, and why
corrective-rag-crag scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 252 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Corrective RAG (CRAG)
CRAG improves RAG by grading document relevance and using web search fallback when local retrieval is insufficient.
CRAG Flow
Question --> Retrieve --> Grade Documents -->
--> If Relevant: Generate
--> If Not Relevant: Transform Query --> Web Search --> Generate
Implementation Pattern
from typing import Any
from typing_extensions import TypedDict
from pydantic import BaseModel, Field
from langchain_anthropic import ChatAnthropic
from langchain_tavily import TavilySearch
from langchain_core.prompts import ChatPromptTemplate
from langgraph.graph import StateGraph, START, END
# Initialize LLM and tools
# Note: Uses Claude Sonnet 4.5; alternative: use ChatOpenAI for OpenAI models
llm = ChatAnthropic(model="claude-sonnet-4-5-20250929", temperature=0)
web_search_tool = TavilySearch(max_results=3)
class GraphState(TypedDict):
"""
Represents the state of our graph.
Attributes:
question: user question
generation: LLM generation
web_search: whether to add search ("Yes" or "No")
documents: list of document contents as strings
"""
question: str
generation: str
web_search: str
documents: list[str]
class GradeDocuments(BaseModel):
"""Binary score for relevance check on retrieved documents."""
binary_score: str = Field(
description="Documents are relevant to the question, 'yes' or 'no'"
)
# Create structured output grader
structured_llm_grader = llm.with_structured_output(GradeDocuments)
# System prompt for grading
system = """You are a grader assessing relevance of a retrieved document to a user question.
If the document contains keyword(s) or semantic meaning related to the question, grade it as relevant.
Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question."""
grade_prompt = ChatPromptTemplate.from_messages([
("system", system),
("human", "Retrieved document: \n\n {document} \n\n User question: {question}"),
])
retrieval_grader = grade_prompt | structured_llm_grader
def retrieve(state: GraphState) -> dict[str, Any]:
"""
Retrieve documents from vectorstore.
"""
question = state["question"]
# Replace with your retriever
# documents = retriever.invoke(question)
documents = [] # Placeholder
return {"documents": documents, "question": question}
def grade_documents(state: GraphState) -> dict[str, Any]:
"""
Determines whether the retrieved documents are relevant to the question.
If any document is not relevant or no documents retrieved, triggers web search.
"""
question = state["question"]
documents = state["documents"]
# Handle empty retrieval - trigger web search
if not documents:
return {"documents": [], "web_search": "Yes"}
# Grade each document
filtered_docs = []
web_search = "No"
for doc in documents:
try:
score = retrieval_grader.invoke({"question": question, "document": doc})
if score.binary_score == "yes":
filtered_docs.append(doc)
else:
web_search = "Yes"
except Exception:
# On grading failure, trigger web search as fallback
web_search = "Yes"
# If all documents filtered out, also trigger web search
if not filtered_docs:
web_search = "Yes"
return {"documents": filtered_docs, "web_search": web_search}
def generate(state: GraphState) -> dict[str, Any]:
"""
Generate answer using RAG on retrieved documents.
"""
question = state["question"]
documents = state["documents"]
# Replace with your RAG chain
# generation = rag_chain.invoke({"context": documents, "question": question})
generation = "" # Placeholder
return {"generation": generation}
def transform_query(state: GraphState) -> dict[str, Any]:
"""
Transform the query to produce a better question for web search.
"""
question = state["question"]
better_question = llm.invoke(
f"Look at the input and try to reason about the underlying semantic intent / meaning. "
f"Here is the initial question: {question}"
)
return {"question": better_question.content}
def web_search(state: GraphState) -> dict[str, Any]:
"""
Web search based on the re-phrased question using Tavily.
"""
question = state["question"]
docs = state["documents"]
# Web search using Tavily
try:
web_results = web_search_tool.invoke({"query": question})
# Defensive access: verify response is dict and extract results safely
if isinstance(web_results, dict):
results_list = web_results.get("results", [])
if isinstance(results_list, list):
web_content = "\n".join([
d.get("content", "") for d in results_list
if isinstance(d, dict)
])
else:
web_content = ""
else:
web_content = ""
except Exception:
web_content = ""
if web_content:
docs = docs + [web_content]
return {"documents": docs}
def decide_to_generate(state: GraphState) -> str:
"""
Determines whether to generate an answer, or re-generate a question.
"""
if state["web_search"] == "Yes":
return "transform_query"
return "generate"
# Build graph
workflow = StateGraph(GraphState)
# Define the nodes
workflow.add_node("retrieve", retrieve)
workflow.add_node("grade_documents", grade_documents)
workflow.add_node("generate", generate)
workflow.add_node("transform_query", transform_query)
workflow.add_node("web_search_node", web_search)
# Build graph edges
workflow.add_edge(START, "retrieve")
workflow.add_edge("retrieve", "grade_documents")
workflow.add_conditional_edges(
"grade_documents",
decide_to_generate,
{
"transform_query": "transform_query",
"generate": "generate",
},
)
workflow.add_edge("transform_query", "web_search_node")
workflow.add_edge("web_search_node", "generate")
workflow.add_edge("generate", END)
# Compile
app = workflow.compile()
# Example usage
initial_state = {
"question": "What is the capital of France?",
"generation": "",
"web_search": "No",
"documents": []
}
result = app.invoke(initial_state)
print(result["generation"])
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 252 lines · 58 tokens per session scan A e6c626f72c69
corrective-rag-crag is a skill published in the GitHub repository postindustria-tech/agentic-toolkit (2 stars, last pushed 1mo ago), licensed MIT. It adds 58 tokens to every session and 1,832 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
agent-platform-rag-engine-management
Manage and query Agent Platform RAG Engine Corpora and retrieve grounded contexts using the Google GenAI SDK. Use when listing RAG corpora or files, inspecting a corpus, retrieving contexts, or generating content grounded in a RAG corpus. Do not use for standard database queries (use SQL/Spanner skills), Google…
9router-embeddings
Generate vector embeddings via 9Router /v1/embeddings using OpenAI / Gemini / Mistral / Voyage / Nvidia / GitHub embedding models for RAG, semantic search, similarity. Use when the user wants embeddings, vectors, RAG, semantic search, or to embed text.
potpie-source-ingestion
Use when the user explicitly asks to ingest, refresh, or deeply understand a repository, PR, issue, ticket, runbook, incident report, document, or web link into Potpie. The harness performs todo-driven discovery, uses local/GitHub/integration tools and read-only subagents when available, builds evidence-backed…
embedding-strategies
Select and optimize embedding models for semantic search and RAG applications. Use when choosing embedding models, implementing chunking strategies, or optimizing embedding quality for specific domains.
generate-rag-dataset
Generate a synthetic evaluation dataset from your RAG knowledge base. Creates diverse Q&A pairs with expected answers and relevant context, ready for LangWatch experiments and platform import. Use when you need test data for your RAG pipeline.
embeddings
Vector embeddings configuration and semantic search.