Website AI Assistant: Capability Boundaries & Technical Design
This site's AI assistant is currently rule-based Q&A (preset KB, no medical records, no external LLM); the content below is a planned engineering design illustrating the approach and a reference implementation.
Overall System Architecture
Responsibilities of the four core modules
Front-end chat interface
React/Vue components: message list, input, typing state, quick chips, streaming rendering, language switching and accessibility (aria / keyboard friendly).
Back-end message processing service
Session state, intent routing, compliance guardrails, context assembly, LLM API calls, escalation triggers and audit logging.
LLM chat API integration (planned)
LLM service API: medical-compliance system prompt, RAG retrieval, Function Calling to KB/CRM, SSE streaming replies.
R&D Assistant Agent · Code Generation / Fixes
The planned R&D assistant agent: generates new-intent and FAQ code, fixes defects and produces PRs, merged after human review.
Request chain of a conversation
- 1User sends
The front end collects messages and a sessionId, uploading to /api/chat over encrypted WSS/HTTPS.
- 2Intent routing
The back end detects intent (price / eye / travel / membership / emergency) via keywords and a classifier, then assembles context and KB snippets.
- 3LLM chat API · generation
The back end calls the LLM API (with guardrails and RAG) and streams via SSE; escalation conditions route to human agents.
- 4Front-end rendering
The front end renders replies incrementally and logs sessions and satisfaction for iteration and self-repair.
The R&D assistance pipeline runs independently: a developer files a ticket (new intent / bug) → the agent generates or fixes code → produces a Pull Request → review and merge into production.
Key interfaces / data contracts
POST /api/chat (SSE) request/response contract:
// Request
{
"sessionId": "sess_8f3a", // session id
"message": "How much is a dental implant?", // user text
"lang": "en" // language
}
// Response (text/event-stream, chunked)
data: {"delta": "The indicative USD range for a single implant is ..."}
data: {"delta": "Final pricing follows the hospital."}
data: [DONE]
LLM invocation contract (back end → model service):
POST https://api.openai.com/v1/chat/completions
{
"model": "gpt-4o-mini",
"stream": true,
"messages": [
{"role":"system","content":"compliance guardrails + KB snippets"},
{"role":"user","content":"[en] How much is a dental implant?"}
]
}
R&D assistant task contract (backend → R&D assistant agent):
{
"task": "Add an FAQ follow-up to the price intent: does it include bone graft costs",
"file": "src/intents/price.js",
"failing_test": null,
"review": "required" // must be human-reviewed before merging
}
Key implementation (runnable)
The following is a generic example illustrating the integration approach only,not production code of this site, and has not been deployed.
Back-end message service + LLM integration (Node 18+, requires express and openai):
// server.js
import express from 'express';
import OpenAI from 'openai';
const app = express();
app.use(express.json());
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
// Medical compliance guardrails: no diagnosis / prescriptions / efficacy promises
const GUARDRAILS = [
'You are the AI assistant of a medical travel concierge site; provide objective process and credential information only.',
'Never diagnose, prescribe, promise outcomes, or rank doctors.',
'Actual treatment requires an in-person visit with a licensed physician; costs follow hospital pricing.',
'For emergencies, guide users to local emergency numbers (120 in China / 911 in the US).',
'When unsure, escalate to a human agent.'
].join(String.fromCharCode(10));
// Intent routing: keyword hit decides the class, otherwise general
const INTENTS = {
price: /价格|比价|费用|报价|usd|\$/i,
eye: /眼科|近视|激光|smile|lasik|icl|白内障/i,
travel: /行程|签证|机票|酒店|陪护/i,
member: /会员|登录|账号|保险/i,
emergency: /紧急|急救|意外|危险/i
};
function route(text){ for(const k in INTENTS) if(INTENTS[k].test(text)) return k; return 'general'; }
app.post('/api/chat', async (req, res) => {
const { sessionId, message, lang = 'zh-CN' } = req.body;
const intent = route(message);
const kb = await retrieveKB(intent, message); // vector retrieval placeholder
const stream = await openai.chat.completions.create({
model: 'gpt-4o-mini', stream: true,
messages: [
{ role:'system', content: GUARDRAILS + '\nKB snippets:\n' + kb },
{ role:'user', content: '[' + lang + '] ' + message }
]
});
res.setHeader('Content-Type','text/event-stream');
for await (const chunk of stream) {
const t = (chunk.choices[0] && chunk.choices[0].delta && chunk.choices[0].delta.content) || '';
if (t) res.write('data: ' + JSON.stringify({ delta: t }) + String.fromCharCode(10) + String.fromCharCode(10));
}
res.write('data: [DONE]' + String.fromCharCode(10) + String.fromCharCode(10));
res.end();
});
async function retrieveKB(intent, q){ return '(Example) public credential and price-range notes for this intent.'; }
app.listen(3000, () => console.log('AI chat service on :3000'));
Front-end streaming call (browser):
// chat-client.js
export async function sendChat(sessionId, message, lang, onDelta) {
const res = await fetch('/api/chat', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({ sessionId, message, lang })
});
const reader = res.body.getReader();
const dec = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
for (const line of dec.decode(value).split(String.fromCharCode(10))) {
if (line.startsWith('data: ')) {
const payload = line.slice(6);
if (payload === '[DONE]') return;
onDelta(JSON.parse(payload).delta);
}
}
}
}
Code generation / repair module (dev support, planned) (Python, requires openai, replace model when wiring in the R&D assistant agent):
# codex_agent.py
import os, openai, sys
client = openai.OpenAI(api_key=os.environ['OPENAI_API_KEY'])
def generate_or_fix(task, file_path=None, failing_test=None):
ctx = ''
if file_path and os.path.exists(file_path):
ctx += '\n# Existing file ' + file_path + '\n' + open(file_path, encoding='utf-8').read()
if failing_test:
ctx += '\n# Failing test output\n' + failing_test
prompt = ('You are the code engineer for the customer-service system. Task: ' + task +
'\nOutput only a mergeable code diff or the complete file, with a brief explanation.\n' + ctx)
r = client.chat.completions.create(
model='gpt-4o', # replace model when wiring in the actual code model
messages=[{'role':'system','content':'You are a senior frontend / Node engineer familiar with this customer-service system.'},
{'role':'user','content':prompt}])
return r.choices[0].message.content
if __name__ == '__main__':
print(generate_or_fix(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else None))