This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Thursday, 18 December 2025
السلسلة: LLLs المحلي للبيانات - الجزء 1 من 2
هذا هو الخطأ الذي يرتكبه الجميع: يحاولون أن يغذيوا سيرتهم الذاتية في إل إل إل إل إل إل. لا تفعل. وينبغي أن تولد هذه السجلات استفسارات، لا أن تستهلك البيانات.
لديك ملف CSV و تريد أن تسأل "ما هو متوسط قيمة الترتيب بحسب المنطقة؟" أدوات مثل جاري التنفيذ في Excel هل تستطيع فعل هذا ، ولكن ماذا لو كانت بياناتك حساسة جدا لخدمات السحابة ؟ ماذا لو احتجت ان تبنيها بنفسك ؟
هذه المقالة تظهر لكم كيف - محليا، خاصا، في C#.
استخدم DakDB للاستفسار عن ملفات CSV مباشرة. استخدم LLM محلي لتولد SQL. الـ LLM لا ترى بياناتك - فقط المخطط. Case: sub- 100m queentions on millon- row files, outline.
وللاطلاع على علاج تكميلي يركز بقدر أكبر على المبادرة المتكاملة للبيانات المكانية ويتوسع في استخدام الملامح الإحصائية كواجهة LLM (ويظهر أداة كاملة لتنفيذ هذه الأفكار - التنميط، وأسلوب SQL الآمن، والاستنساخ الاصطناعي، والكشف عن الانجراف)، انظر المقال المرافق: البيانات SD البيانات مخطِط: تحديد البيانات المحلية السريعة - ولا سيما القسم المعنون "The Key Update: Statistics as Interspace". وتشكل هاتان المقالتان سلسلة قصيرة عن أنماط LLM المحلية العملية + الاستعلام.
استخدام LLM كمخزن بيانات هو خطأ التجريد. LLMs هي أساساً غير قادرة على مسح الملايين من الصفوف لحساب متوسط - هذا ليس ما هي عليه. حتى نافذة السياق الرمزي 200K تناسب ربما 50000 صف. لديك 500MB CSV ملايين.
الـ صحيح نمط: أسباب LLLL، قاعدة البيانات الحسابية.
flowchart LR
A[User Question] --> B[LLM]
B --> C[SQL Query]
C --> D[DuckDB]
D --> E[Results]
style B stroke:#333,stroke-width:4px
style D stroke:#333,stroke-width:4px
لاحظ ما يحدث: LLLM يولد استعلام SQL بناءً على سؤالك والمخطط. DakDB ينفذه على البيانات الفعلية. LLM لا يلمس بياناتك أبداً - إنه فقط يرى أسماء وأصناف الأعمدة. لهذا السبب هو سريع وخاص ودقيق.
وللاطلاع على مزيد من المعلومات عن معالجة النبذات باعتبارها واجهة LLLLM (ومؤشراً عملياً عملياً ملموساً يُنفِّذ التوصيفات - أولاً السرد، وسؤالاً مأموناً مدعوماً من SQL، وQ&A، وجلسات مدعومة بالسجل، واستنساخاً إصطناعياً)، انظر: البيانات SD البيانات مخطِط: تحديد البيانات المحلية السريعة.
والنُهُج الواضحة تتشاطر جميعاً نفس العيب المميت:
Csvvvverer / إعدادات البياناتحمّل ملفّ الكل ملفّ إلى NAM. A 500MB CSV يصبح 2-4GB من كائنات. A 5GB ملفّ؟ OOOM تحطّم.
SQLite / PostgresQL: يحتاج إلى درجة استيراد بطيئة (دقائق للملفات الكبيرة)، وتعاريف أولية، وتكاليف عامة لإدارة قاعدة البيانات.
PandsAI: ما زالت تحمل كل شيء في الذاكرة. بالإضافة إلى ذلك، تنفيذ LLM الشفرة التعسفية المولدة من LLM كابوس أمني - SQL هو تفسيري ورمل قابل للتغليف؛ Python ليس.
DDB هو إستفسارات CCSV ملفات مباشرة مباشرة - لا خطوة استيراد، لا تحميل في الذاكرة:
using var connection = new DuckDBConnection("DataSource=:memory:");
connection.Open();
using var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT Region, SUM(Amount) FROM 'sales.csv' GROUP BY Region";
// Executes directly against the file - no import, no memory explosion
السمة القاتلة: يُعامل الملفات كجداوللا يوجد طابور، لا مدخل سائب، لا إنتظار.
Vactor / Csvfrder / SQLite / DaddB / |--------|-----------|--------|--------| | ذاكرة يحمّل كامل ملفّ حمولات أثناء استيراد / سطور من قرص / | إنشاء [لا يوجد] Schema + استيراد: لا يوجد] | **** □ 2GB RAM □ دقائق لاستيراد □ | **** تحطّم في مكان الحادث / بطيئ جداً جداً يَعْملُ غرامةَ / | **** لا، لا، لا، نعم (10-100x أسرع)
DakDB هو ما يستخدمه مهندسو البيانات في بايثون في حالة الاستخدام هذه. صحائف التجليات تعطيك كامل دعم ADO.net - يبدو مثل أي قاعدة بيانات أخرى، إلا أنك تستجوب الملفات.
• العنصر / لماذا هذا الشخص /
|-----------|--------------|
| DDB أسئلة CSV مباشرة، لا توجد خطوة استيراد
| الرشـتـان دعم كامل لـ ADO.net، يشعر بالوطن
| الوليمة استدلال محلي، لا مفاتيح API، لا سحابة
| الكسس □ بيانات الاختبار الواقعية على أي نطاق □
| qwen2.5-coder:7b أفضل دقة QQL SQL في حجم 7B
مذكرة بشأن الأمنهذا أكثر أماناً من الشفرة التعسفية، لكنّه ما زال يتطلب التحقق. قسم الأمن وللاطلاع على مناقشة أوسع بشأن تحويل الملامح إلى واجهة LLLL ومؤشراً محلياً ينفذ هذه الأنماط، انظر القطعة المرافقة. البيانات SD البيانات مخطِط: تحديد البيانات المحلية السريعة.
دعونا ننشئ مشروع عينة. تثبيت الحزمة:
dotnet add package DuckDB.NET.Data.Full
dotnet add package OllamaSharp
dotnet add package Bogus
سحب a تشفير التركيز نموذج هو جيّد في SQL:
ollama pull qwen2.5-coder:7b
وهنا كيف تنسجم القطع مع بعضها البعض:
flowchart TB
subgraph Input
Q[User Question]
CSV[CSV File]
end
subgraph Processing
Schema[Extract Schema]
Sample[Get Sample Rows]
Context[Build LLM Context]
LLM[Generate SQL]
Validate[Validate SQL]
Execute[Execute Query]
end
subgraph Output
Results[Query Results]
end
CSV --> Schema
CSV --> Sample
Schema --> Context
Sample --> Context
Q --> Context
Context --> LLM
LLM --> Validate
Validate -->|Error| LLM
Validate -->|OK| Execute
CSV --> Execute
Execute --> Results
style LLM stroke:#333,stroke-width:4px
style Execute stroke:#333,stroke-width:4px
الفكرة الرئيسية: نحن نعطي LLLM ثانياً - البيانات المتعلقة بالمخطط والبيانات المتعلقة بالعينةلا البيانات الفعلية. هذا يبقي السياق صغير والاستجابات سريعة.
لهذا السبب هذا الأمرالدالة LLM توليد النية (SQL). DaDB ينفّذ ذلك. الـ confid this this this this status synstatus obthing obs قبل التنفيذ. الـ restry place communicle fault. هذا الفصل هو ما يجعل النظام أكثر أماناً ودقة. لمزيد من التفصيل CLI- conconnect reviews (بما في ذلك النبذة - الأوّل thirg and sQL الآمن standards) انظر. البيانات SD البيانات مخطِط: تحديد البيانات المحلية السريعة.
هل لديك بيانات CSV؟ إلى هذا الخطوة 2: بناء الإطار.
قبل أن نتمكن من اختبار جهاز تحليل CSV الذي يعمل بطاقته LLLL، نحتاج إلى بيانات لتحليلها. من أجل التطوير والاختبار، البيانات الإصطناعية تتغلب على البيانات الحقيقية:
الكسس هو ميناء NET لمكتبة المزيفين الشعبية. يولّد بيانات زائفة واقعية المظهر - الأسماء، العناوين، البريد الإلكتروني، التواريخ، الأرقام - مع دعم محلي مناسب. بدلاً من اختبار التركيب اليدوي ملفات CSV أو استخدام بيانات القمامة العشوائية، بوغوس يعطيك بيانات أن النظرات في الواقع:
f.Name.FullName() • "جون سميث" (وليس "asdf1234")f.Internet.Email() □ "[email protected]" (الصيغة الموضحة بصورة مباشرة)f.Date.Between(start, end) □ التوزيع الحقيقي لتاريخ التوزيعf.Commerce.ProductName() "الجبن الغراني المصنَّع" (متعة، ولكن يمكن الاعتراف بها)هذا الأمر مهم لأن البيانات الواقعية تساعدك على تحديد القضايا - التهيئة الغريبة، التجميعات غير المتوقعة، حالات الحافة في التعامل مع التاريخ - التي يمكن أن تختبئ فيها السلاسل العشوائية.
internal class SaleRecord
{
public string OrderId { get; set; } = "";
public DateTime OrderDate { get; set; }
public string CustomerId { get; set; } = "";
public string CustomerName { get; set; } = "";
public string Region { get; set; } = "";
public string Category { get; set; } = "";
public string ProductName { get; set; } = "";
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal Discount { get; set; }
public bool IsReturned { get; set; }
}
يستخدم بوغوس معدلاً قياسياً متقناً لتحديد قواعد التوليد:
var categories = new[] { "Electronics", "Clothing", "Home & Garden", "Sports", "Books" };
var regions = new[] { "North", "South", "East", "West", "Central" };
var faker = new Faker<SaleRecord>()
.RuleFor(s => s.OrderId, f => f.Random.Guid().ToString()[..8].ToUpper())
.RuleFor(s => s.OrderDate, f => f.Date.Between(
new DateTime(2022, 1, 1),
new DateTime(2024, 12, 31)))
.RuleFor(s => s.CustomerId, f => $"CUST-{f.Random.Number(10000, 99999)}")
.RuleFor(s => s.CustomerName, f => f.Name.FullName())
.RuleFor(s => s.Region, f => f.PickRandom(regions))
.RuleFor(s => s.Category, f => f.PickRandom(categories))
.RuleFor(s => s.ProductName, (f, s) => GenerateProductName(f, s.Category))
.RuleFor(s => s.Quantity, f => f.Random.Number(1, 20))
.RuleFor(s => s.UnitPrice, f => f.Random.Decimal(9.99m, 299.99m))
.RuleFor(s => s.Discount, f => f.Random.Bool(0.3f) ? f.Random.Decimal(0.05m, 0.25m) : 0m)
.RuleFor(s => s.IsReturned, f => f.Random.Bool(0.05f));
دعونا نوضح ما يحدث:
f (الضعف) - حالة المولد مع إمكانية الوصول إلى جميع وحدات البيانات (الاسم، التاريخ، المنطقة العشوائية، وما إلى ذلك)f.Random.Guid().ToString()[..8] - تُعدّ علامة رمزية ولكن تأخذ فقط أولاً فقط 8 درجات لـ a قراءة أمر تعريفf.Date.Between() - التاريخ العشوائي ضمن نطاق واقعي )وليس السنة ٩٩٩٩٩(f.PickRandom(array) - انتقِش عشوائياً من خيارات معرفة مسبقاً (الضماناتf.Random.Bool(0.3f) - 30 في المائة فرصة حقيقية (30 في المائة من الطلبات تحصل على خصم)(f, s) ** - الوصول إلى كل من المزيفة والمزيفة والسجل الجزئي - هذا يسمح ProductName الاعتماد على Categoryالـ (f, s) هذا التماسك يجعل البيانات المتولدة أكثر واقعية لاختبار التجميعات مثل "الإيراد حسب الفئة".
var records = faker.Generate(100_000); // Adjust for your testing needs
await using var writer = new StreamWriter(csvPath, false, Encoding.UTF8);
await writer.WriteLineAsync("OrderId,OrderDate,CustomerId,CustomerName,Region,Category,...");
foreach (var record in records)
{
var total = record.Quantity * record.UnitPrice * (1 - record.Discount);
await writer.WriteLineAsync($"{record.OrderId},{record.OrderDate:yyyy-MM-dd},...");
}
الـ توليد هو سريع لـ لـ بوغوس لـ سَتّة.
بِتْ بِجِيجأولاً- وضع
Randomizer.Seed = new Random(12345)قبل توليد للحصول على بيانات قابلة للتكرير. نفس البذرة = نفس سجلات "العشوائية" في كل مرة، وهو أمر قيم للتنقيط.
قبل LLM قادر على توليد SQL، يحتاج إلى فهم بنية البيانات. نستخرج هذا من DakDB:
public class DataContext
{
public string CsvPath { get; set; } = "";
public List<ColumnInfo> Columns { get; set; } = new();
public List<Dictionary<string, string>> SampleRows { get; set; } = new();
public long RowCount { get; set; }
}
public class ColumnInfo
{
public string Name { get; set; } = "";
public string Type { get; set; } = ""; // VARCHAR, DOUBLE, TIMESTAMP, etc.
}
هذا يلتقط كل شيء تحتاج إليه LLLM: أسماء الأعمدة، الأنواع، وعدد قليل من صفوف العينات لفهم شكل البيانات.
DachdB يمكن أن يصف أي CVS بدون تحميله كلّ:
private DataContext BuildContext(DuckDBConnection connection, string csvPath)
{
var context = new DataContext { CsvPath = csvPath };
// Get schema - DuckDB infers types from the CSV
using var cmd = connection.CreateCommand();
cmd.CommandText = $"DESCRIBE SELECT * FROM '{csvPath}'";
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
context.Columns.Add(new ColumnInfo
{
Name = reader.GetString(0), // Column name
Type = reader.GetString(1) // Inferred type
});
}
return context;
}
الـ DESCRIBE الأمر يقرأ فقط ترويسة الملف بالإضافة إلى بضعة صفوف للنوع الاستدلال - هو موجود حتى على ملفات ضخمة.
تساعد صفّات العينات LLLM على فهم أشكال البيانات (التواريخ، الهويات، وما إلى ذلك):
using var cmd = connection.CreateCommand();
cmd.CommandText = $"SELECT * FROM '{csvPath}' LIMIT 3";
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
var row = new Dictionary<string, string>();
for (int i = 0; i < reader.FieldCount; i++)
{
var value = reader.IsDBNull(i) ? "NULL" : reader.GetValue(i)?.ToString() ?? "";
row[reader.GetName(i)] = value;
}
context.SampleRows.Add(row);
}
ثلاثة صفوف عادة ما تكون كافية - فهي تبين LLLM ما هي الأشكال التي يمكن توقعها بدون إهدار الرموز.
هذا هو الجزء الصعب. الهندسة السريعة هنا غير قابلة للتفاوض - بدون قواعد صارمة، LLMs المحلية سوف تنتج الإبداع ولكن كسر SQL. الهدف هو التحديد، وليس الإبداع.
private string BuildPrompt(DataContext context, string question, string? previousError)
{
var sb = new StringBuilder();
sb.AppendLine("You are a SQL expert. Generate a DuckDB SQL query to answer the user's question.");
sb.AppendLine();
sb.AppendLine("IMPORTANT RULES:");
sb.AppendLine("1. The table is accessed directly from the CSV file path");
sb.AppendLine("2. Use single quotes around the file path in FROM clause");
sb.AppendLine("3. DuckDB syntax - use LIMIT not TOP, use || for string concat");
sb.AppendLine("4. Return ONLY the SQL query, no explanation, no markdown");
sb.AppendLine();
sb.AppendLine($"CSV File: '{context.CsvPath}'");
sb.AppendLine($"Row Count: {context.RowCount:N0}");
sb.AppendLine();
// Schema
sb.AppendLine("Schema:");
foreach (var col in context.Columns)
{
sb.AppendLine($" - {col.Name}: {col.Type}");
}
قسم القواعد مهم جداً - فهو يخبر LLLM بالضبط كيفية تشكيل الإستفسار لـ DakDB. أن يكون صريحاً حول syditax (LIMT vs TOP, concateation الأوتار) يمنع الأخطاء الشائعة.
if (context.SampleRows.Count > 0)
{
sb.AppendLine();
sb.AppendLine("Sample data (first 3 rows):");
foreach (var row in context.SampleRows)
{
var values = row.Select(kv => $"{kv.Key}='{kv.Value}'");
sb.AppendLine($" {{{string.Join(", ", values)}}}");
}
}
إذا فشلت محاولة سابقة، أدرج الخطأ:
if (previousError != null)
{
sb.AppendLine();
sb.AppendLine("YOUR PREVIOUS QUERY HAD AN ERROR:");
sb.AppendLine(previousError);
sb.AppendLine("Please fix the query based on this error.");
}
sb.AppendLine();
sb.AppendLine($"Question: {question}");
sb.AppendLine();
sb.AppendLine("SQL Query (no markdown, no explanation):");
return sb.ToString();
}
آلية إعادة البحث هذه مهمة - LLLS المحلية في بعض الأحيان تفعل أخطاء في الصياغة، وتعطيهم الخطأ عادة إصلاحه على المحاولة الثانية.
var request = new GenerateRequest { Model = _model, Prompt = prompt };
var response = await _ollama.GenerateAsync(request).StreamToEndAsync();
var sql = CleanSqlResponse(response?.Response ?? "");
الـ StreamToEndAsync() تنتظر الإستجابة الكاملة. لـ a أفضل UX، أنت يُمْكِنُ أَنْ تَرْفعَ الرموزَ عندما تَصِلُ.
غالباً ما تلف LLS SQL في كتل رمزية على الرغم من أنه تم إخبارها بعدم:
private string CleanSqlResponse(string response)
{
var sql = response.Trim();
// Remove markdown code blocks if present
if (sql.StartsWith("```"))
{
var lines = sql.Split('\n').ToList();
lines.RemoveAt(0); // Remove opening ```sql
if (lines.Count > 0 && lines[^1].Trim().StartsWith("```"))
{
lines.RemoveAt(lines.Count - 1); // Remove closing ```
}
sql = string.Join('\n', lines);
}
return sql.Trim('`', ' ', '\n', '\r');
}
DDB's EXPLAIN نتحقق من SQL selection unther this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this this
private string? ValidateSql(DuckDBConnection connection, string sql)
{
try
{
using var cmd = connection.CreateCommand();
cmd.CommandText = $"EXPLAIN {sql}";
cmd.ExecuteNonQuery();
return null; // Valid
}
catch (Exception ex)
{
return ex.Message;
}
}
إذا فشل التحقق، نقوم بتغذية الخطأ مرة أخرى إلى LLM و إعادة الاختبار (حتى حد أقصى).
الـ جاري التنفيذ و تنسيق مخرجات:
private QueryResult ExecuteQuery(DuckDBConnection connection, string sql)
{
var result = new QueryResult { Sql = sql };
try
{
using var cmd = connection.CreateCommand();
cmd.CommandText = sql;
using var reader = cmd.ExecuteReader();
// Capture column names
for (int i = 0; i < reader.FieldCount; i++)
{
result.Columns.Add(reader.GetName(i));
}
// Capture rows
while (reader.Read())
{
var row = new List<object?>();
for (int i = 0; i < reader.FieldCount; i++)
{
row.Add(reader.IsDBNull(i) ? null : reader.GetValue(i));
}
result.Rows.Add(row);
}
result.Success = true;
}
catch (Exception ex)
{
result.Success = false;
result.Error = ex.Message;
}
return result;
}
الـ QueryResult (الصنف (مصنف بالكامل في مشروع العينة) يشمل ToString() كجدول مقروء.
ولأغراض التحليل التفاعلي، كثيراً ما يرغب المستعملون في طرح أسئلة متابعة:
"What's the total revenue?"
→ "Break that down by region"
→ "Show the top 5 regions"
والسؤالان الثاني والثالث لا معنى لهما إلا مع السياق من الأول.
public class ConversationTurn
{
public string Question { get; set; } = "";
public string Sql { get; set; } = "";
public bool Success { get; set; }
public int RowCount { get; set; }
public string Summary { get; set; } = ""; // "Single value: 1234567.89"
}
if (_history.Count > 0)
{
sb.AppendLine();
sb.AppendLine("CONVERSATION HISTORY (for context):");
foreach (var turn in _history.TakeLast(5)) // Last 5 turns
{
sb.AppendLine($"Q: {turn.Question}");
sb.AppendLine($"SQL: {turn.Sql}");
if (turn.Success)
{
sb.AppendLine($"Result: {turn.Summary}");
}
sb.AppendLine();
}
}
التاريخ يعطي سياق LLLM لفهم الإشارات مثل "ذلك" أو "تلك النتائج" أو "كسره إلى أبعد من ذلك".
من أجل توليد SQQL، تعمل النماذج المركزة على الترميز بأفضل طريقة. ها هي الخيارات المتاحة عن طريق مكتبة أولاما النموذجية:
□ نموذج نموذجي للحجم JIU QQQQQ Quality link o
| ------- | ------ | ------- | --------- | ------ |
|---|---|---|---|---|
deepseek-coder-v2:16b □ 9GB / متوسط / متوسط / أفضل / الوليمة |
||||
codellama:7b * ٤ ملڠڠڠڠ / سرعة سريعة / / الوليمة |
||||
llama3.2:3b ° 2Ggggypt 2GB / سريع جداً جداً وسريع جداً وسريع جداً وسريع جداً الوليمة |
بالنسبة لحالات الاستخدام الأكثر استخداماً، qwen2.5-coder:7b QL، سرعة جيدة، تشغيل على أجهزة متواضعة (8GB+RM).
على اختبار 100K صف CSV ملف CSV (14MB) على آلة dev القياسية (Ryzen 5, NVMe SSD, 32GPRM):
• نوع السؤال/ الوقت |------------|------| الحساب المبسـط / 65ms / / /مجمـع بالمجموع بالسوم □ تجميع مركب مع ميكروم الفريق المتعدد الأطراف من إعداد فريق عامل
تحت-100m للاستفسارات التحليلية على 100K صف - بدون أي خطوة استيراد. استفسر عن التعقيدات التي تهم أكثر من عدد الصف ؛ DakDB محرك عمودي commends بفعالية بغض النظر عن حجم الملف.
للملفات فوق 1GB، هو 10.100x أسرع:
using var cmd = connection.CreateCommand();
cmd.CommandText = $"COPY (SELECT * FROM '{csvPath}') TO '{parquetPath}' (FORMAT PARQUET)";
cmd.ExecuteNonQuery();
ملف باركيت المضغوط هو أيضا أصغر بكثير.
عند تنفيذ LLLMSQL:
private bool IsSafeQuery(string sql)
{
var dangerous = new[] { "DROP", "DELETE", "TRUNCATE", "UPDATE", "INSERT", "ALTER", "CREATE" };
var upperSql = sql.ToUpperInvariant();
return !dangerous.Any(d => upperSql.Contains(d));
}
DADB في نمط الذاكرة في DADB يوفر أيضا العزلة الطبيعية - لا يمكن أن تؤثر على قواعد بيانات الإنتاج الخاصة بك.
وهنا كيف تجمعت كلها معاً:
// Generate test data
await GenerateSalesCsvAsync("sales.csv", 100_000);
// Simple query
using var service = new CsvQueryService("qwen2.5-coder:7b", verbose: true);
var result = await service.QueryAsync("sales.csv", "What are total sales by region?");
Console.WriteLine(result);
// Conversational analysis
using var analyser = new ConversationalCsvAnalyser("sales.csv", "qwen2.5-coder:7b");
Console.WriteLine(await analyser.AskAsync("What's the total revenue?"));
Console.WriteLine(await analyser.AskAsync("Break that down by category"));
Console.WriteLine(await analyser.AskAsync("Which category has the most returns?"));
النموذج العقلي للحفاظ على: أسباب LLLLS; قواعد البيانات compitute.
لا إطعام البيانات إلى LLM. إطعامها تخطيطية ، السماح لها بتوليد SQL ، تنفيذ أن SQL على محرك مناسب للاستفسار. هذا الفصل هو السبب في أن النهج يعمل على مقياس.
(أ) التنفيذ:
النتيجة: استفسارات تحليلية تحت - 100ms على ملفات المليار دور، تماماً خارج الشبكة، مع بيانات لا تترك آلتك أبداً.
ويمكن الاطلاع على كامل مشروع العينة في الموقع التالي: CssvLlm - بما في ذلك CsvQueryService, ConversationalCsvAnalyser، وتوليد البيانات القائمة على بوغوس.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.