كما كان I' يبني وضوحRAG أنا أقرأ وسائل الإعلام الإجتماعية حيث يسأل الناس نفس الشيء. عميقاً في مساحة الـ OCR اعتقدت انني سوف اكتب طريقة ' ملائمة للمبتدئين ' للطريقة غير الملائمة لتلك الطريقة
لديك صور مع نص . تريد استخراج ذلك النص , ثم تجد البنية المفيدة في داخله | ( | الأسماء |, | الشركات | МSK4 | الأماكن | ) | دون أن تتصل بـ LLM
هذه المقالة تظهر أبسط ما يمكن خط أنابيب: تيسيراكت من أجل استخراج النص, عندها بيرت نيور (via ONNX) للتعرف على الكياناتM SK2 جميعها محلية . جميعهم محددين . جميعهما في CMSC5
تعبر هنا عن نسخ ثابتة, بيانات لغة ثابتة
غويت قادم قريباً - I'm أقوم بتغليف هذا إلى شيء بسيط
mostlylucid.ocrnerمكتبة. لحد الآن, الشفرة التالية هي النسخ -paste readyM SK3
flowchart LR
subgraph OCR["Part 1: OCR"]
IMG[Image]
TESS[Tesseract]
TXT[Raw Text]
end
subgraph NER["Part 2: NER"]
TOK[Tokenize]
BERT[BERT NER<br/>ONNX]
ENT[Entities]
end
IMG --> TESS
TESS --> TXT
TXT --> TOK
TOK --> BERT
BERT --> ENT
style TESS stroke:#f60,stroke-width:3px
style BERT stroke:#f60,stroke-width:3px
style ENT stroke:#090,stroke-width:3px
خطوات اثنان , نماذج اثنتين , كلاهما يعمل محلياً | . | دع |' | يبني كل جزء |
تيسيراكت هو نموذج مفتوح - source OCR engine . سنستخدم Tesseract.NET, مُغلّم C# مَغلِم .
dotnet add package Tesseract
تحتاج أيضاً إلى حزم البيانات المدرّسة. تحميل eng.traineddata من بيانات تيس ووضعها في tessdata folder.
using Tesseract;
public static string ExtractText(string imagePath)
{
using var engine = new TesseractEngine("./tessdata", "eng", EngineMode.Default);
using var img = Pix.LoadFromFile(imagePath);
using var page = engine.Process(img);
return page.GetText();
}
تلك هي .. المكالمة ExtractText("invoice.png") وتحصل على سلسلة
مهم:
TesseractEngineيكلف صنعه. في التطبيقات الحقيقية, صنعها مرة واحدة وإعادة استخدامها
تسيراكت تعمل بشكل جيد نظيف, عالي-contrast text in standard fonts. إنها تعاني مع:
inter-\nnational) قد يحتاج إلى معالجة بعد - قبل NERللأنظمة الإنتاجية التي تحتاج إلى التعامل مع الأشياء الغريبة , أنظر أنابيب تير ثلاثية -- الذي يضيف فلورانس-2 ONNX كطبقة متوسطة وتسليط لرؤية LLM للمواد الصلبة .
لهذا الدروس , نحن' سنفترض أن لديكم صور أو نص نظيفة من مصدر آخر ( تحليل PDF
في الواقع , سترغب عادة في توصيل خروجية الـOCR ( إحداث فضاء أبيض | , إنحدار خطوط جديدة مكررة |, إصلاح المصطلحات الواضحة ٬) قبل أن تنقلها إلى NER
قبل أن نغوص في البرمجة، دعونا نفهم ما نفعله بالفعل.
التعرف على الكائنات المسمى (NER) هو مشكلة حلة. لقد قام الباحثون بتدريب شبكات عصبية يمكنها قراءة النص وتسليط الضوء على "الجزئيات المثيرة
النموذج لا يفهم 't " understood" the textM SK3itMSC4s learned statistical patterns from millions of labelled examples NER هو استخراج الخصائص, ليس استدلالًا. إنها تطابق النمط على الاستيدروجين
أونكس (تبادل شبكات عصبية مفتوحة) هو النموذج القياسي لنماذج الميل . frozen inference DLL لشبكات عصبية: ثقوب ثابتة في, مقبضات خارجيّةM SK2 لا منطق تدريبيّ
flowchart LR
subgraph Training["Training (Python)"]
PT[PyTorch Model]
TF[TensorFlow Model]
end
subgraph Export["Export Once"]
ONNX[model.onnx]
end
subgraph Runtime["Run Anywhere"]
CS[C# App]
CPP[C++ App]
JS[JavaScript App]
end
PT --> ONNX
TF --> ONNX
ONNX --> CS
ONNX --> CPP
ONNX --> JS
style ONNX stroke:#f60,stroke-width:4px
style CS stroke:#090,stroke-width:3px
الفكرة الرئيسية: شخص آخر قام بعمل شاق (تدريب النموذج في Python). تقوم فقط بتشغيل الاستنتاج في CM SK2
يمكنك إرسال رسالة نصية إلى GPT-4 وتسأل "إيجاد الأشخاص والشركات في هذا النصM SK2 إنه ينجح
| المقاربة | السرعة | التكلفة لكل | 1000 | دوتات | خصوصيية | مSK5 | التماسك | مSK6 | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| أونكس نيور | ~50ms | $0 | ||||||||||||
| واجهة LLM محلية | 4-30s | $0 | النماذج الصغيرة يمكنها أن تكون رقيقة | متغير | |||||||||||
| LLM API |
LLMs great for complex reasoning. For pattern extraction at scaleM SK1 a dedicated model is 40x faster and freeMSC3
هذا ما نصنعه هنا
flowchart LR
subgraph Input
TEXT[Raw Text]
end
subgraph Tokenization["Step 1: Tokenization"]
TOK[Split into tokens]
IDS[Convert to IDs]
end
subgraph Model["Step 2: ONNX Inference"]
BERT[BERT Model]
LOGITS[Logits Output]
end
subgraph Output["Step 3: Decode"]
LABELS[BIO Labels]
ENT[Entities]
end
TEXT --> TOK
TOK --> IDS
IDS --> BERT
BERT --> LOGITS
LOGITS --> LABELS
LABELS --> ENT
style BERT stroke:#f60,stroke-width:4px
style ENT stroke:#090,stroke-width:3px
كل خطوة بسيطة
تحتاج إلى ثلاثة فايلات من HuggingFace. تحمّلهم لاسيًا إلى папة M SK1e .g., ./models/ner/):
| الملف | الحجم | URL | |||
|---|---|---|---|---|---|
model.onnx |
~430MB | تنزيل | |||
vocab.txt مسك0 ~230KB |
تنزيل | ||||
config.json مسك0 ~1KB |
تنزيل |
النموذج هو bert-base-NER exported to ONNX format by محمية.
يجب أن تبدو مجلدك مثل:
models/
ner/
model.onnx (the neural network)
vocab.txt (word → ID mapping)
config.json (label definitions)
إنشاء تطبيق تحكم جديد وإضافة حزم NuGet:
dotnet new console -n NerDemo
cd NerDemo
dotnet add package Microsoft.ML.OnnxRuntime
dotnet add package Microsoft.ML.Tokenizers
ذلك ' s it . بطاقتين :
قبل أن يستطيع النموذج معالجة النص , نحتاج إلى تحويله إلى أرقام . هذا يدعى التدوين.
flowchart TD
subgraph Input
TEXT["John works at Microsoft"]
end
subgraph Tokenize["Tokenization"]
T1["[CLS]"]
T2["John"]
T3["works"]
T4["at"]
T5["Microsoft"]
T6["[SEP]"]
end
subgraph IDs["Token IDs"]
I1["101"]
I2["1287"]
I3["2573"]
I4["1120"]
I5["7513"]
I6["102"]
end
TEXT --> T1 & T2 & T3 & T4 & T5 & T6
T1 --> I1
T2 --> I2
T3 --> I3
T4 --> I4
T5 --> I5
T6 --> I6
style T1 stroke:#c00,stroke-width:3px
style T6 stroke:#c00,stroke-width:3px
style I2 stroke:#090,stroke-width:3px
style I5 stroke:#090,stroke-width:3px
النقاط الرئيسية:
[CLS] و [SEP] هي اشارات خاصة تشير إلى حدود الجملةvocab.txtusing Microsoft.ML.Tokenizers;
// Load the vocabulary file
var vocabPath = "./models/ner/vocab.txt";
var options = new BertOptions
{
LowerCaseBeforeTokenization = false, // BERT-NER is case-sensitive!
UnknownToken = "[UNK]",
ClassificationToken = "[CLS]",
SeparatorToken = "[SEP]",
PaddingToken = "[PAD]"
};
using var stream = File.OpenRead(vocabPath);
var tokenizer = BertTokenizer.Create(stream, options);
لماذا LowerCaseBeforeTokenization = false? تم تدريب هذا النماذج على نص مكعب. "JohnM SK3 و MSC4johnMSC5 لها معناه مختلفةMST6oneMS'محتمل أن يكون اسمًا
مهم: الرمز يجب أن تتطابق بالنموذج بالضبط. بإستخدام حرف مختلف, إختيار القضبان , أو هوية رموز خاصة سوف تحطم النتائج بصمت
vocab.txtالذي يركب مع النموذج.
var text = "John Smith works at Microsoft in London.";
// Tokenize (splits into subwords)
var encoded = tokenizer.EncodeToTokens(text, out _);
// Get special token IDs
var clsId = 101; // [CLS] token
var sepId = 102; // [SEP] token
// Build the full sequence: [CLS] + tokens + [SEP]
var tokenIds = new List<int> { clsId };
tokenIds.AddRange(encoded.Select(t => t.Id));
tokenIds.Add(sepId);
// Also keep the text tokens for later
var tokens = new List<string> { "[CLS]" };
tokens.AddRange(encoded.Select(t => t.Value));
tokens.Add("[SEP]");
بعد هذا , لدينا :.
tokenIds: [101, 1287, 3455, 2573, 1120, 7513, 1999, 2414, 119, 102]tokens: ["[CLS]", "John", "Smith", "works", "at", "Microsoft", "in", "London", ".", "[SEP]"]الآن ندخل هذه الأرقام في نموذج ONNX
flowchart LR
subgraph Inputs
IDS["Token IDs<br/>[101, 1287, 3455, ...]"]
MASK["Attention Mask<br/>[1, 1, 1, ...]"]
end
subgraph Model
ONNX["BERT NER<br/>model.onnx"]
end
subgraph Outputs
LOG["Logits<br/>[batch, seq_len, 9]"]
end
IDS --> ONNX
MASK --> ONNX
ONNX --> LOG
style ONNX stroke:#f60,stroke-width:4px
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
// Configure for best performance
var sessionOptions = new SessionOptions
{
GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL,
IntraOpNumThreads = Math.Min(4, Environment.ProcessorCount)
};
// Load the model (takes ~2 seconds first time)
var session = new InferenceSession("./models/ner/model.onnx", sessionOptions);
مهم: إنشاء session of tokenizer and inference once (singleton
InferenceSessionمن التكلفة أن تصنع
النموذج يتوقع:
long[]// Pad to a fixed length (BERT requires fixed shapes; powers of 2 are cache-friendly)
int sequenceLength = 64; // or 128, 256, 512
var inputIds = new long[sequenceLength];
var attentionMask = new long[sequenceLength];
for (int i = 0; i < sequenceLength; i++)
{
if (i < tokenIds.Count)
{
inputIds[i] = tokenIds[i];
attentionMask[i] = 1;
}
else
{
inputIds[i] = 0; // PAD token
attentionMask[i] = 0;
}
}
// Create tensors (shape: [batch_size=1, sequence_length])
var inputIdsTensor = new DenseTensor<long>(inputIds, [1, sequenceLength]);
var attentionMaskTensor = new DenseTensor<long>(attentionMask, [1, sequenceLength]);
// Build inputs
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("input_ids", inputIdsTensor),
NamedOnnxValue.CreateFromTensor("attention_mask", attentionMaskTensor)
};
// Run the model
using var results = session.Run(inputs);
// Get output logits
var output = results.First(r => r.Name == "logits");
var logits = output.AsTensor<float>();
المخرج logits لديه شكل [1, sequence_length, 9]-9 possibly labels for each token position.
النموذج ينتج نقاط خامة. نحن بحاجة إلى
النموذج يستخدم ملاحظة بيولوجية:
flowchart LR
subgraph Tokens
T1["John"]
T2["Smith"]
T3["works"]
T4["at"]
T5["Microsoft"]
end
subgraph Labels
L1["B-PER"]
L2["I-PER"]
L3["O"]
L4["O"]
L5["B-ORG"]
end
T1 --> L1
T2 --> L2
T3 --> L3
T4 --> L4
T5 --> L5
style L1 stroke:#090,stroke-width:3px
style L2 stroke:#090,stroke-width:3px
style L5 stroke:#00f,stroke-width:3px
هذا يسمح للنموذج بتعامل مع العديد من -كلمات مثل "جون سميث" أو "مملكة المتحدةM SK4
// These are the 9 labels the model was trained on (CoNLL-2003 dataset)
string[] labels =
{
"O", // 0: Outside any entity
"B-PER", // 1: Beginning of Person
"I-PER", // 2: Inside Person
"B-ORG", // 3: Beginning of Organization
"I-ORG", // 4: Inside Organization
"B-LOC", // 5: Beginning of Location
"I-LOC", // 6: Inside Location
"B-MISC", // 7: Beginning of Miscellaneous
"I-MISC" // 8: Inside Miscellaneous
};
ملاحظة: هذا النموذج المحدد يستخدم معيار 9-label schema CoNLL. بعض निर्यातات ONNX تتضمن أسماء العلامات في
config.json(id2labelمجال). إذا قمت باستبدال النماذج, قراءة العلامات من konfigur بدلاً عن البرمجة القاسيةM SK2
لكل علامة نختار العلامة ذات التقييم الأعلى
var predictions = new List<(string Token, string Label, float Confidence)>();
int numLabels = 9;
for (int i = 0; i < tokens.Count; i++)
{
// Skip special tokens
if (tokens[i] is "[CLS]" or "[SEP]" or "[PAD]")
continue;
// Find highest scoring label
float maxScore = float.MinValue;
int maxIndex = 0;
for (int j = 0; j < numLabels; j++)
{
float score = logits[0, i, j];
if (score > maxScore)
{
maxScore = score;
maxIndex = j;
}
}
// Convert logit to probability (softmax)
float confidence = Softmax(logits, i, numLabels, maxIndex);
predictions.Add((tokens[i], labels[maxIndex], confidence));
}
الـ Softmax Function converts raw scores to probabilities (0-1):
static float Softmax(Tensor<float> logits, int position, int numLabels, int targetIndex)
{
// Find max for numerical stability
float maxLogit = float.MinValue;
for (int j = 0; j < numLabels; j++)
maxLogit = Math.Max(maxLogit, logits[0, position, j]);
// Compute softmax
float sumExp = 0f;
for (int j = 0; j < numLabels; j++)
sumExp += MathF.Exp(logits[0, position, j] - maxLogit);
return MathF.Exp(logits[0, position, targetIndex] - maxLogit) / sumExp;
}
ملاحظة حول الثقة: نقاط Softmax هي النسيج, احتمالات غير مقيَّدة. هي ' مفيدة لتصنيف وتقدير الدرجاتM SK3 لكنها لا تعالج
0.92كـ "92% صحيحة". استخدمها لتصفية توقعات الثقة المنخفضة -M SK3 وليست حقاً أرضياً
الآن لدينا توقعات للـ - ,token ,. .علينا أن ندمجها في كيانات ..
أولا, مساعدات دمج WordPiece. هذه المقبض ## كلمات فرعية وامتداد العلامات بشكل صحيح:
static void AppendWordPiece(StringBuilder sb, string token)
{
if (string.IsNullOrEmpty(token)) return;
// WordPiece continuation: "##soft" → append without space
if (token.StartsWith("##", StringComparison.Ordinal))
{
sb.Append(token.AsSpan(2));
return;
}
// No leading space if first token or if punctuation
if (sb.Length > 0 && !IsPunctuationToken(token))
sb.Append(' ');
sb.Append(token);
}
static bool IsPunctuationToken(string token) =>
token.Length == 1 && char.IsPunctuation(token[0]);
static string MergeWordPieces(IEnumerable<string> tokens)
{
var sb = new StringBuilder();
foreach (var t in tokens)
AppendWordPiece(sb, t);
return sb.ToString();
}
الآن استخراج الكائنات . الثقة الكائنة هي الثقة المحدودة في الرموز على امتداد المسافة - conservative , بحيث لا يتم إخفاء علامة ضعيفة واحدة .
public sealed class Entity
{
public required string Text { get; init; }
public required string Type { get; init; } // PER, ORG, LOC, MISC
public required float Confidence { get; init; }
}
static List<Entity> ExtractEntities(
IReadOnlyList<(string Token, string Label, float Confidence)> predictions)
{
var entities = new List<Entity>();
string? currentType = null;
var currentTokens = new List<string>();
float currentConfidence = 1.0f;
void Flush()
{
if (currentType == null || currentTokens.Count == 0) return;
entities.Add(new Entity
{
Type = currentType,
Text = MergeWordPieces(currentTokens),
Confidence = currentConfidence
});
currentType = null;
currentTokens.Clear();
currentConfidence = 1.0f;
}
foreach (var (token, label, conf) in predictions)
{
// Continue current entity if model says I-<same type>
if (currentType != null && label == $"I-{currentType}")
{
currentTokens.Add(token); // keep ## form, merge handles it
currentConfidence = Math.Min(currentConfidence, conf);
continue;
}
// New entity begins
if (label.StartsWith("B-", StringComparison.Ordinal))
{
Flush();
currentType = label[2..];
currentTokens.Add(token);
currentConfidence = conf;
continue;
}
// Anything else (O, or I- without matching current type) ends the entity
Flush();
}
Flush();
return entities;
}
ملاحظة: WordPiece يتم التعامل معه بالكامل بواسطة MergeWordPieces-لا حاجة لتدفق التحكم الخاص
هنا' مثال عمل بسيط يمكنك نسخه وتشغيله
using System.Text;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.Tokenizers;
// === Configuration ===
var modelPath = "./models/ner/model.onnx";
var vocabPath = "./models/ner/vocab.txt";
// === Load tokenizer ===
var bertOptions = new BertOptions
{
LowerCaseBeforeTokenization = false,
UnknownToken = "[UNK]",
ClassificationToken = "[CLS]",
SeparatorToken = "[SEP]"
};
using var vocabStream = File.OpenRead(vocabPath);
var tokenizer = BertTokenizer.Create(vocabStream, bertOptions);
// === Load model ===
var sessionOptions = new SessionOptions
{
GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL
};
using var session = new InferenceSession(modelPath, sessionOptions);
// === Process text ===
var text = "John Smith, CEO of Microsoft, announced the acquisition in London yesterday.";
// Tokenize
var encoded = tokenizer.EncodeToTokens(text, out _);
// Build sequence with special tokens
var tokens = new List<string> { "[CLS]" };
tokens.AddRange(encoded.Select(t => t.Value));
tokens.Add("[SEP]");
var rawIds = new List<int> { 101 }; // [CLS]
rawIds.AddRange(encoded.Select(t => t.Id));
rawIds.Add(102); // [SEP]
// Pad to fixed length
int seqLen = 64;
var inputIds = new long[seqLen];
var attentionMask = new long[seqLen];
for (int i = 0; i < seqLen; i++)
{
inputIds[i] = i < rawIds.Count ? rawIds[i] : 0;
attentionMask[i] = i < rawIds.Count ? 1 : 0;
}
// === Run inference ===
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("input_ids",
new DenseTensor<long>(inputIds, [1, seqLen])),
NamedOnnxValue.CreateFromTensor("attention_mask",
new DenseTensor<long>(attentionMask, [1, seqLen]))
};
using var results = session.Run(inputs);
var logits = results.First().AsTensor<float>();
// === Decode predictions ===
string[] labels = ["O", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC", "B-MISC", "I-MISC"];
// WordPiece merge helper
static string MergeWordPieces(List<string> tokens)
{
var sb = new StringBuilder();
foreach (var t in tokens)
{
if (t.StartsWith("##", StringComparison.Ordinal))
sb.Append(t.AsSpan(2));
else if (sb.Length > 0 && t.Length > 0 && !char.IsPunctuation(t[0]))
sb.Append(' ').Append(t);
else
sb.Append(t);
}
return sb.ToString();
}
Console.WriteLine($"Input: {text}\n");
Console.WriteLine("Entities found:");
string? currentType = null;
var currentTokens = new List<string>();
for (int i = 1; i < tokens.Count - 1; i++) // Skip [CLS] and [SEP]
{
var token = tokens[i];
// Find best label
int bestIdx = 0;
float bestScore = float.MinValue;
for (int j = 0; j < 9; j++)
{
if (logits[0, i, j] > bestScore)
{
bestScore = logits[0, i, j];
bestIdx = j;
}
}
var label = labels[bestIdx];
// Continue current entity if model says I-<same type>
if (currentType != null && label == $"I-{currentType}")
{
currentTokens.Add(token);
continue;
}
// New entity begins
if (label.StartsWith("B-"))
{
if (currentType != null)
Console.WriteLine($" [{currentType}] {MergeWordPieces(currentTokens)}");
currentType = label[2..];
currentTokens = [token];
continue;
}
// Anything else ends the current entity
if (currentType != null)
Console.WriteLine($" [{currentType}] {MergeWordPieces(currentTokens)}");
currentType = null;
currentTokens.Clear();
}
// Output last entity
if (currentType != null)
Console.WriteLine($" [{currentType}] {MergeWordPieces(currentTokens)}");
ال sortie:
Input: John Smith, CEO of Microsoft, announced the acquisition in London yesterday.
Entities found:
[PER] John Smith
[ORG] Microsoft
[LOC] London
يستخدم BERT تدوين WordPiece, الذي يقسم الكلمات غير المعروفة إلى كلمات فرعية ## prefix means "continuation of previous word":
flowchart LR
subgraph Original
W1["Elasticsearch"]
end
subgraph Tokenized
T1["Elastic"]
T2["##search"]
end
subgraph Merged
M1["Elasticsearch"]
end
W1 --> T1 & T2
T1 --> M1
T2 --> M1
style T2 stroke:#c00,stroke-width:3px
الـ MergeWordPieces المساعد يتعامل مع هذا: ## تم إضافة الرموز دون أن يكون هناك فضاء "Elasticsearch" بدلاً من "Elastic search".
إذا كان لديك الكثير من الرسائل , تعالجها في مجموعات :
// Instead of: 1 text × 1 inference = 50ms
// Do: 16 texts × 1 inference = 100ms (6ms per text)
int batchSize = 16;
var batchInputIds = new long[batchSize, seqLen];
// ... fill batch ...
var tensor = new DenseTensor<long>(batchInputIds, [batchSize, seqLen]);
لا تقلصوا دائماً إلى 512. استخدموا أصغر سطل يلائم :
int[] buckets = [32, 64, 128, 256, 512];
int targetLength = buckets.FirstOrDefault(b => b >= tokenIds.Count);
if (targetLength == 0) targetLength = 512;
في الواقع , ONNX NER سريع بما فيه الكفاية لتشغيله في الخطوط أثناء الإمتصاص, ليس فقط كمهمة عمل. يمكنك استخراج الكائنات عند وصول الوثائق بدلاً من الاصطفاء لها في وقت لاحق
للسرعة العالية , إستخدم DirectML (WindowsM SK2 أو CUDA:
dotnet add package Microsoft.ML.OnnxRuntime.DirectML # Windows GPU
# or
dotnet add package Microsoft.ML.OnnxRuntime.Gpu # NVIDIA CUDA
var options = new SessionOptions();
options.AppendExecutionProvider_DML(); // Use GPU
| إستخدم ONNX NER | إستخدام LLM (GPTM SK3Claude) |
|---|---|
| حجم كبير (1000s من الأبحاث ) | واحد -تحليل خارجي |
| الوحدات القياسية ( الناس, المنظماتM SK3 الأماكنMNK4 | أنواع الوحدت المخصصة SNK6 |
| خصوصية-بيانات حساسة | عندما تحتاج إلى تفسير |
| خطوط أنابيب إختبارية | تحليل استكشافي |
| استخراج الخصائص | تفسير / استنساخ |
كلا النهجين يعملون. يحلون مشاكل مختلفة. يستخرج NER الهيكل; سبب LLM عن المعنىM SK2
هذا النمط-الاستخراج الإفتراضي مع نماذج متجمدة, تتبعها التركيبة البديلة لاحقاً- يتقلص أفضل بكثير من دفع النص الخام إلى LLM ويأمل أن يتصرف
NER ليس شيئًا تقوم به "agentify". إنهM SK2بنية تحتية . تقوم بتشغيله عند الإدخالMSC4 تخزين الكائناتMNK5 وتستخدمها في الأسفل لصفيتهاMRK6 ربطهاMMK7 أو توصيلها في خطوط أنابيب أكثر تعقيدًا
نفس المقاربة تطبق على مهمات إستخراج الخصائص الأخرى..
أين يلائم هذا: هذا الرسم البياني + خط أنابيب النطاق الشمالي هو قطعة بناء واحدة. للصورة الكاملةM SK3 كيف تتغذى الكائنات المستخرجة في بناء الرسوم البيانيةMSC4 التكرارMNK5 والإستخراجMMK6انظر تقلل من RAG و وثائق LucidRAG. الكائنات التي تخرجها هنا تصبح العقدة; الوثائق تصبح الحوافM SK2 يشاهد LLM فقط ما يحتاجه
المكتبات & نماذج:
المقالات المرتبطة:
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.