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
Blazor和当地LMs的确定性声音形式
Monday, 05 January 2026
十诫 –集成建筑
在其中,我们建立了一个声音系统 -#to @-sform 这个系统不能给AI王国的钥匙
@.}(这里是关于语音界面的话题) 每个人都想要它们 , 没人相信它们
多数声音形式在模型错误读取日期或决定“"@helptime @"” 跳过前端. 你说:‘"’ May _12}#1984"和LLM摘录 {" May @MS K7 并前进到下一个字段,然后你才能更正它>._or worse : 它会给人信心带来幻觉 而自动□-}用错误的数据向您提交您的表格
当您让 LLM {"} 控制} "} 您的表单,} 你已将一个非@-} 确定性黑盒引入到可以预测的用户体验中 @.}
这是'的假设吗? . McDonald ' @s 运行 AI- @ power 驱动器@-_thru 订购 校对:Soup
但如果我们可以吃蛋糕 并把它也吃掉 为了方便的语音输入 确定性守则 对于所有真正重要的东西 ?
使用 Blazor Server@,当地耳语表达器的语音形式系统
适用十诫
本项目如下: LLM 使用的十诫. @ @ MSk0 @ t 如果您读到@ MS K1} 短版本@ I: @ LMs 是概率引擎 @ MPK4 @ 不是决定@ O- @ makeers @ MOK6# 它们翻译并分类 @ MASK7 @ 他们不' @ t控制 @ MCSK9 @
对于语音表格来说 , 相关命令是:
- 让LLM自己立州 @- 国家机器的轨迹形成进步=%,}不是模型
- 让LLM引起影响 它建议提取 ;
- III. 与叙述分开的因果关系 @-LLM解释自己听到的#; 验证人决定它是否正确
- 在概率可以接受的情况下使用LLMs @ - @ 从演讲中提取@ MS K1_ May @ I12 @ t"} 是模糊的 ;{ 字段订单不是
语音形式设计目标
除了命令之外 这个制度遵循具体的原则 :
- 演讲是损失的输入 @- @ 一种填充字段的方法 @ , @ never the truth source
- 确认是策略@- @% 驱动 “-”+“Config,”中的阈值,而不是LLM判决。
- 用户总是可以推翻 @-@ 声音是方便的 @ ,# 不是强迫
- 全部都是本地经营的 - Whisper和Ollama,没有云层依赖性
- 失败是优雅的 当声音失声时 ,}打字仍然有效
这里#'}这在实践上如何看? 200)}:
flowchart LR
A[User Speaks] --> B[Whisper STT]
B --> C[Raw Transcript]
C --> D[Ollama LLM]
D --> E[Extracted Value]
E --> F{Validation}
F -->|Pass| G{Policy Check}
F -->|Fail| H[Show Error]
G -->|High Confidence| I[Auto-Confirm]
G -->|Low Confidence| J[Ask User]
J --> K{User Confirms?}
K -->|Yes| L[State Machine: Next Field]
K -->|No| M[Retry Recording]
I --> L
H --> M
style D stroke:#f96,stroke-width:2px
style F stroke:#6f6,stroke-width:2px
style G stroke:#ff9,stroke-width:2px
这是做什么? '吗?
让'%s明白范围@: @
- 没有自然对话 - 这里是' t a chatbot}. 1 phone field as a time@.
- 不询问适应性提问 “-”形式是静态的“. ” LLM doesnZ't Jimprovise 跟随“MS K3cups @.}
- 没有"助理 "个性 “LLM”提取了值“, ” 它确实“MS K2 ” 做了些小闲聊 .
- 没有横跨字段的上下文 @- @ 每一次提取都是独立的@.}LLM does'}在询问电子邮件时都不记得你的名字 .
这些限制是特性@, 而非bugs. 它们使系统可以预测 @, 测试{, 和可信赖}MS K4
如果您想要一个对话代理@ , @ building a talance agent *\ .} 如果您想要正确的数据 < MS K2 > don\ MPK3t 假装交谈有助于\ I.}
项目结构
我们正在建造一个独立的 Blazor 服务器 App._Breaking a separity brazor server appMSK1}这里是'_Chis the struilitation :
Mostlylucid.VoiceForm/
├── Config/
│ └── VoiceFormConfig.cs # Configuration binding
├── Models/
│ ├── FormSchema/ # Form definitions
│ ├── State/ # Session state
│ └── Extraction/ # LLM input/output
├── Services/
│ ├── Stt/ # Speech-to-text (Whisper)
│ ├── Extraction/ # Field extraction (Ollama)
│ ├── Validation/ # Type-based validators
│ ├── StateMachine/ # Form flow control
│ └── Orchestration/ # Coordinates everything
├── Components/
│ └── Pages/ # Blazor UI
└── wwwroot/js/
└── audio-recorder.js # Web Audio API capture
扶养规则_: 服务只依赖于下面的抽象数据。 没有上游的人知道下游发生什么
建立基础设施
首先,你需要耳语和奥拉马在本地跑. 加上这些 devdeps-docker-compose.yml:
services:
whisper:
image: onerahmet/openai-whisper-asr-webservice:latest
container_name: whisper-stt
ports:
- "9000:9000"
environment:
- ASR_MODEL=base.en
- ASR_ENGINE=faster_whisper
volumes:
- whisper-models:/root/.cache/huggingface
restart: unless-stopped
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
- ollama-models:/root/.ollama
restart: unless-stopped
volumes:
whisper-models:
ollama-models:
在旋转后“,”拉出一个Ollama:的模型
docker exec -it ollama ollama pull llama3.2:3b
为何本地@? @ 测试点:.}没有利率限制 , 没有网络变异性=.
注:: 缩略 base.en 对于英文来说,耳语模式是快速和准确的。 small.en 或 medium.en 提高准确性@. @%
表格SchemaQ:+Z 声明格式定义
表格在 JSON.中定义,这是关于哪些领域存在及其行为方式的唯一真相来源。
{
"id": "customer-intake",
"name": "Customer Intake Form",
"fields": [
{
"id": "fullName",
"label": "Full Name",
"type": "Text",
"prompt": "Please say your full name.",
"required": true
},
{
"id": "dateOfBirth",
"label": "Date of Birth",
"type": "Date",
"prompt": "What is your date of birth?",
"required": true,
"confirmationPolicy": {
"alwaysConfirm": true
}
},
{
"id": "email",
"label": "Email Address",
"type": "Email",
"prompt": "What is your email address?",
"required": true
},
{
"id": "phone",
"label": "Phone Number",
"type": "Phone",
"prompt": "What is your phone number?",
"required": false
},
{
"id": "notes",
"label": "Additional Notes",
"type": "Text",
"prompt": "Any additional notes?",
"required": false
}
]
}
C# 代表此模式的模型{:
public record FormDefinition(
string Id,
string Name,
List<FieldDefinition> Fields);
public record FieldDefinition(
string Id,
string Label,
FieldType Type,
string Prompt,
bool Required = true,
ConfirmationPolicy? ConfirmationPolicy = null);
public enum FieldType
{
Text,
Date,
Email,
Phone,
Choice // Constrained vocabulary - especially important for voice
}
public record ConfirmationPolicy(
bool AlwaysConfirm = false,
double ConfidenceThreshold = 0.85);
因为剧情是宣示性的 , 添加字段无需触摸状态机器. 在 JSON,中丢弃新的字段定义, 且表单自动包含有适当的流量控制@.
国家机器-:-决定形式流动
该州立机器明确禁止该“.”
国家机器使用 AY=.+# 依据明确的规则决定过渡的逻辑=.}
public class FormStateMachine : IFormStateMachine
{
private FormSession _session = null!;
private int _currentFieldIndex;
public FormSession StartSession(FormDefinition form)
{
_session = new FormSession
{
Id = Guid.NewGuid().ToString(),
Form = form,
Status = FormStatus.InProgress,
StartedAt = DateTime.UtcNow,
FieldStates = form.Fields.ToDictionary(
f => f.Id,
f => new FieldState { FieldId = f.Id, Status = FieldStatus.Pending })
};
// First field starts in progress
if (form.Fields.Count > 0)
{
_session.FieldStates[form.Fields[0].Id].Status = FieldStatus.InProgress;
}
return _session;
}
public FieldDefinition? GetCurrentField()
{
if (_currentFieldIndex >= _session.Form.Fields.Count)
return null;
return _session.Form.Fields[_currentFieldIndex];
}
}
州过渡是明确和可测试的 :
public StateTransitionResult ProcessExtraction(
ExtractionResponse extraction,
ValidationResult validation)
{
var currentField = GetCurrentField();
if (currentField == null)
return new StateTransitionResult(false, "No current field");
var fieldState = _session.FieldStates[currentField.Id];
fieldState.AttemptCount++;
// Validation failed? Stay on current field
if (!validation.IsValid)
{
return new StateTransitionResult(
false,
$"Validation failed: {validation.ErrorMessage}");
}
// Store the pending value
fieldState.PendingValue = extraction.Value;
fieldState.PendingConfidence = extraction.Confidence;
// Check confirmation policy - this is rules, not AI
var policy = currentField.ConfirmationPolicy
?? new ConfirmationPolicy();
var needsConfirmation = policy.AlwaysConfirm
|| extraction.Confidence < policy.ConfidenceThreshold;
if (needsConfirmation)
{
fieldState.Status = FieldStatus.AwaitingConfirmation;
return new StateTransitionResult(
true,
"Please confirm this value",
RequiresConfirmation: true);
}
// Auto-confirm high confidence values
return ConfirmValue();
}
关键点@: 缩略 _currentFieldIndex 只有在确认后 president@, @ never on republic_.}这表示提取失败或拒绝确认将您保留在同一字段@ .# 用户继续控制\ . @
注意确认逻辑@: @ it'}一个简单的政策检查 ,}不是LLM推理.#高度信任 *{+}否 alwaysConfirm 低置信度或敏感域 @=问用户@.
LLM' 合同_: 只翻译
Ollama 提取器有一份工作: 把乱七八糟的人的演讲变成结构化的字段值."
如果您能写下这个界面, 而不感到尴尬 @,}LLM正在做太多的事情@:#
public interface IFieldExtractor
{
Task<ExtractionResponse> ExtractAsync(
ExtractionContext context,
CancellationToken ct = default);
}
public record ExtractionContext(
FieldDefinition Field,
string Prompt,
string Transcript);
public record ExtractionResponse(
string FieldId,
string? Value,
double Confidence,
bool NeedsConfirmation, // Suggestion only - policy has final say
string? Reason);
重要的: 提取器可能暗示 NeedsConfirmation: true但确认政策总是有最终的发言权。 LLM='=%s 意见是建议*,}不是权威 .
以及执行@:
public class OllamaFieldExtractor : IFieldExtractor
{
private readonly HttpClient _httpClient;
private readonly string _model;
public async Task<ExtractionResponse> ExtractAsync(
ExtractionContext context,
CancellationToken ct = default)
{
var systemPrompt = BuildSystemPrompt(context.Field);
var userPrompt = $"User said: \"{context.Transcript}\"";
var request = new
{
model = _model,
messages = new[]
{
new { role = "system", content = systemPrompt },
new { role = "user", content = userPrompt }
},
format = "json",
stream = false,
options = new { temperature = 0.1 } // Low = deterministic
};
var response = await _httpClient.PostAsJsonAsync(
"/api/chat", request, ct);
return ParseResponse(response, context.Field.Id);
}
}
为什么温度会变温? 我们希望LLM是无聊的和可预测的"."鉴于相同的笔录 ,"它应该每次提取同样的值 "."温度"\0.1" 最大限度地减少创造性变异"\ -"我们想要的数据提取什么"MS K5"
系统即时功能明确显示LLM'}有限角色=:
private string BuildSystemPrompt(FieldDefinition field)
{
return $"""
You are a data extraction assistant. Extract the {field.Label}
from the user's speech.
Field type: {field.Type}
Return JSON only:
{{
"fieldId": "{field.Id}",
"value": "<extracted value or null>",
"confidence": <0.0-1.0>,
"needsConfirmation": <true/false>,
"reason": "<brief explanation>"
}}
Rules:
- For dates, output ISO format (YYYY-MM-DD)
- For emails, output lowercase
- For phones, output digits only
- If you can't extract, set value to null
- Be conservative with confidence scores
DO NOT:
- Ask follow-up questions
- Suggest next steps
- Make assumptions beyond the transcript
""";
}
LLM 提取@,}验证类型格式 @,}并报告信任性 它决定了接下来会发生什么
WAV 的音频记录器@:浏览器
JavaScript 侧面捕捉麦克风音频并将其转换为 @ 16kHz 单 WAV:}
window.voiceFormAudio = (function () {
let mediaRecorder = null;
let audioChunks = [];
let audioContext = null;
let dotNetRef = null;
async function startRecording() {
const stream = await navigator.mediaDevices
.getUserMedia({ audio: true });
audioContext = new AudioContext();
audioChunks = [];
const options = { mimeType: 'audio/webm;codecs=opus' };
mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
audioChunks.push(event.data);
}
};
mediaRecorder.onstop = async () => {
stream.getTracks().forEach(track => track.stop());
const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
const wavBlob = await convertToWav(audioBlob);
const wavBytes = await wavBlob.arrayBuffer();
// Send to Blazor
const uint8Array = new Uint8Array(wavBytes);
await dotNetRef.invokeMethodAsync(
'OnRecordingComplete',
Array.from(uint8Array));
};
mediaRecorder.start(100);
}
return { initialize, startRecording, stopRecording };
})();
为什么WAV? Whisper接受关于“16kHz one WAV.”的培训。同样的音频在“MS K2”中也包含相同的字节。
缩略 convertToWav 函数重新标注@- @I'}可以节省您使用 WAV header bit @-_twidling{,},但是在 repoQ.}中它会='%s
Blazor UI:+2 -+Column布局
UI 显示左侧的当前字段 ,}所有字段都可见于右侧的边栏\ I.} 侧边栏不是化妆品@- @it_'}是信任边界 @. 用户可以随时看到进步@, state @,和意图}#.
graph LR
subgraph "Left Panel"
A[Current Field Prompt]
B[Record Button]
C[Transcript Display]
D[Confirmation Dialog]
end
subgraph "Right Sidebar"
E[Field 1: Full Name ✓]
F[Field 2: DOB - Active]
G[Field 3: Email - Pending]
H[Field 4: Phone - Pending]
end
style F stroke:#36f,stroke-width:2px
style E stroke:#6f6,stroke-width:2px
这是Blazor页面结构的:
@page "/voiceform/{FormId}"
@inject IFormOrchestrator Orchestrator
@rendermode InteractiveServer
<div class="top-bar">
<h1>Voice Form</h1>
<button class="theme-toggle" onclick="voiceFormTheme.toggle()">
Dark Mode
</button>
</div>
<main>
<div class="voice-form-layout">
<!-- Left: Active Field -->
<div class="active-field-panel">
@if (_currentField != null)
{
<div class="current-prompt">
<h2>@_currentField.Label</h2>
<p class="prompt-text">@_message</p>
</div>
<AudioRecorder OnAudioCaptured="HandleAudioCaptured"
IsRecording="_isRecording"
IsProcessing="_isProcessing" />
@if (!string.IsNullOrEmpty(_transcript))
{
<TranscriptDisplay Transcript="_transcript"
Confidence="_transcriptConfidence" />
}
@if (_showConfirmation)
{
<ConfirmationDialog ExtractedValue="_pendingValue"
OnConfirm="HandleConfirm"
OnReject="HandleReject" />
}
}
</div>
<!-- Right: Form Overview -->
<div class="form-sidebar">
<h3>@_session.Form.Name</h3>
<div class="form-fields-list">
@foreach (var field in _session.Form.Fields)
{
var state = _session.GetFieldState(field.Id);
<div class="form-field-item @GetFieldClass(field, state)">
<div class="field-status-icon">
@GetStatusIcon(state.Status)
</div>
<div class="field-info">
<div class="field-name">@field.Label</div>
<div class="field-value">
@(state.Value ?? "Waiting")
</div>
</div>
</div>
}
</div>
</div>
</div>
</main>
编织者: 将它统领到一起
管弦乐队协调各服务... 本身没有分支逻辑@-it只是按顺序拨打服务电话,
public class FormOrchestrator : IFormOrchestrator
{
private readonly ISttService _sttService;
private readonly IFieldExtractor _extractor;
private readonly IFormValidator _validator;
private readonly IFormStateMachine _stateMachine;
private readonly IFormEventLog _eventLog;
public async Task<ProcessingResult> ProcessAudioAsync(byte[] audioData)
{
var currentField = _stateMachine.GetCurrentField();
if (currentField == null)
return ProcessingResult.Error("No current field");
// Step 1: Speech to text
var sttResult = await _sttService.TranscribeAsync(audioData);
await _eventLog.LogAsync(new TranscriptReceivedEvent(
currentField.Id, sttResult.Transcript, sttResult.Confidence));
// Step 2: Extract structured value
var context = new ExtractionContext(
currentField, currentField.Prompt, sttResult.Transcript);
var extraction = await _extractor.ExtractAsync(context);
await _eventLog.LogAsync(new ExtractionAttemptEvent(
currentField.Id, extraction));
// Step 3: Validate
var validation = _validator.Validate(currentField, extraction.Value);
// Step 4: State machine decides next step
var transition = _stateMachine.ProcessExtraction(extraction, validation);
return new ProcessingResult(
Success: transition.Success,
Message: transition.Message,
Session: _stateMachine.GetSession(),
RequiresConfirmation: transition.RequiresConfirmation,
PendingValue: extraction.Value);
}
}
每一步都是独立和可测试的 . 国家机器 永不触动网络灵丹妙药 绝不触动国家.
胜利的黑暗模式@: CSS 变量
使用 CSS 自定义属性来执行暗模式@ :
:root {
--bg-primary: #f8fafc;
--bg-secondary: #ffffff;
--text-primary: #1e293b;
--accent-blue: #3b82f6;
--accent-green: #22c55e;
}
[data-theme="dark"] {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--text-primary: #f1f5f9;
--accent-blue: #60a5fa;
--accent-green: #4ade80;
}
body {
background: var(--bg-primary);
color: var(--text-primary);
}
主题切换通过本地端Storage @:+#
window.voiceFormTheme = (function () {
const THEME_KEY = 'voiceform-theme';
function toggle() {
const current = document.documentElement
.getAttribute('data-theme') || 'light';
const newTheme = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem(THEME_KEY, newTheme);
}
// Initialize from saved preference or system preference
function init() {
const saved = localStorage.getItem(THEME_KEY);
const systemDark = window.matchMedia(
'(prefers-color-scheme: dark)').matches;
const theme = saved || (systemDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
}
return { toggle, init };
})();
测试 :單位測試 {+}瀏覽器整合
确定性结构在测试中得到回报... .... Here'...
[Fact]
public void ProcessExtraction_HighConfidence_AutoConfirms()
{
// Arrange
var form = CreateTestForm();
var stateMachine = new FormStateMachine();
stateMachine.StartSession(form);
var extraction = new ExtractionResponse(
FieldId: "fullName",
Value: "John Smith",
Confidence: 0.95, // High confidence
NeedsConfirmation: false,
Reason: "Clear speech");
var validation = ValidationResult.Success();
// Act
var result = stateMachine.ProcessExtraction(extraction, validation);
// Assert
result.Success.Should().BeTrue();
result.RequiresConfirmation.Should().BeFalse();
var fieldState = stateMachine.GetSession()
.GetFieldState("fullName");
fieldState.Status.Should().Be(FieldStatus.Confirmed);
fieldState.Value.Should().Be("John Smith");
}
而这里的' 测试为负数 部队 不论LLM建议什么 :
[Fact]
public void ProcessExtraction_LowConfidence_RequiresConfirmation()
{
// Arrange
var form = CreateTestForm();
var stateMachine = new FormStateMachine();
stateMachine.StartSession(form);
var extraction = new ExtractionResponse(
FieldId: "fullName",
Value: "John Smith",
Confidence: 0.65, // Below threshold
NeedsConfirmation: false, // LLM says no, but policy overrides
Reason: "Noisy audio");
var validation = ValidationResult.Success();
// Act
var result = stateMachine.ProcessExtraction(extraction, validation);
// Assert
result.RequiresConfirmation.Should().BeTrue(
"Policy threshold (0.85) should override LLM suggestion");
var fieldState = stateMachine.GetSession()
.GetFieldState("fullName");
fieldState.Status.Should().Be(FieldStatus.AwaitingConfirmation);
}
以及一个 Putopieer Sharp 浏览器测试, 实际上点击东西@: @%
[Fact]
public async Task HomePage_ThemeToggle_ShouldSwitchTheme()
{
await _page!.GoToAsync(BaseUrl);
await _page.WaitForSelectorAsync(".theme-toggle");
var initialTheme = await _page.EvaluateFunctionAsync<string?>(
"() => document.documentElement.getAttribute('data-theme')");
// Click toggle
await _page.ClickAsync(".theme-toggle");
await Task.Delay(100);
var newTheme = await _page.EvaluateFunctionAsync<string?>(
"() => document.documentElement.getAttribute('data-theme')");
newTheme.Should().NotBe(initialTheme);
}
[Fact]
public async Task VoiceFormPage_Sidebar_ShouldShowAllFields()
{
await _page!.GoToAsync($"{BaseUrl}/voiceform/customer-intake");
await _page.WaitForSelectorAsync(".form-fields-list");
var fieldItems = await _page.QuerySelectorAllAsync(".form-field-item");
fieldItems.Should().HaveCount(5, "Customer intake form has 5 fields");
}
完整的测试套件运行“% 98” 测试“ MS K1” 单位测试,用于商业逻辑“ @ ,” 和“ MPK3” 浏览器集成检测UI.” 。
重要的是,不是测试本身 -it' 建筑使得它们成为可能
为什么这个建筑问题
让我们重温为什么我们这样建造它 : *
graph TD
subgraph "Traditional Voice Form"
A1[User Speaks] --> B1[LLM]
B1 --> C1[LLM decides field]
C1 --> D1[LLM validates]
D1 --> E1[LLM confirms]
E1 --> F1[LLM advances form]
end
subgraph "Ten Commandments Approach"
A2[User Speaks] --> B2[Whisper STT]
B2 --> C2[Ollama Extract]
C2 --> D2[C# Validator]
D2 --> E2[Policy Check]
E2 --> F2[State Machine]
end
style B1 stroke:#f96,stroke-width:2px
style C1 stroke:#f96,stroke-width:2px
style D1 stroke:#f96,stroke-width:2px
style E1 stroke:#f96,stroke-width:2px
style F1 stroke:#f96,stroke-width:2px
style C2 stroke:#f96,stroke-width:2px
style D2 stroke:#6f6,stroke-width:2px
style E2 stroke:#6f6,stroke-width:2px
style F2 stroke:#6f6,stroke-width:2px
传统做法: 一切都是全能的,“. ”每个决定都是非“- 确定性”或“MS K2 ” 每个测试都是概率的“MSC3”
每个错误都是 @ " @ it just sometimes does that @ I"-# 无法复制和解释@ MS K2 @
在我们的做法中,LLM是 还有一件事: 将演讲翻译为结构化的值@. 其他一切都是确定性的 C# 您可以调试, 测试 @, 和追踪#.
这是动作中的 II,}IIIMS K1}和四号命令 “:LLM”翻译了“(no side -effects}),}州立機控管系統流 *{(causality
自己运行
- 开始依赖关系@:}
docker compose -f devdeps-docker-compose.yml up -d
docker exec -it ollama ollama pull llama3.2:3b
- 运行 App:
cd Mostlylucid.VoiceForm
dotnet run
导航至
http://localhost:5000点击“"”+“海关收件”"然后开始说!
结论结论
语音界面@' @t 必须是黑盒子 @ .} 通过将演讲作为另一种输入方法来对待 ,}LMs 作为翻译{,}(译者) 并保持确定代码的流量控制>,你得到:}
- 可预见行为 -}相同的投入 *,}同样的输出
- 可检验逻辑 -单位商业规则测试
- 可审计裁决 每个州都记录了过渡情况
- 优减降解 @ - @ 语音失败@ MS K1_ type
- 当地业务 - 核心功能无云依赖性
@"_Ten 命令@"}是'}关于反对-QAAI.的 将大赦国际置于适当位置“:”是一个强有力的工具,可以翻译人类的不便和计算机精确度之间 ”“,”不是为我们做决定的神器 ‘.
AI在减少模棱两可之处时赢得了自己的地位 -*not 当它取代责任的时候
现在去建造一些东西 在那里你-}而不是模型{-}决定下一步会发生什么
部分内容为 @2:#语音反馈@(_IVR%)}
现在该用户读到提示并说回应@.}但是如果这个系统可以呢? 回话@? @ part @ 2 @ 将添加文字@ MS K2 @to @ MPK3_ speech 回馈@ I, @ 将此转换成完整的 IVR @ MCK5# 交互式语音响应 @ MASK6 @ system+: @
- 大声朗读提示 请说出你的全名 "
- 确认提取 "- "" 我听见了"' 约翰・史密斯・史密斯•'." 这是正确的吗?
- 音频提示 - @ sound for record start@ /_stop,}确认 , 错误
- 手M-无限制操作 完整表格不看屏幕
此架构已准备好 @ : @ 国家机器发布事件@ MS K1 @ 管弦乐队坐标服务 @ I. @ 添加语音输出只是另一个倾听这些事件的服务 @ MPK3 @
进入了“3:”部分的政策执行
目前的验证是 @-BARBAR:}电子邮件看起来像是emails{,}日期被解析为date@.}但是关于商业规则 <?} "#出生日期必须至少是%18}几年前 *."{Q"Phone number 必须匹配所选区域}."}"}Notes字段不能包含 profanity=."}
部分 @3}将添加#:
- 基于规则的 - 校验 “-” 计划中的声明政策
- Crossó- 实地限制 “- " 如果国家是美国,, 电话必须是“10 位数 @"”
- LLM- 辅助政策检查 使用这个模型来标出潜在问题@,,
- 审计线索 “- 哪个政策触发了“ , 为什么失败” @, 用户接下来做了什么?
同样的原则... ...:... ...LLM建议...
继续阅读
- LLM 使用的十诫 这个建筑背后的理念
- 开发依赖使用嵌入合成软件 建立地方服务机构
- 带有 ASP.NET 核心的 HTMX -伺服器{-}驱动的UI模式
完整源代码在 Mostlylucid.VoiceForm 在 repo. 中的项目