diff --git a/backend/gateway/platforms/deepview_sse.py b/backend/gateway/platforms/deepview_sse.py
index 0aaf000..0f612a7 100644
--- a/backend/gateway/platforms/deepview_sse.py
+++ b/backend/gateway/platforms/deepview_sse.py
@@ -592,6 +592,9 @@ class DeepviewSSEServer:
else:
systemPrompt += f"\n\n## 通用模式\n企业知识库目录:{orgDir}/wiki/\n平台规则参考:{platformDir}/wiki/\n"
+ # 强调输出纪律,从源头杜绝输出底层 JSON 结构给前端
+ systemPrompt += "\n\n【严格输出规范】\n严禁在最终回答中输出任何 JSON 结构、工具调用过程记录、文件读取错误等底层调试信息。你必须将系统结果和发现转化为专业、流畅的文档级 Markdown 给医生阅读!\n"
+
# 3. 加载上下文履历,实现真正的 Stateful Context
history = db.get_messages_as_conversation(chatId)
diff --git a/src/app/app.css b/src/app/app.css
index 20f8dc4..34c1ee6 100644
--- a/src/app/app.css
+++ b/src/app/app.css
@@ -395,28 +395,44 @@
.chat-send-btn:disabled { background: #cbd5e1; color: #f1f5f9; }
/* Markdown in Chat */
.markdown-body {
- font-family: inherit;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
+ font-size: 15px;
+ color: #1e293b;
+ letter-spacing: 0.01em;
}
.markdown-body p {
- margin-bottom: 8px;
+ margin-bottom: 12px;
}
.markdown-body p:last-child {
margin-bottom: 0;
}
.markdown-body strong {
font-weight: 700;
+ color: #0f172a;
}
.markdown-body ul, .markdown-body ol {
- padding-left: 20px;
- margin-bottom: 8px;
+ padding-left: 24px;
+ margin-bottom: 12px;
+ margin-top: 4px;
+}
+.markdown-body ul {
+ list-style-type: disc;
+}
+.markdown-body ol {
+ list-style-type: decimal;
}
.markdown-body li {
- margin-bottom: 4px;
+ margin-bottom: 6px;
+ display: list-item;
}
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4 {
- margin-top: 12px;
- margin-bottom: 8px;
+ margin-top: 16px;
+ margin-bottom: 10px;
font-weight: 700;
- line-height: 1.4;
+ line-height: 1.3;
+ color: #0f172a;
+}
+.markdown-body h3, .markdown-body h4 {
+ font-size: 16px;
}
diff --git a/src/app/app.html b/src/app/app.html
index 68d29b1..4005853 100644
--- a/src/app/app.html
+++ b/src/app/app.html
@@ -136,7 +136,7 @@
diff --git a/src/app/app.ts b/src/app/app.ts
index 07eb4df..3af5762 100644
--- a/src/app/app.ts
+++ b/src/app/app.ts
@@ -127,7 +127,8 @@ export class App implements OnDestroy, OnInit {
const currentStreamingMsg = this.chatMessages.find(m => m.isStreaming && m.role === 'agent');
if (currentStreamingMsg) {
currentStreamingMsg.rawContent = (currentStreamingMsg.rawContent || '') + payload.text;
- currentStreamingMsg.htmlContent = marked.parse(currentStreamingMsg.rawContent) as string;
+ const displayStr = this.sanitizeStreamingContent(currentStreamingMsg.rawContent);
+ currentStreamingMsg.htmlContent = marked.parse(displayStr) as string;
}
break;
case 'agent:thinking':
@@ -141,7 +142,11 @@ export class App implements OnDestroy, OnInit {
activeStreamingMsg.isStreaming = false;
if (payload.fullAnswer) {
activeStreamingMsg.rawContent = payload.fullAnswer;
- activeStreamingMsg.htmlContent = marked.parse(activeStreamingMsg.rawContent || '') as string;
+ const finalStr = this.sanitizeStreamingContent(activeStreamingMsg.rawContent || '');
+ activeStreamingMsg.htmlContent = marked.parse(finalStr) as string;
+ } else {
+ const finalFallbackStr = this.sanitizeStreamingContent(activeStreamingMsg.rawContent || '');
+ activeStreamingMsg.htmlContent = marked.parse(finalFallbackStr) as string;
}
}
break;
@@ -458,7 +463,8 @@ export class App implements OnDestroy, OnInit {
if (res && res.messages && res.messages.length > 0) {
this.chatMessages = res.messages.map((m: any) => {
const rawContent = m.content || '';
- const htmlContent = marked.parse(rawContent) as string;
+ const displayStr = this.sanitizeStreamingContent(rawContent);
+ const htmlContent = marked.parse(displayStr) as string;
return {
role: m.role,
rawContent: rawContent,
@@ -509,4 +515,16 @@ export class App implements OnDestroy, OnInit {
}
}
+ private sanitizeStreamingContent(raw: string): string {
+ if (!raw) return '';
+ let text = raw;
+ // Strip markdown JSON block wrappings entirely
+ text = text.replace(/```json\s*\{[\s\S]*?\}\s*```/g, '');
+ // Strip bare unescaped JSON tool reports which match specific sigs
+ text = text.replace(/\{"content":[\s\S]*?\}/g, '');
+ text = text.replace(/\{"total_count":[\s\S]*?\}/g, '');
+ // Strip trailing tool garbage that might be partially yielded
+ return text.trim();
+ }
+
}