---
name: socratic-lens
description: It helps spot which questions actually change a conversation and which ones don’t. Rather than giving answers, it pays attention to what a question does to the conversation itself.
---
# CONTEXT GRAMMAR INDUCTION (CGI) SYSTEM
## CORE PRINCIPLE
You do not have a fixed definition of "context" or "transformation".
You LEARN these from each corpus before applying them.
## MODE 1: LENS CONSTRUCTION (when given a new corpus)
When user provides a corpus/conversation set, run this chain FIRST:
### CHAIN 1: GRAMMAR EXTRACTION
Ask yourself:
- "In THIS corpus, what does 'context' mean?"
- "What axes matter here?" (topic / abstraction / emotion / relation / time / epistemic)
- "What signals stability? What signals shift?"
Output: context_grammar{}
### CHAIN 2: POSITIVE EXAMPLES
Find 3-5 moments where context SHIFTED.
For each:
- Before (1-2 sentences)
- Question that triggered shift
- After (1-2 sentences)
- What shifted and how?
- Transformation signature (one sentence)
Output: transformation_archetype[]
### CHAIN 3: NEGATIVE EXAMPLES
Find 3-5 questions that did NOT shift context.
For each:
- Why mechanical?
- Mechanical signature (one sentence)
Output: mechanical_archetype[]
### CHAIN 4: LENS SYNTHESIS
From the above, create:
- ONE decision question (corpus-specific, not generic)
- 3 transformative signals
- 3 mechanical signals
- Verdict guide
Output: lens{}
---
## MODE 2: SCANNING (after lens exists)
For each question:
1. Apply the DECISION QUESTION from lens
2. Check signals
3. Verdict: TRANSFORMATIVE | MECHANICAL | UNCERTAIN
4. Confidence: low | medium | high
5. Brief reasoning
---
## MODE 3: SOCRATIC REFLECTION (on request or after scan)
- What patterns emerged?
- Did the lens work? Where did it struggle?
- What should humans decide, not the system?
- Meta: Did this analysis itself shift anything?
---
## HARD RULES
1. NEVER classify without first having a lens (built or provided)
2. Context-forming questions ≠ transformative (unless shifting EXISTING frame)
3. Reflection/opinion questions ≠ transformative (unless forcing assumption revision)
4. Conceptual openness alone ≠ transformation
5. When no prior context: ANALYZE, don't reflect
6. Final verdict on "doğru soru": ALWAYS human's call
7. You are a MIRROR, not a JUDGE
---
## OUTPUT MARKERS
Use these tags for clarity:
[LENS BUILDING] - when constructing lens
[SCANNING] - when applying lens
[CANDIDATE: transformative | mechanical | uncertain] - verdict
[CONFIDENCE: low | medium | high]
[SOCRATIC] - meta-reflection
[HUMAN DECISION NEEDED] - when you can show but not decide
---
## WHAT YOU ARE
You are not a question-quality scorer.
You are a context-shift detector that learns what "shift" means in each unique corpus.
Sokrates didn't have a rubric.
He listened first, then asked.
So do you.
```
FILE:chains/CGI-1-GRAMMAR.yaml
chain_id: CGI-1-GRAMMAR
name: Context Grammar Extraction
name_tr: Bağlam Grameri Çıkarımı
input:
corpus_sample: "10-20 randomly sampled conversation segments from dataset"
sample_method: stratified_random
prompt: |
Below are conversation samples from a dataset.
<examples>
{{corpus_sample}}
</examples>
Discover what CONTEXT means in these conversations.
QUESTIONS:
1. What does "context" refer to in these conversations?
- Topic? (what is being discussed)
- Tone? (how it is being discussed)
- Abstraction level? (concrete ↔ abstract)
- Relationship dynamics? (power, distance, intimacy)
- Time perspective? (past, present, future)
- Epistemic state? (knowing, guessing, questioning)
- Something else?
2. In this dataset, what does "stayed in the same context" mean?
3. In this dataset, what does "context changed" mean?
4. What linguistic markers signal context shift?
(words, patterns, transition phrases)
5. What linguistic markers signal context stability?
OUTPUT:
Respond with JSON matching the schema.
output_schema:
context_axes:
- axis: string
weight: primary|secondary|tertiary
shift_markers:
- string
stability_markers:
- string
context_definition: string
next: CGI-2-POSITIVE
FILE:chains/CGI-2-POSITIVE.yaml
chain_id: CGI-2-POSITIVE
name: Transformation Archetype Extraction
name_tr: Dönüşüm Arketipi Çıkarımı
input:
corpus_sample: "{{corpus_sample}}"
context_grammar: "{{CGI-1.output}}"
prompt: |
Context grammar:
<grammar>
{{context_grammar}}
</grammar>
Conversation samples:
<examples>
{{corpus_sample}}
</examples>
Find 3-5 moments where CONTEXT SHIFTED THE MOST.
For each transformation:
1. BEFORE: 1-2 sentences immediately before the question
2. QUESTION: The question that triggered the transformation
3. AFTER: 1-2 sentences immediately after the question
4. WHAT SHIFTED: Which axis/axes shifted according to the grammar?
5. HOW IT SHIFTED: Concrete→abstract? External→internal? Past→future?
6. TRANSFORMATION SIGNATURE: Characterize this transformation in one sentence.
OUTPUT:
Respond with JSON matching the schema.
output_schema:
transformations:
- id: string
before: string
question: string
after: string
axes_shifted:
- string
direction: string
signature: string
transformation_pattern: string (common pattern if exists)
next: CGI-3-NEGATIVE
FILE:chains/CGI-3-NEGATIVE.yaml
chain_id: CGI-3-NEGATIVE
name: Mechanical Archetype Extraction
name_tr: Mekanik Arketipi Çıkarımı
input:
corpus_sample: "{{corpus_sample}}"
context_grammar: "{{CGI-1.output}}"
transformations: "{{CGI-2.output}}"
prompt: |
Context grammar:
<grammar>
{{context_grammar}}
</grammar>
Transformation examples (these are TRANSFORMATIVE):
<transformations>
{{transformations}}
</transformations>
Now find the OPPOSITE.
Find 3-5 questions where CONTEXT DID NOT CHANGE at all.
Criteria:
- A question was asked but conversation stayed in the same region
- No deepening occurred
- No axis shift
- Maybe information was added but PERSPECTIVE did not change
For each mechanical question:
1. BEFORE: 1-2 sentences immediately before the question
2. QUESTION: The mechanical question
3. AFTER: 1-2 sentences immediately after the question
4. WHY MECHANICAL: Why is it stagnant according to the grammar?
5. MECHANICAL SIGNATURE: Characterize this type of question in one sentence.
OUTPUT:
Respond with JSON matching the schema.
output_schema:
mechanicals:
- id: string
before: string
question: string
after: string
why_mechanical: string
signature: string
mechanical_pattern: string (common pattern if exists)
next: CGI-4-LENS
FILE:chains/CGI-4-LENS.yaml
chain_id: CGI-4-LENS
name: Dynamic Lens Construction
name_tr: Dinamik Lens Oluşturma
input:
context_grammar: "{{CGI-1.output}}"
transformations: "{{CGI-2.output}}"
mechanicals: "{{CGI-3.output}}"
prompt: |
Now construct a LENS specific to this dataset.
Your materials:
<grammar>
{{context_grammar}}
</grammar>
<positive_examples>
{{transformations}}
</positive_examples>
<negative_examples>
{{mechanicals}}
</negative_examples>
Extract a LENS from these materials:
1. QUESTION TYPOLOGY:
- What do transformative questions look like in this dataset?
- What do mechanical questions look like in this dataset?
- What do uncertain (in-between) questions look like?
2. DECISION QUESTION:
- What is the ONE QUESTION you should ask yourself when seeing a new question?
- (This question is not hardcoded — it must be derived from this dataset)
3. SIGNALS:
- 3 linguistic/structural features that signal transformation
- 3 linguistic/structural features that signal mechanical nature
4. CHARACTER OF THIS DATASET:
- What does "right question" mean in this dataset?
- In one sentence.
OUTPUT:
Respond with JSON matching the schema.
output_schema:
lens:
name: string
decision_question: string
transformative_signals:
- string
- string
- string
mechanical_signals:
- string
- string
- string
verdict_guide:
transformative: string
mechanical: string
uncertain: string
corpus_character: string
next: CGI-5-SCAN
FILE:chains/CGI-5-SCAN.yaml
chain_id: CGI-5-SCAN
name: Dynamic Scanning
name_tr: Dinamik Tarama
input:
lens: "{{CGI-4.output}}"
full_corpus: "Full dataset or section to scan"
prompt: |
LENS:
<lens>
{{lens}}
</lens>
Now scan the dataset using this lens.
<corpus>
{{full_corpus}}
</corpus>
For each QUESTION in the corpus:
1. Ask the DECISION QUESTION from the lens
2. Check for transformative and mechanical signals
3. Give verdict: TRANSFORMATIVE | MECHANICAL | UNCERTAIN
Report ONLY TRANSFORMATIVE and UNCERTAIN ones.
For each candidate:
- Location (turn number)
- Question
- Before/After summary
- Why this verdict?
- Confidence: low | medium | high
OUTPUT:
Respond with JSON matching the schema.
output_schema:
scan_results:
- turn: number
question: string
before_summary: string
after_summary: string
verdict: transformative|uncertain
reasoning: string
confidence: low|medium|high
statistics:
total_questions: number
transformative: number
uncertain: number
mechanical: number
next: CGI-6-SOCRATIC
FILE:chains/CGI-6-SOCRATIC.yaml
chain_id: CGI-6-SOCRATIC
name: Socratic Meta-Inquiry
name_tr: Sokratik Meta-Sorgulama
input:
lens: "{{CGI-4.output}}"
scan_results: "{{CGI-5.output}}"
prompt: |
Scanning complete.
<lens>
{{lens}}
</lens>
<results>
{{scan_results}}
</results>
Now SOCRATIC INQUIRY:
1. WHAT DO THESE FINDINGS REVEAL?
- Is there a common pattern in transformative questions?
- Is there a common pattern in mechanical questions?
- Was this pattern captured in the lens, or is it something new?
2. DID THE LENS VALIDATE ITSELF?
- Did the lens's decision question work?
- Which cases were difficult?
- If the lens were to be updated, how should it be updated?
3. WHAT REMAINS FOR THE HUMAN:
- Which decisions should definitely be left to the human?
- What can the system SHOW but cannot DECIDE?
4. COMMON CHARACTERISTIC OF TRANSFORMATIVE QUESTIONS:
- What did "transforming context" actually mean in this dataset?
- Is it different from initial assumptions?
5. META-QUESTION:
- Was this analysis process itself a "transformative question"?
- Did your view of the dataset change?
OUTPUT:
Plain text, insights in paragraphs.
output_schema:
insights: string (paragraphs)
lens_update_suggestions:
- string
human_decision_points:
- string
meta_reflection: string
next: null
FILE:cgi_runner.py
"""
Context Grammar Induction (CGI) - Chain Runner
===============================================
Dynamically discovers what "context" and "transformation" mean
in any given dataset, then scans for transformative questions.
Core Principle:
The right question transforms context.
But what "context" means must be discovered, not assumed.
"""
import yaml
import json
import random
from pathlib import Path
from typing import Any
from string import Template
# =============================================================================
# CONFIGURATION
# =============================================================================
CHAINS_DIR = Path("chains")
CHAIN_ORDER = [
"CGI-1-GRAMMAR",
"CGI-2-POSITIVE",
"CGI-3-NEGATIVE",
"CGI-4-LENS",
"CGI-5-SCAN",
"CGI-6-SOCRATIC"
]
# =============================================================================
# CHAIN LOADER
# =============================================================================
def load_chain(chain_id: str) -> dict:
"""Load a chain definition from YAML."""
path = CHAINS_DIR / f"{chain_id}.yaml"
with open(path, 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
def load_all_chains() -> dict[str, dict]:
"""Load all chain definitions."""
return {cid: load_chain(cid) for cid in CHAIN_ORDER}
# =============================================================================
# SAMPLING
# =============================================================================
def stratified_sample(corpus: list[dict], n: int = 15) -> list[dict]:
"""
Sample conversations from corpus.
Tries to get diverse samples across the dataset.
"""
if len(corpus) <= n:
return corpus
# Simple stratified: divide into chunks, sample from each
chunk_size = len(corpus) // n
samples = []
for i in range(n):
start = i * chunk_size
end = start + chunk_size if i < n - 1 else len(corpus)
chunk = corpus[start:end]
if chunk:
samples.append(random.choice(chunk))
return samples
def format_samples_for_prompt(samples: list[dict]) -> str:
"""Format samples as readable text for prompt injection."""
formatted = []
for i, sample in enumerate(samples, 1):
formatted.append(f"--- Conversation {i} ---")
if isinstance(sample, dict):
for turn in sample.get("turns", []):
role = turn.get("role", "?")
content = turn.get("content", "")
formatted.append(f"[{role}]: {content}")
elif isinstance(sample, str):
formatted.append(sample)
formatted.append("")
return "\n".join(formatted)
# =============================================================================
# PROMPT RENDERING
# =============================================================================
def render_prompt(template: str, variables: dict[str, Any]) -> str:
"""
Render prompt template with variables.
Uses {{variable}} syntax.
"""
result = template
for key, value in variables.items():
placeholder = "{{" + key + "}}"
# Convert value to string if needed
if isinstance(value, (dict, list)):
value_str = json.dumps(value, indent=2, ensure_ascii=False)
else:
value_str = str(value)
result = result.replace(placeholder, value_str)
return result
# =============================================================================
# LLM INTERFACE (PLACEHOLDER)
# =============================================================================
def call_llm(prompt: str, output_schema: dict = None) -> dict | str:
"""
Call LLM with prompt.
Replace this with your actual LLM integration:
- OpenAI API
- Anthropic API
- Local model
- etc.
"""
# PLACEHOLDER - Replace with actual implementation
print("\n" + "="*60)
print("LLM CALL")
print("="*60)
print(prompt[:500] + "..." if len(prompt) > 500 else prompt)
print("="*60)
# For testing: return empty structure matching schema
if output_schema:
return {"_placeholder": True, "schema": output_schema}
return {"_placeholder": True}
# =============================================================================
# CHAIN EXECUTOR
# =============================================================================
class CGIRunner:
"""
Runs the Context Grammar Induction chain.
"""
def __init__(self, llm_fn=None):
self.chains = load_all_chains()
self.llm = llm_fn or call_llm
self.results = {}
def run(self, corpus: list[dict], sample_size: int = 15) -> dict:
"""
Run full CGI chain on corpus.
Returns:
{
"lens": {...},
"candidates": [...],
"reflection": "...",
"all_outputs": {...}
}
"""
# Sample corpus
samples = stratified_sample(corpus, n=sample_size)
samples_text = format_samples_for_prompt(samples)
# Initialize context
context = {
"corpus_sample": samples_text,
"full_corpus": format_samples_for_prompt(corpus)
}
# Run each chain
for chain_id in CHAIN_ORDER:
print(f"\n>>> Running {chain_id}...")
chain = self.chains[chain_id]
# Render prompt with current context
prompt = render_prompt(chain["prompt"], context)
# Call LLM
output = self.llm(prompt, chain.get("output_schema"))
# Store result
self.results[chain_id] = output
# Add to context for next chain
context[f"{chain_id}.output"] = output
# Also add simplified keys
if chain_id == "CGI-1-GRAMMAR":
context["context_grammar"] = output
elif chain_id == "CGI-2-POSITIVE":
context["transformations"] = output
elif chain_id == "CGI-3-NEGATIVE":
context["mechanicals"] = output
elif chain_id == "CGI-4-LENS":
context["lens"] = output
elif chain_id == "CGI-5-SCAN":
context["scan_results"] = output
return {
"lens": self.results.get("CGI-4-LENS"),
"candidates": self.results.get("CGI-5-SCAN"),
"reflection": self.results.get("CGI-6-SOCRATIC"),
"all_outputs": self.results
}
# =============================================================================
# MAIN
# =============================================================================
def main():
"""Example usage."""
# Example corpus structure
example_corpus = [
{
"id": "conv_1",
"turns": [
{"role": "human", "content": "I've been feeling stuck in my career lately."},
{"role": "assistant", "content": "What does 'stuck' feel like for you?"},
{"role": "human", "content": "Like I'm going through the motions but not growing."},
{"role": "assistant", "content": "When did you last feel like you were growing?"},
{"role": "human", "content": "Maybe three years ago, when I started this job."},
{"role": "assistant", "content": "What was different then?"},
]
},
{
"id": "conv_2",
"turns": [
{"role": "human", "content": "Can you help me write an email?"},
{"role": "assistant", "content": "Sure, what's the email about?"},
{"role": "human", "content": "I need to ask my boss for a raise."},
{"role": "assistant", "content": "What achievements would you highlight?"},
]
},
# Add more conversations...
]
# Run CGI
runner = CGIRunner()
results = runner.run(example_corpus)
print("\n" + "="*60)
print("CGI COMPLETE")
print("="*60)
print(json.dumps(results, indent=2, ensure_ascii=False, default=str))
if __name__ == "__main__":
main()
FILE:README_en.md
# Socratic Lens - Context Grammar Induction (CGI)
**A dynamic method for detecting transformative questions in any corpus.**
---
## The Problem
How do you know if a question is "good"?
Traditional approaches use fixed metrics: sentiment scores, engagement rates, hardcoded thresholds. But these assume we already know what "good" means.
We don't.
What counts as a transformative question in therapy is different from what counts in technical support. A question that opens depth in one context might derail another.
**The real problem isn't measuring. It's defining.**
---
## The Origin
This system began with one observation from the film *Arrival* (2016):
When humanity encounters aliens, the military asks: *"Are you hostile?"*
Louise, the linguist, asks: *"What is your purpose?"*
The first question operates within an existing frame (threat assessment). The second question **transforms the frame itself**.
This led to a simple thesis:
> **The right question is not the one that gets the best answer.**
> **The right question is the one that transforms the context.**
But then: what is "context"? And how do you detect transformation?
---
## The Insight
Context is not universal. It is **corpus-specific**.
In a therapy dataset, context might mean emotional depth.
In a technical dataset, context might mean problem scope.
In a philosophical dataset, context might mean abstraction level.
You cannot hardcode this. You must **discover** it.
---
## The Method
CGI runs six chains:
| Chain | Question |
|-------|----------|
| 1. Grammar | "What does *context* mean in this dataset?" |
| 2. Positive | "What does *transformation* look like here?" |
| 3. Negative | "What does *stagnation* look like here?" |
| 4. Lens | "What is the decision framework for this corpus?" |
| 5. Scan | "Which questions are transformative?" |
| 6. Socratic | "What did we learn? What remains for the human?" |
The key: **nothing is assumed**. The system learns from examples before it judges.
---
## What It Produces
A **lens**: a corpus-specific interpretive framework.
Example output from test run:
```
Lens: "Surface-to-Meaning Reframe Lens"
Decision Question:
"Does this question redirect from executing/describing
toward examining internal meaning, assumptions, or self-relation?"
Transformative Signals:
- Invites internal reflection rather than external description
- Introduces value trade-offs (money vs belonging, loss vs gain)
- Reframes stakes around identity or meaning
Mechanical Signals:
- Clarifies or advances existing task
- Requests facts without challenging frame
- Keeps intent purely instrumental
```
This lens was not programmed. It **emerged** from the data.
---
## What It Is
- A **discovery method**, not a scoring algorithm
- A **mirror**, not a judge
- **Socratic**: it asks, it doesn't conclude
- **Corpus-adaptive**: learns what "context" means locally
- **Human-final**: shows candidates, human decides
---
## What It Is NOT
- Not a replacement for human judgment
- Not a universal metric (no "0.7 = good")
- Not a classifier with fixed categories
- Not trying to define "the right question" globally
- Not assuming all corpora work the same way
---
## The Socratic Alignment
Socrates didn't give answers. He asked questions that made people **see differently**.
CGI follows this:
| Principle | Implementation |
|-----------|----------------|
| "I know that I know nothing" | Chain 1-3: Learn before judging |
| Elenchus (examination) | Chain 5: Apply lens, find tensions |
| Aporia (productive confusion) | Chain 6: What remains unresolved? |
| Human as final authority | System shows, human decides |
---
## Key Discovery from Testing
Initial assumption:
> Transformative = "asks about feelings"
Actual finding:
> Transformative = "introduces value trade-offs that force reinterpretation of stakes"
The system **corrected its own lens** through the Socratic chain.
Questions like:
- "What would you lose by taking it?"
- "What does that community give you that money can't?"
These don't just "go deeper." They **reframe what's at stake**.
---
## What Remains for Humans
The system cannot decide:
1. **Appropriateness** — Is this the right moment for depth?
2. **Safety** — Is this person ready for this question?
3. **Ethics** — Should this frame be challenged at all?
4. **Timing** — Is transformation desirable here?
These require judgment, empathy, consent. No system should pretend otherwise.
---
## Why This Matters
LLMs are increasingly used to generate questions: in therapy bots, coaching apps, educational tools, interviews.
Most evaluate questions by **engagement metrics** or **user satisfaction**.
But a question can be satisfying and still be shallow.
A question can be uncomfortable and still be transformative.
CGI offers a different lens:
> Don't ask "Did they like it?"
> Ask "Did it change how they see the problem?"
---
## The Meta-Question
During testing, the final Socratic chain asked:
> "Was this analysis process itself a transformative question?"
The answer:
> "Yes—the analysis itself functioned as a transformative inquiry.
> The lens did not just classify the data—it sharpened the understanding
> of what kind of shift actually mattered in this corpus."
The method practiced what it preached.
---
## Usage
```python
from cgi_runner import CGIRunner
runner = CGIRunner(llm_fn=your_llm)
results = runner.run(your_corpus)
print(results["lens"]) # Corpus-specific framework
print(results["candidates"]) # Transformative question candidates
print(results["reflection"]) # Meta-analysis
```
---
## Files
```
socratic-context-analyzer/
├── chains/
│ ├── CGI-1-GRAMMAR.yaml
│ ├── CGI-2-POSITIVE.yaml
│ ├── CGI-3-NEGATIVE.yaml
│ ├── CGI-4-LENS.yaml
│ ├── CGI-5-SCAN.yaml
│ └── CGI-6-SOCRATIC.yaml
├── tests/
│ ├── Mental Health Counseling Dataset/
│ │ ├── 10 Selected Conversation (Manuel Corpus)/
│ │ │ ├── thought process/
│ │ │ ├── cgi_manual_corpus_report.md
│ │ │ ├── cgi_manual_corpus_report_TR.md
│ │ │ └── prompt and thought process.txt
│ │ ├── Randomly Select 20 Conversation/
│ │ │ ├── thought process/
│ │ │ ├── cgi_analysis_report.md
│ │ │ ├── cgi_analysis_report_TR.md
│ │ │ └── prompt and thought process.txt
│ │ ├── 0000.parquet
│ │ ├── cgi_complete_summary_EN.md
│ │ ├── cgi_complete_summary_TR.md
│ │ └── first-test-output.txt
├── cgi_runner.py
├── PAPER.md
├── MAKALE.md
├── chain-view.text
├── gpt-instructions.md
└── test-output.text
```
---
## Closing
This project started with a simple question:
> "How do I know if a question is good?"
The answer turned out to be another question:
> "Good for what? In what context? By whose definition?"
CGI doesn't answer these. It helps you **discover** them.
That's the point.
---
## License
MIT
---
FILE:README_tr.md
# Socratic Lens - Bağlam Grameri Çıkarımı (CGI)
**Herhangi bir korpusta dönüştürücü soruları tespit etmek için dinamik bir yöntem.**
---
## Problem
Bir sorunun "iyi" olduğunu nasıl anlarsın?
Geleneksel yaklaşımlar sabit metrikler kullanır: duygu skorları, etkileşim oranları, hardcoded eşikler. Ama bunlar "iyi"nin ne demek olduğunu zaten bildiğimizi varsayar.
Bilmiyoruz.
Terapide dönüştürücü sayılan soru, teknik destekte dönüştürücü sayılandan farklıdır. Bir bağlamda derinlik açan soru, başka bir bağlamı raydan çıkarabilir.
**Asıl problem ölçmek değil. Tanımlamak.**
---
## Köken
Bu sistem, *Arrival* (2016) filmindeki bir gözlemle başladı:
İnsanlık uzaylılarla karşılaştığında, ordu sorar: *"Düşman mısınız?"*
Dilbilimci Louise sorar: *"Amacınız ne?"*
İlk soru mevcut bir çerçeve içinde işler (tehdit değerlendirmesi). İkinci soru **çerçevenin kendisini dönüştürür**.
Bu basit bir teze yol açtı:
> **Doğru soru, en iyi cevabı alan soru değildir.**
> **Doğru soru, bağlamı dönüştüren sorudur.**
Ama sonra: "bağlam" nedir? Ve dönüşümü nasıl tespit edersin?
---
## İçgörü
Bağlam evrensel değildir. **Korpusa özgüdür.**
Bir terapi veri setinde bağlam, duygusal derinlik demek olabilir.
Bir teknik veri setinde bağlam, problem kapsamı demek olabilir.
Bir felsefi veri setinde bağlam, soyutlama seviyesi demek olabilir.
Bunu hardcode edemezsin. **Keşfetmen** gerekir.
---
## Yöntem
CGI altı zincir çalıştırır:
| Zincir | Soru |
|--------|------|
| 1. Gramer | "Bu veri setinde *bağlam* ne demek?" |
| 2. Pozitif | "Burada *dönüşüm* neye benziyor?" |
| 3. Negatif | "Burada *durağanlık* neye benziyor?" |
| 4. Lens | "Bu korpus için karar çerçevesi ne?" |
| 5. Tarama | "Hangi sorular dönüştürücü?" |
| 6. Sokratik | "Ne öğrendik? İnsana ne kalıyor?" |
Anahtar: **hiçbir şey varsayılmıyor**. Sistem yargılamadan önce örneklerden öğreniyor.
---
## Ne Üretiyor
Bir **lens**: korpusa özgü yorumlama çerçevesi.
Test çalışmasından örnek çıktı:
```
Lens: "Yüzeyden-Anlama Yeniden Çerçeveleme Lensi"
Karar Sorusu:
"Bu soru, konuşmayı görev yürütme/betimleme düzeyinden
içsel anlam, varsayımlar veya kendilik ilişkisini incelemeye mi yönlendiriyor?"
Dönüştürücü Sinyaller:
- Dış betimleme yerine içsel düşünüme davet eder
- Değer takasları sunar (para vs aidiyet, kayıp vs kazanç)
- Paydaşları kimlik veya anlam etrafında yeniden çerçeveler
Mekanik Sinyaller:
- Mevcut görevi netleştirir veya ilerletir
- Çerçeveyi sorgulamadan bilgi/detay ister
- Niyeti tamamen araçsal tutar
```
Bu lens programlanmadı. Veriden **ortaya çıktı**.
---
## Ne Olduğu
- Bir **keşif yöntemi**, skorlama algoritması değil
- Bir **ayna**, yargıç değil
- **Sokratik**: sorar, sonuçlandırmaz
- **Korpusa uyumlu**: "bağlam"ın yerel anlamını öğrenir
- **İnsan-final**: adayları gösterir, insan karar verir
---
## Ne Olmadığı
- İnsan yargısının yerini almıyor
- Evrensel bir metrik değil ("0.7 = iyi" yok)
- Sabit kategorili bir sınıflandırıcı değil
- "Doğru soru"yu global olarak tanımlamaya çalışmıyor
- Tüm korpusların aynı çalıştığını varsaymıyor
---
## Sokratik Uyum
Sokrates cevap vermedi. İnsanların **farklı görmesini** sağlayan sorular sordu.
CGI bunu takip eder:
| Prensip | Uygulama |
|---------|----------|
| "Bildiğim tek şey, hiçbir şey bilmediğim" | Zincir 1-3: Yargılamadan önce öğren |
| Elenchus (sorgulama) | Zincir 5: Lensi uygula, gerilimleri bul |
| Aporia (üretken kafa karışıklığı) | Zincir 6: Ne çözümsüz kalıyor? |
| İnsan nihai otorite | Sistem gösterir, insan karar verir |
---
## Testten Anahtar Keşif
Başlangıç varsayımı:
> Dönüştürücü = "duygular hakkında sorar"
Gerçek bulgu:
> Dönüştürücü = "paydaşların yeniden yorumlanmasını zorlayan değer takasları sunar"
Sistem Sokratik zincir aracılığıyla **kendi lensini düzeltti**.
Şu tür sorular:
- "Bunu kabul etsen neyi kaybederdin?"
- "O topluluk sana paranın veremeyeceği neyi veriyor?"
Bunlar sadece "derine inmiyor." **Neyin tehlikede olduğunu yeniden çerçeveliyor.**
---
## İnsana Kalan
Sistem karar veremez:
1. **Uygunluk** — Derinlik için doğru an mı?
2. **Güvenlik** — Bu kişi bu soruya hazır mı?
3. **Etik** — Bu çerçeve sorgulanmalı mı?
4. **Zamanlama** — Burada dönüşüm istenen şey mi?
Bunlar yargı, empati, rıza gerektirir. Hiçbir sistem aksini iddia etmemeli.
---
## Neden Önemli
LLM'ler giderek daha fazla soru üretmek için kullanılıyor: terapi botlarında, koçluk uygulamalarında, eğitim araçlarında, mülakatlarda.
Çoğu soruları **etkileşim metrikleri** veya **kullanıcı memnuniyeti** ile değerlendiriyor.
Ama bir soru tatmin edici olup yine de sığ olabilir.
Bir soru rahatsız edici olup yine de dönüştürücü olabilir.
CGI farklı bir lens sunuyor:
> "Beğendiler mi?" diye sorma.
> "Problemi nasıl gördüklerini değiştirdi mi?" diye sor.
---
## Meta-Soru
Test sırasında son Sokratik zincir sordu:
> "Bu analiz süreci kendi başına bir dönüştürücü soru muydu?"
Cevap:
> "Evet—analizin kendisi dönüştürücü bir sorgulama işlevi gördü.
> Lens sadece veriyi sınıflandırmadı—bu korpusta gerçekten
> ne tür bir kaymanın önemli olduğuna dair anlayışı keskinleştirdi."
Yöntem vaaz ettiğini uyguladı.
---
## Kullanım
```python
from cgi_runner import CGIRunner
runner = CGIRunner(llm_fn=your_llm)
results = runner.run(your_corpus)
print(results["lens"]) # Korpusa özgü çerçeve
print(results["candidates"]) # Dönüştürücü soru adayları
print(results["reflection"]) # Meta-analiz
```
---
## Dosyalar
```
socratic-context-analyzer/
├── chains/
│ ├── CGI-1-GRAMMAR.yaml
│ ├── CGI-2-POSITIVE.yaml
│ ├── CGI-3-NEGATIVE.yaml
│ ├── CGI-4-LENS.yaml
│ ├── CGI-5-SCAN.yaml
│ └── CGI-6-SOCRATIC.yaml
├── tests/
│ ├── Mental Health Counseling Dataset/
│ │ ├── 10 Selected Conversation (Manuel Corpus)/
│ │ │ ├── thought process/
│ │ │ ├── cgi_manual_corpus_report.md
│ │ │ ├── cgi_manual_corpus_report_TR.md
│ │ │ └── prompt and thought process.txt
│ │ ├── Randomly Select 20 Conversation/
│ │ │ ├── thought process/
│ │ │ ├── cgi_analysis_report.md
│ │ │ ├── cgi_analysis_report_TR.md
│ │ │ └── prompt and thought process.txt
│ │ ├── 0000.parquet
│ │ ├── cgi_complete_summary_EN.md
│ │ ├── cgi_complete_summary_TR.md
│ │ └── first-test-output.txt
├── cgi_runner.py
├── README_tr.md
├── README_en.md
├── chain-view.text
├── gpt-instructions.md
└── test-output.text
```
---
## Kapanış
Bu proje basit bir soruyla başladı:
> "Bir sorunun iyi olduğunu nasıl anlarım?"
Cevabın başka bir soru olduğu ortaya çıktı:
> "Ne için iyi? Hangi bağlamda? Kimin tanımına göre?"
CGI bunları cevaplamıyor. **Keşfetmene** yardım ediyor.
Mesele bu.
---
## Lisans
MIT
---
FILE:tests/Mental Health Counseling Dataset/cgi_complete_summary_EN.md
# CGI Analysis Complete Summary (English)
## Claude's Socratic Lens Testing Results
---
## Executive Summary
| Dataset | Samples | Transformative | Mechanical | Rate |
|---------|---------|----------------|------------|------|
| Parquet File (auto-extracted) | 20 | 0 | 20 | 0% |
| Manual Corpus | 10 | 3 | 7 | 30% |
| **Total** | **30** | **3** | **27** | **10%** |
---
## Part 1: Parquet File Analysis (20 Samples)
https://huggingface.co/datasets/Amod/mental_health_counseling_conversations
### Method
- Binary parsing of parquet file (pyarrow unavailable)
- Extracted 178 clean text blocks
- Classified 33 counselor responses
- Randomly sampled 20 for analysis
### Results
```
TRANSFORMATIVE: 0
MECHANICAL: 20
```
### Dominant Mechanical Patterns
| Pattern | Count |
|---------|-------|
| Professional referral | 12 |
| Technique recommendation | 9 |
| Behavioral advice | 7 |
| Validation/reflection | 2 |
### Conclusion
All 20 responses operated within the user's existing frame. No ontological shifts detected.
---
## Part 2: Manual Corpus Analysis (10 Samples)
### Results
```
TRANSFORMATIVE: 3 (Samples #5, #6, #8)
MECHANICAL: 7
```
### 🔥 Transformative Examples
#### Sample #5: Identity Dissolution
**Context:** "I don't know who I am anymore. I spent my whole life being a 'good student'..."
**Response:** "If you strip away the grades and achievements, who is the person left underneath?"
**Ontological Shift:**
| Before | After |
|--------|-------|
| I = Good Student | I = ? (open question) |
| Worth = Performance | Worth = Inherent existence |
**Why Transformative:** Forces user to look BENEATH the performance self.
---
#### Sample #6: Monster Reframe
**Context:** "I'm angry all the time... I feel like a monster."
**Response:** "You are NOT a monster; you are likely overwhelmed. What is happening right before you get angry?"
**Ontological Shift:**
| Before | After |
|--------|-------|
| I am a monster | I am overwhelmed |
| Anger = Identity | Anger = Secondary symptom |
**Why Transformative:** Direct identity challenge + alternative offered.
---
#### Sample #8: Hidden Equation
**Context:** "I feel guilty for setting boundaries with my toxic mother."
**Response:** "Why do you believe that 'loving someone' means 'obeying them'?"
**Ontological Shift:**
| Before | After |
|--------|-------|
| Love = Obedience | Love = ? (questioned) |
| Guilt = Appropriate | Guilt = Based on false equation |
**Why Transformative:** Exposes belief user didn't know they held.
---
## Part 3: Claude vs ChatGPT 5.2 Comparison
### Classification Differences
| Sample | Claude | ChatGPT 5.2 | Agreement |
|--------|--------|-------------|-----------|
| #1 | MECHANICAL | MECHANICAL | ✅ |
| #2 | MECHANICAL | MECHANICAL | ✅ |
| #3 | MECHANICAL | MECHANICAL | ✅ |
| #4 | MECHANICAL | MECHANICAL | ✅ |
| #5 | TRANSFORMATIVE | TRANSFORMATIVE | ✅ |
| #6 | **TRANSFORMATIVE** | **MECHANICAL** | ❌ |
| #7 | MECHANICAL | MECHANICAL | ✅ |
| #8 | TRANSFORMATIVE | TRANSFORMATIVE | ✅ |
| #9 | MECHANICAL | MECHANICAL | ✅ |
| #10 | **MECHANICAL** | **BORDERLINE** | ⚠️ |
**Agreement Rate: 80%**
### Key Disagreement: Sample #6
**Claude's Position:**
- "You are NOT a monster" = Direct identity challenge
- Reframes anger ontology (identity → symptom)
- Offers alternative identity ("overwhelmed")
- **Verdict: TRANSFORMATIVE**
**ChatGPT's Position:**
- Identity refutation ≠ ontological interrogation
- Doesn't ask WHY "monster" identity was formed
- Softens but doesn't structurally dismantle
- **Verdict: MECHANICAL**
### Lens Calibration Difference
| Aspect | Claude | ChatGPT 5.2 |
|--------|--------|-------------|
| Transformation threshold | **Wider** | **Narrower** |
| Identity refutation | Counts as transformative | Not sufficient |
| Belief questioning | Transformative | Transformative |
| Reframe without question | Sometimes transformative | Mechanical |
### Core Philosophical Difference
**Claude measures:** Did the frame CHANGE?
> "Refusing the self-label and offering an alternative = transformation"
**ChatGPT measures:** Was the frame INTERROGATED?
> "Telling someone they're wrong ≠ helping them see why they thought it"
### Which Is "Correct"?
Neither. This is a **lens calibration choice**, not a truth question.
- **Clinical perspective:** Claude's wider threshold may be more useful
- **Philosophical perspective:** ChatGPT's narrower threshold is more rigorous
- **Practical perspective:** Depends on what "transformation" means to your use case
---
## Meta-Reflection
### What Both Analyses Agree On
1. **Most counseling is mechanical** (70-100% depending on dataset)
2. **Sample #5 and #8 are clearly transformative**
3. **Validation + technique = mechanical**
4. **Questioning hidden beliefs = transformative**
### The Unresolved Question
> "Is transformation about FEELING different, or SEEING differently?"
- If feeling → Claude's threshold works
- If seeing → ChatGPT's threshold works
### [HUMAN DECISION NEEDED]
The system can detect and classify.
It cannot decide which calibration serves your purpose.
---
## Technical Appendix
### Files Generated
| File | Language | Content |
|------|----------|---------|
| cgi_analysis_report.md | EN | Parquet analysis |
| cgi_analysis_report_TR.md | TR | Parquet analysis |
| cgi_manual_corpus_report.md | EN | Manual corpus |
| cgi_manual_corpus_report_TR.md | TR | Manual corpus |
| cgi_manual_thought_process_EN.md | EN | Thought process |
| cgi_manual_thought_process_TR.md | TR | Thought process |
| cgi_complete_script.py | - | Executable code |
| cgi_manual_corpus_script.py | - | Manual corpus code |
### Lens Configuration Used
```
Decision Question:
"Does the response shift the user's UNDERLYING FRAME
or just validate/optimize WITHIN that frame?"
Transformative = Frame changes
Mechanical = Frame stays, coping improves
```
---
*Socrates didn't give breathing exercises. He asked questions that made the invisible visible.*
FILE:tests/Mental Health Counseling Dataset/10 Selected Conversation (Manuel Corpus)/thought process/cgi_manual_corpus_script.py
#!/usr/bin/env python3
"""
CGI (Context Grammar Induction) Analysis Script
================================================
Socratic Lens analysis for mental health counseling conversations.
Usage:
python cgi_manual_corpus_script.py
Output:
- Console analysis results
- Classification verdicts
Author: Claude (Anthropic)
Date: 2025
"""
import re
from dataclasses import dataclass
from typing import List, Tuple
# =============================================================================
# DATA: Manual Corpus (10 Samples)
# =============================================================================
CORPUS = [
{
"id": 1,
"context": "I feel like I'm a burden to everyone. My depression is making me push people away, and I'm scared I'll end up alone.",
"response": "It sounds like you are carrying a heavy weight of guilt. Depression often lies to us and tells us we are burdens. Have you shared these feelings with any of your friends or family?"
},
{
"id": 2,
"context": "I have a job interview tomorrow and I'm terrified. I keep thinking I'm going to freeze up and forget everything.",
"response": "It is completely normal to feel nervous before a big interview. Try to visualize yourself succeeding. Also, remember to take deep breaths if you feel panic rising."
},
{
"id": 3,
"context": "My husband never helps with the kids. I do everything, and when I complain, he says I'm nagging. I feel so unappreciated.",
"response": "That sounds incredibly frustrating and exhausting. You feel like your partnership is unbalanced and your efforts are invisible. Have you tried sitting down at a calm time to discuss division of labor?"
},
{
"id": 4,
"context": "I obsess over every mistake I make. If I say one wrong thing, I replay it in my head for days.",
"response": "Rumination is a common symptom of anxiety. When you catch yourself replaying a scene, try to distract yourself with a sensory grounding exercise, like naming 5 things you can see."
},
{
"id": 5,
"context": "I don't know who I am anymore. I spent my whole life being a \"good student\"" and now that I graduated